From richard at xmos.com Mon Nov 17 07:15:15 2008 From: richard at xmos.com (Richard Osborne) Date: Mon, 17 Nov 2008 13:15:15 +0000 Subject: [llvm-commits] [patch] Additional support for softening unary floating point ops. Message-ID: <49216E63.6000106@xmos.com> The attached patch adds support to LegalizeTypes for softening some additional unary floating point operations (FSQRT, FSIN, FCOS, FLOG*, FEXP*). OK to commit? -- Richard Osborne | XMOS http://www.xmos.com -------------- next part -------------- A non-text attachment was scrubbed... Name: softfp.patch Type: text/x-patch Size: 12744 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20081117/a41aa088/attachment.bin From richard at xmos.com Mon Nov 17 07:26:54 2008 From: richard at xmos.com (Richard Osborne) Date: Mon, 17 Nov 2008 13:26:54 +0000 Subject: [llvm-commits] [patch] Add support for softening FNEG Message-ID: <4921711E.5010605@xmos.com> The attached patch adds support to LegalizeTypes for softening FNEG. OK to commit? -- Richard Osborne | XMOS http://www.xmos.com -------------- next part -------------- A non-text attachment was scrubbed... Name: softfneg.patch Type: text/x-patch Size: 2550 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20081117/deb0b0f9/attachment.bin From matthijs at stdin.nl Mon Nov 17 07:41:57 2008 From: matthijs at stdin.nl (Matthijs Kooijman) Date: Mon, 17 Nov 2008 14:41:57 +0100 Subject: [llvm-commits] [llvm] r58718 - /llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp In-Reply-To: References: <200811042054.mA4Ks4Ro024583@zion.cs.uiuc.edu> <20081104212751.GK1010@katherina.student.utwente.nl> Message-ID: <20081117134157.GU1010@katherina.student.utwente.nl> Hi Chris, > I think the right fix for this problem is to make it so that GEP can't > index into a vector element. That seems to make sense I guess. It wouldn't cause any problems for me, so feel free (I don't have the time available...). Gr. Matthijs -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: Digital signature Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20081117/d11a07cc/attachment.bin From richard at xmos.com Mon Nov 17 08:49:08 2008 From: richard at xmos.com (Richard Osborne) Date: Mon, 17 Nov 2008 14:49:08 +0000 Subject: [llvm-commits] [patch] fix for PR3080 - don't produce ADDC/ADDE nodes if not legal. Message-ID: <49218464.2080600@xmos.com> The attached patch fixes PR3080 http://llvm.org/bugs/show_bug.cgi?id=3080. DAGTypeLegalizer::ExpandShiftByConstant() should test if ADDC/ADDE nodes and not emit them if they are not. This matches logic used when expanding ADD / SUB. OK to commit? -- Richard Osborne | XMOS http://www.xmos.com -------------- next part -------------- A non-text attachment was scrubbed... Name: shl64.patch Type: text/x-patch Size: 1049 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20081117/12df8c17/attachment.bin From gohman at apple.com Mon Nov 17 10:37:30 2008 From: gohman at apple.com (Dan Gohman) Date: Mon, 17 Nov 2008 16:37:30 -0000 Subject: [llvm-commits] [llvm] r59445 - in /llvm/trunk/lib/CodeGen/SelectionDAG: LatencyPriorityQueue.cpp ScheduleDAGList.cpp Message-ID: <200811171637.mAHGbUib008340@zion.cs.uiuc.edu> Author: djg Date: Mon Nov 17 10:37:30 2008 New Revision: 59445 URL: http://llvm.org/viewvc/llvm-project?rev=59445&view=rev Log: Don't use the isPending flag to mean what the isAvailable flag means. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LatencyPriorityQueue.cpp llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LatencyPriorityQueue.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LatencyPriorityQueue.cpp?rev=59445&r1=59444&r2=59445&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LatencyPriorityQueue.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LatencyPriorityQueue.cpp Mon Nov 17 10:37:30 2008 @@ -150,7 +150,7 @@ /// scheduled will make this node available, so it is better than some other /// node of the same priority that will not make a node available. void LatencyPriorityQueue::AdjustPriorityOfUnscheduledPreds(SUnit *SU) { - if (SU->isPending) return; // All preds scheduled. + if (SU->isAvailable) return; // All preds scheduled. SUnit *OnlyAvailablePred = getSingleUnscheduledPred(SU); if (OnlyAvailablePred == 0 || !OnlyAvailablePred->isAvailable) return; Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp?rev=59445&r1=59444&r2=59445&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Mon Nov 17 10:37:30 2008 @@ -164,7 +164,7 @@ // It is available if it has no predecessors. if (SUnits[i].Preds.empty()) { AvailableQueue->push(&SUnits[i]); - SUnits[i].isAvailable = SUnits[i].isPending = true; + SUnits[i].isAvailable = true; } } From foldr at codedgers.com Mon Nov 17 11:29:18 2008 From: foldr at codedgers.com (Mikhail Glushenkov) Date: Mon, 17 Nov 2008 17:29:18 -0000 Subject: [llvm-commits] [llvm] r59447 - in /llvm/trunk: include/llvm/CompilerDriver/Common.td tools/llvmc2/doc/LLVMC-Reference.rst tools/llvmc2/doc/LLVMC-Tutorial.rst tools/llvmc2/plugins/Base/Base.td tools/llvmc2/plugins/Clang/Clang.td tools/llvmc2/plugins/Simple/Simple.td utils/TableGen/LLVMCConfigurationEmitter.cpp Message-ID: <200811171729.mAHHTJ2e010621@zion.cs.uiuc.edu> Author: foldr Date: Mon Nov 17 11:29:18 2008 New Revision: 59447 URL: http://llvm.org/viewvc/llvm-project?rev=59447&view=rev Log: Add a layer of indirection to make plugins more flexible. Use strings instead of TableGen defs in the compilation graph definition. Makes it easier for the plugins to modify an existing graph. Modified: llvm/trunk/include/llvm/CompilerDriver/Common.td llvm/trunk/tools/llvmc2/doc/LLVMC-Reference.rst llvm/trunk/tools/llvmc2/doc/LLVMC-Tutorial.rst llvm/trunk/tools/llvmc2/plugins/Base/Base.td llvm/trunk/tools/llvmc2/plugins/Clang/Clang.td llvm/trunk/tools/llvmc2/plugins/Simple/Simple.td llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Modified: llvm/trunk/include/llvm/CompilerDriver/Common.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CompilerDriver/Common.td?rev=59447&r1=59446&r2=59447&view=diff ============================================================================== --- llvm/trunk/include/llvm/CompilerDriver/Common.td (original) +++ llvm/trunk/include/llvm/CompilerDriver/Common.td Mon Nov 17 11:29:18 2008 @@ -15,10 +15,6 @@ list properties = l; } -// Special Tool instance - the root node of the compilation graph. - -def root : Tool<[]>; - // Possible Tool properties def in_language; @@ -87,19 +83,19 @@ // Compilation graph -class EdgeBase { - Tool a = t1; - Tool b = t2; +class EdgeBase { + string a = t1; + string b = t2; dag weight = d; } -class Edge : EdgeBase; +class Edge : EdgeBase; // Edge and SimpleEdge are synonyms. -class SimpleEdge : EdgeBase; +class SimpleEdge : EdgeBase; // Optionally enabled edge. -class OptionalEdge : EdgeBase; +class OptionalEdge : EdgeBase; class CompilationGraph lst> { list edges = lst; Modified: llvm/trunk/tools/llvmc2/doc/LLVMC-Reference.rst URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/doc/LLVMC-Reference.rst?rev=59447&r1=59446&r2=59447&view=diff ============================================================================== --- llvm/trunk/tools/llvmc2/doc/LLVMC-Reference.rst (original) +++ llvm/trunk/tools/llvmc2/doc/LLVMC-Reference.rst Mon Nov 17 11:29:18 2008 @@ -158,7 +158,7 @@ include "llvm/CompilerDriver/Common.td" // And optionally: // include "llvm/CompilerDriver/Tools.td" - // which contains tool definitions. + // which contains some useful tool definitions. Internally, LLVMC stores information about possible source transformations in form of a graph. Nodes in this graph represent @@ -171,19 +171,19 @@ ``plugins/Base/Base.td`` for an example) is just a list of edges:: def CompilationGraph : CompilationGraph<[ - Edge, - Edge, + Edge<"root", "llvm_gcc_c">, + Edge<"root", "llvm_gcc_assembler">, ... - Edge, - Edge, + Edge<"llvm_gcc_c", "llc">, + Edge<"llvm_gcc_cpp", "llc">, ... - OptionalEdge, - OptionalEdge, + OptionalEdge<"llvm_gcc_c", "opt", [(switch_on "opt")]>, + OptionalEdge<"llvm_gcc_cpp", "opt", [(switch_on "opt")]>, ... - OptionalEdge, @@ -193,7 +193,10 @@ As you can see, the edges can be either default or optional, where optional edges are differentiated by an additional ``case`` expression -used to calculate the weight of this edge. +used to calculate the weight of this edge. Notice also that we refer +to tools via their names (as strings). This allows us to add edges to +an existing compilation graph without having to include all tool +definitions that it uses. The default edges are assigned a weight of 1, and optional edges get a weight of 0 + 2*N where N is the number of tests that evaluated to Modified: llvm/trunk/tools/llvmc2/doc/LLVMC-Tutorial.rst URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/doc/LLVMC-Tutorial.rst?rev=59447&r1=59446&r2=59447&view=diff ============================================================================== --- llvm/trunk/tools/llvmc2/doc/LLVMC-Tutorial.rst (original) +++ llvm/trunk/tools/llvmc2/doc/LLVMC-Tutorial.rst Mon Nov 17 11:29:18 2008 @@ -66,7 +66,7 @@ def LanguageMap : LanguageMap<[LangToSuffixes<"c", ["c"]>]>; // Compilation graph - def CompilationGraph : CompilationGraph<[Edge]>; + def CompilationGraph : CompilationGraph<[Edge<"root", "gcc">]>; As you can see, this file consists of three parts: tool descriptions, language map, and the compilation graph definition. Modified: llvm/trunk/tools/llvmc2/plugins/Base/Base.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/plugins/Base/Base.td?rev=59447&r1=59446&r2=59447&view=diff ============================================================================== --- llvm/trunk/tools/llvmc2/plugins/Base/Base.td (original) +++ llvm/trunk/tools/llvmc2/plugins/Base/Base.td Mon Nov 17 11:29:18 2008 @@ -17,42 +17,42 @@ // Toolchains def CompilationGraph : CompilationGraph<[ - Edge, - Edge, - Edge, - Edge, - Edge, - Edge, - - Edge, - Edge, - Edge, - Edge, - Edge, - - OptionalEdge, - OptionalEdge, - OptionalEdge, - OptionalEdge, - OptionalEdge, - Edge, - - Edge, - Edge, - OptionalEdge, + Edge<"root", "llvm_gcc_assembler">, + Edge<"root", "llvm_gcc_cpp">, + Edge<"root", "llvm_gcc_m">, + Edge<"root", "llvm_gcc_mxx">, + Edge<"root", "llvm_as">, + + Edge<"llvm_gcc_c", "llc">, + Edge<"llvm_gcc_cpp", "llc">, + Edge<"llvm_gcc_m", "llc">, + Edge<"llvm_gcc_mxx", "llc">, + Edge<"llvm_as", "llc">, + + OptionalEdge<"llvm_gcc_c", "opt", (case (switch_on "opt"), (inc_weight))>, + OptionalEdge<"llvm_gcc_cpp", "opt", (case (switch_on "opt"), (inc_weight))>, + OptionalEdge<"llvm_gcc_m", "opt", (case (switch_on "opt"), (inc_weight))>, + OptionalEdge<"llvm_gcc_mxx", "opt", (case (switch_on "opt"), (inc_weight))>, + OptionalEdge<"llvm_as", "opt", (case (switch_on "opt"), (inc_weight))>, + Edge<"opt", "llc">, + + Edge<"llc", "llvm_gcc_assembler">, + Edge<"llvm_gcc_assembler", "llvm_gcc_linker">, + OptionalEdge<"llvm_gcc_assembler", "llvm_gcc_cpp_linker", (case (or (input_languages_contain "c++"), - (input_languages_contain "objective-c++")), + (input_languages_contain "objective-c++")), (inc_weight), (or (parameter_equals "linker", "g++"), (parameter_equals "linker", "c++")), (inc_weight))>, - Edge, - OptionalEdge, + OptionalEdge<"root", "llvm_gcc_cpp_linker", (case (or (input_languages_contain "c++"), - (input_languages_contain "objective-c++")), + (input_languages_contain "objective-c++")), (inc_weight), (or (parameter_equals "linker", "g++"), (parameter_equals "linker", "c++")), (inc_weight))> Modified: llvm/trunk/tools/llvmc2/plugins/Clang/Clang.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/plugins/Clang/Clang.td?rev=59447&r1=59446&r2=59447&view=diff ============================================================================== --- llvm/trunk/tools/llvmc2/plugins/Clang/Clang.td (original) +++ llvm/trunk/tools/llvmc2/plugins/Clang/Clang.td Mon Nov 17 11:29:18 2008 @@ -76,11 +76,11 @@ // Compilation graph def CompilationGraph : CompilationGraph<[ - Edge, - Edge, - Edge, - Edge, - Edge, - Edge + Edge<"root", "clang_c">, + Edge<"root", "clang_cpp">, + Edge<"root", "clang_objective_c">, + Edge<"clang_c", "llvm_ld">, + Edge<"clang_cpp", "llvm_ld">, + Edge<"clang_objective_c", "llvm_ld"> ]>; Modified: llvm/trunk/tools/llvmc2/plugins/Simple/Simple.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/plugins/Simple/Simple.td?rev=59447&r1=59446&r2=59447&view=diff ============================================================================== --- llvm/trunk/tools/llvmc2/plugins/Simple/Simple.td (original) +++ llvm/trunk/tools/llvmc2/plugins/Simple/Simple.td Mon Nov 17 11:29:18 2008 @@ -27,4 +27,4 @@ def LanguageMap : LanguageMap<[LangToSuffixes<"c", ["c"]>]>; -def CompilationGraph : CompilationGraph<[Edge]>; +def CompilationGraph : CompilationGraph<[Edge<"root", "gcc">]>; Modified: llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp?rev=59447&r1=59446&r2=59447&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Mon Nov 17 11:29:18 2008 @@ -764,11 +764,11 @@ } -/// CollectPropertiesFromOptionList - Gather information about -/// *global* option properties from the OptionList. -void CollectPropertiesFromOptionList (RecordVector::const_iterator B, - RecordVector::const_iterator E, - GlobalOptionDescriptions& OptDescs) +/// CollectPropertiesFromOptionLists - Gather information about +/// *global* option properties from all OptionLists. +void CollectPropertiesFromOptionLists (RecordVector::const_iterator B, + RecordVector::const_iterator E, + GlobalOptionDescriptions& OptDescs) { // Iterate over a properties list of every Tool definition for (;B!=E;++B) { @@ -805,7 +805,7 @@ const GlobalOptionDescription& Val = B->second; if (!nonSuperfluousOptions.count(Val.Name) && Val.Type != OptionType::Alias) - cerr << "Warning: option '-" << Val.Name << "' has no effect! " + llvm::cerr << "Warning: option '-" << Val.Name << "' has no effect! " "Probable cause: this option is specified only in the OptionList.\n"; } } @@ -1448,29 +1448,31 @@ /// EmitPopulateLanguageMap - Emit the PopulateLanguageMap() function. void EmitPopulateLanguageMap (const RecordKeeper& Records, std::ostream& O) { - // Get the relevant field out of RecordKeeper - Record* LangMapRecord = Records.getDef("LanguageMap"); - if (!LangMapRecord) - throw std::string("Language map definition not found!"); - - ListInit* LangsToSuffixesList = LangMapRecord->getValueAsListInit("map"); - if (!LangsToSuffixesList) - throw std::string("Error in the language map definition!"); - // Generate code O << "namespace {\n\n"; O << "void PopulateLanguageMapLocal(LanguageMap& langMap) {\n"; - for (unsigned i = 0; i < LangsToSuffixesList->size(); ++i) { - Record* LangToSuffixes = LangsToSuffixesList->getElementAsRecord(i); + // Get the relevant field out of RecordKeeper + Record* LangMapRecord = Records.getDef("LanguageMap"); - const std::string& Lang = LangToSuffixes->getValueAsString("lang"); - const ListInit* Suffixes = LangToSuffixes->getValueAsListInit("suffixes"); + // It is allowed for a plugin to have no language map. + if (LangMapRecord) { - for (unsigned i = 0; i < Suffixes->size(); ++i) - O << Indent1 << "langMap[\"" - << InitPtrToString(Suffixes->getElement(i)) - << "\"] = \"" << Lang << "\";\n"; + ListInit* LangsToSuffixesList = LangMapRecord->getValueAsListInit("map"); + if (!LangsToSuffixesList) + throw std::string("Error in the language map definition!"); + + for (unsigned i = 0; i < LangsToSuffixesList->size(); ++i) { + Record* LangToSuffixes = LangsToSuffixesList->getElementAsRecord(i); + + const std::string& Lang = LangToSuffixes->getValueAsString("lang"); + const ListInit* Suffixes = LangToSuffixes->getValueAsListInit("suffixes"); + + for (unsigned i = 0; i < Suffixes->size(); ++i) + O << Indent1 << "langMap[\"" + << InitPtrToString(Suffixes->getElement(i)) + << "\"] = \"" << Lang << "\";\n"; + } } O << "}\n\n}\n\n"; @@ -1492,13 +1494,11 @@ } /// TypecheckGraph - Check that names for output and input languages -/// on all edges do match. -// TOFIX: It would be nice if this function also checked for cycles -// and multiple default edges in the graph (better error -// reporting). Unfortunately, it is awkward to do right now because -// our intermediate representation is not sufficiently -// sophisticated. Algorithms like these require a real graph instead of -// an AST. +/// on all edges do match. This doesn't do much when the information +/// about the whole graph is not available (i.e. when compiling most +/// plugins). +// TODO: add a --check-graph switch to llvmc2. It would also make it +// possible to detect cycles and multiple default edges. void TypecheckGraph (Record* CompilationGraph, const ToolPropertiesList& TPList) { StringMap > ToolToInLang; @@ -1511,18 +1511,18 @@ for (unsigned i = 0; i < edges->size(); ++i) { Record* Edge = edges->getElementAsRecord(i); - Record* A = Edge->getValueAsDef("a"); - Record* B = Edge->getValueAsDef("b"); - StringMap::iterator IA = ToolToOutLang.find(A->getName()); - StringMap >::iterator IB = ToolToInLang.find(B->getName()); - if (IA == IAE) - throw A->getName() + ": no such tool!"; - if (IB == IBE) - throw B->getName() + ": no such tool!"; - if (A->getName() != "root" && IB->second.count(IA->second) == 0) - throw "Edge " + A->getName() + "->" + B->getName() - + ": output->input language mismatch"; - if (B->getName() == "root") + const std::string& A = Edge->getValueAsString("a"); + const std::string& B = Edge->getValueAsString("b"); + StringMap::iterator IA = ToolToOutLang.find(A); + StringMap >::iterator IB = ToolToInLang.find(B); + + if (A != "root") { + if (IA != IAE && IB != IBE && IB->second.count(IA->second) == 0) + throw "Edge " + A + "->" + B + + ": output->input language mismatch"; + } + + if (B == "root") throw std::string("Edges back to the root are not allowed!"); } } @@ -1578,13 +1578,13 @@ for (unsigned i = 0; i < edges->size(); ++i) { Record* Edge = edges->getElementAsRecord(i); - Record* B = Edge->getValueAsDef("b"); + const std::string& B = Edge->getValueAsString("b"); DagInit* Weight = Edge->getValueAsDag("weight"); if (isDagEmpty(Weight)) continue; - EmitEdgeClass(i, B->getName(), Weight, OptDescs, O); + EmitEdgeClass(i, B, Weight, OptDescs, O); } } @@ -1605,13 +1605,12 @@ for (unsigned i = 0; i < edges->size(); ++i) { Record* Edge = edges->getElementAsRecord(i); - Record* A = Edge->getValueAsDef("a"); - Record* B = Edge->getValueAsDef("b"); + const std::string& A = Edge->getValueAsString("a"); + const std::string& B = Edge->getValueAsString("b"); - if (A->getName() != "root") - ToolsInGraph.insert(A->getName()); - if (B->getName() != "root") - ToolsInGraph.insert(B->getName()); + if (A != "root") + ToolsInGraph.insert(A); + ToolsInGraph.insert(B); } for (llvm::StringSet<>::iterator B = ToolsInGraph.begin(), @@ -1624,14 +1623,14 @@ for (unsigned i = 0; i < edges->size(); ++i) { Record* Edge = edges->getElementAsRecord(i); - Record* A = Edge->getValueAsDef("a"); - Record* B = Edge->getValueAsDef("b"); + const std::string& A = Edge->getValueAsString("a"); + const std::string& B = Edge->getValueAsString("b"); DagInit* Weight = Edge->getValueAsDag("weight"); - O << Indent1 << "G.insertEdge(\"" << A->getName() << "\", "; + O << Indent1 << "G.insertEdge(\"" << A << "\", "; if (isDagEmpty(Weight)) - O << "new SimpleEdge(\"" << B->getName() << "\")"; + O << "new SimpleEdge(\"" << B << "\")"; else O << "new Edge" << i << "()"; @@ -1763,6 +1762,7 @@ EmitIncludes(O); // Get a list of all defined Tools. + RecordVector Tools = Records.getAllDerivedDefinitions("Tool"); if (Tools.empty()) throw std::string("No tool definitions found!"); @@ -1773,8 +1773,8 @@ CollectToolProperties(Tools.begin(), Tools.end(), tool_props, opt_descs); RecordVector OptionLists = Records.getAllDerivedDefinitions("OptionList"); - CollectPropertiesFromOptionList(OptionLists.begin(), OptionLists.end(), - opt_descs); + CollectPropertiesFromOptionLists(OptionLists.begin(), OptionLists.end(), + opt_descs); // Check that there are no options without side effects (specified // only in the OptionList). @@ -1795,6 +1795,9 @@ E = tool_props.end(); B!=E; ++B) EmitToolClassDefinition(*(*B), opt_descs, O); + // TOTHINK: Nothing actually prevents us from having multiple + // compilation graphs in a single plugin; OTOH, I do not see how + // that could be useful. Record* CompilationGraphRecord = Records.getDef("CompilationGraph"); if (!CompilationGraphRecord) throw std::string("Compilation graph description not found!"); From foldr at codedgers.com Mon Nov 17 11:29:43 2008 From: foldr at codedgers.com (Mikhail Glushenkov) Date: Mon, 17 Nov 2008 17:29:43 -0000 Subject: [llvm-commits] [llvm] r59448 - /llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Message-ID: <200811171729.mAHHTh5d010681@zion.cs.uiuc.edu> Author: foldr Date: Mon Nov 17 11:29:42 2008 New Revision: 59448 URL: http://llvm.org/viewvc/llvm-project?rev=59448&view=rev Log: Filter ToolPropertiesList to exclude all Tools not mentioned in the compilation graph. Modified: llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Modified: llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp?rev=59448&r1=59447&r2=59448&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Mon Nov 17 11:29:42 2008 @@ -750,7 +750,7 @@ { // Iterate over a properties list of every Tool definition for (;B!=E;++B) { - Record* T = *B; + const Record* T = *B; // Throws an exception if the value does not exist. ListInit* PropList = T->getValueAsListInit("properties"); @@ -1453,7 +1453,7 @@ O << "void PopulateLanguageMapLocal(LanguageMap& langMap) {\n"; // Get the relevant field out of RecordKeeper - Record* LangMapRecord = Records.getDef("LanguageMap"); + const Record* LangMapRecord = Records.getDef("LanguageMap"); // It is allowed for a plugin to have no language map. if (LangMapRecord) { @@ -1463,7 +1463,7 @@ throw std::string("Error in the language map definition!"); for (unsigned i = 0; i < LangsToSuffixesList->size(); ++i) { - Record* LangToSuffixes = LangsToSuffixesList->getElementAsRecord(i); + const Record* LangToSuffixes = LangsToSuffixesList->getElementAsRecord(i); const std::string& Lang = LangToSuffixes->getValueAsString("lang"); const ListInit* Suffixes = LangToSuffixes->getValueAsListInit("suffixes"); @@ -1499,7 +1499,7 @@ /// plugins). // TODO: add a --check-graph switch to llvmc2. It would also make it // possible to detect cycles and multiple default edges. -void TypecheckGraph (Record* CompilationGraph, +void TypecheckGraph (const Record* CompilationGraph, const ToolPropertiesList& TPList) { StringMap > ToolToInLang; StringMap ToolToOutLang; @@ -1510,7 +1510,7 @@ StringMap >::iterator IBE = ToolToInLang.end(); for (unsigned i = 0; i < edges->size(); ++i) { - Record* Edge = edges->getElementAsRecord(i); + const Record* Edge = edges->getElementAsRecord(i); const std::string& A = Edge->getValueAsString("a"); const std::string& B = Edge->getValueAsString("b"); StringMap::iterator IA = ToolToOutLang.find(A); @@ -1571,13 +1571,13 @@ } /// EmitEdgeClasses - Emit Edge* classes that represent graph edges. -void EmitEdgeClasses (Record* CompilationGraph, +void EmitEdgeClasses (const Record* CompilationGraph, const GlobalOptionDescriptions& OptDescs, std::ostream& O) { ListInit* edges = CompilationGraph->getValueAsListInit("edges"); for (unsigned i = 0; i < edges->size(); ++i) { - Record* Edge = edges->getElementAsRecord(i); + const Record* Edge = edges->getElementAsRecord(i); const std::string& B = Edge->getValueAsString("b"); DagInit* Weight = Edge->getValueAsDag("weight"); @@ -1590,7 +1590,8 @@ /// EmitPopulateCompilationGraph - Emit the PopulateCompilationGraph() /// function. -void EmitPopulateCompilationGraph (Record* CompilationGraph, +void EmitPopulateCompilationGraph (const Record* CompilationGraph, + const ToolPropertiesList& ToolProps, std::ostream& O) { ListInit* edges = CompilationGraph->getValueAsListInit("edges"); @@ -1598,31 +1599,16 @@ O << "namespace {\n\n"; O << "void PopulateCompilationGraphLocal(CompilationGraph& G) {\n"; - // Insert vertices. - // Only tools mentioned in the graph definition are inserted. - - llvm::StringSet<> ToolsInGraph; - - for (unsigned i = 0; i < edges->size(); ++i) { - Record* Edge = edges->getElementAsRecord(i); - const std::string& A = Edge->getValueAsString("a"); - const std::string& B = Edge->getValueAsString("b"); - - if (A != "root") - ToolsInGraph.insert(A); - ToolsInGraph.insert(B); - } - - for (llvm::StringSet<>::iterator B = ToolsInGraph.begin(), - E = ToolsInGraph.end(); B != E; ++B) - O << Indent1 << "G.insertNode(new " << B->first() << "());\n"; + for (ToolPropertiesList::const_iterator B = ToolProps.begin(), + E = ToolProps.end(); B != E; ++B) + O << Indent1 << "G.insertNode(new " << (*B)->Name << "());\n"; O << '\n'; // Insert edges. for (unsigned i = 0; i < edges->size(); ++i) { - Record* Edge = edges->getElementAsRecord(i); + const Record* Edge = edges->getElementAsRecord(i); const std::string& A = Edge->getValueAsString("a"); const std::string& B = Edge->getValueAsString("b"); DagInit* Weight = Edge->getValueAsDag("weight"); @@ -1750,6 +1736,47 @@ << "{ return s == NULL ? \"\" : s; }\n\n"; } +/// NotInGraph - Helper function object for FilterNotInGraph. +struct NotInGraph { +private: + const llvm::StringSet<>& ToolsInGraph_; + +public: + NotInGraph(const llvm::StringSet<>& ToolsInGraph) + : ToolsInGraph_(ToolsInGraph) + {} + + bool operator()(const IntrusiveRefCntPtr& x) { + return (ToolsInGraph_.count(x->Name) == 0); + } +}; + +/// FilterNotInGraph - Filter out from ToolProps all Tools not +/// mentioned in the compilation graph definition. +void FilterNotInGraph (const Record* CompilationGraph, + ToolPropertiesList& ToolProps) { + + // List all tools mentioned in the graph. + llvm::StringSet<> ToolsInGraph; + ListInit* edges = CompilationGraph->getValueAsListInit("edges"); + + for (unsigned i = 0; i < edges->size(); ++i) { + const Record* Edge = edges->getElementAsRecord(i); + const std::string& A = Edge->getValueAsString("a"); + const std::string& B = Edge->getValueAsString("b"); + + if (A != "root") + ToolsInGraph.insert(A); + ToolsInGraph.insert(B); + } + + // Filter ToolPropertiesList. + ToolPropertiesList::iterator new_end = + std::remove_if(ToolProps.begin(), ToolProps.end(), + NotInGraph(ToolsInGraph)); + ToolProps.erase(new_end, ToolProps.end()); +} + // End of anonymous namespace } @@ -1768,48 +1795,50 @@ throw std::string("No tool definitions found!"); // Gather information from the Tool description dags. - ToolPropertiesList tool_props; - GlobalOptionDescriptions opt_descs; - CollectToolProperties(Tools.begin(), Tools.end(), tool_props, opt_descs); + ToolPropertiesList ToolProps; + GlobalOptionDescriptions OptDescs; + CollectToolProperties(Tools.begin(), Tools.end(), ToolProps, OptDescs); RecordVector OptionLists = Records.getAllDerivedDefinitions("OptionList"); CollectPropertiesFromOptionLists(OptionLists.begin(), OptionLists.end(), - opt_descs); + OptDescs); + + // TOTHINK: Nothing actually prevents us from having multiple + // compilation graphs in a single plugin; OTOH, I do not see how + // that could be useful. + const Record* CompilationGraphRecord = Records.getDef("CompilationGraph"); + if (!CompilationGraphRecord) + throw std::string("Compilation graph description not found!"); + + FilterNotInGraph(CompilationGraphRecord, ToolProps); + + // Typecheck the compilation graph. + TypecheckGraph(CompilationGraphRecord, ToolProps); // Check that there are no options without side effects (specified // only in the OptionList). - CheckForSuperfluousOptions(tool_props, opt_descs); + CheckForSuperfluousOptions(ToolProps, OptDescs); // Emit global option registration code. - EmitOptionDescriptions(opt_descs, O); + EmitOptionDescriptions(OptDescs, O); // Emit hook declarations. - EmitHookDeclarations(tool_props, O); + EmitHookDeclarations(ToolProps, O); // Emit PopulateLanguageMap() function // (a language map maps from file extensions to language names). EmitPopulateLanguageMap(Records, O); // Emit Tool classes. - for (ToolPropertiesList::const_iterator B = tool_props.begin(), - E = tool_props.end(); B!=E; ++B) - EmitToolClassDefinition(*(*B), opt_descs, O); - - // TOTHINK: Nothing actually prevents us from having multiple - // compilation graphs in a single plugin; OTOH, I do not see how - // that could be useful. - Record* CompilationGraphRecord = Records.getDef("CompilationGraph"); - if (!CompilationGraphRecord) - throw std::string("Compilation graph description not found!"); - - // Typecheck the compilation graph. - TypecheckGraph(CompilationGraphRecord, tool_props); + for (ToolPropertiesList::const_iterator B = ToolProps.begin(), + E = ToolProps.end(); B!=E; ++B) + EmitToolClassDefinition(*(*B), OptDescs, O); // Emit Edge# classes. - EmitEdgeClasses(CompilationGraphRecord, opt_descs, O); + EmitEdgeClasses(CompilationGraphRecord, OptDescs, O); // Emit PopulateCompilationGraph() function. - EmitPopulateCompilationGraph(CompilationGraphRecord, O); + EmitPopulateCompilationGraph(CompilationGraphRecord, ToolProps, O); // Emit code for plugin registration. EmitRegisterPlugin(O); From foldr at codedgers.com Mon Nov 17 11:30:25 2008 From: foldr at codedgers.com (Mikhail Glushenkov) Date: Mon, 17 Nov 2008 17:30:25 -0000 Subject: [llvm-commits] [llvm] r59449 - in /llvm/trunk: include/llvm/CompilerDriver/Common.td include/llvm/CompilerDriver/Plugin.h tools/llvmc2/driver/Plugin.cpp utils/TableGen/LLVMCConfigurationEmitter.cpp Message-ID: <200811171730.mAHHUPOP010758@zion.cs.uiuc.edu> Author: foldr Date: Mon Nov 17 11:30:25 2008 New Revision: 59449 URL: http://llvm.org/viewvc/llvm-project?rev=59449&view=rev Log: Support dependencies between plugins by priority-sorting. Modified: llvm/trunk/include/llvm/CompilerDriver/Common.td llvm/trunk/include/llvm/CompilerDriver/Plugin.h llvm/trunk/tools/llvmc2/driver/Plugin.cpp llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Modified: llvm/trunk/include/llvm/CompilerDriver/Common.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CompilerDriver/Common.td?rev=59449&r1=59448&r2=59449&view=diff ============================================================================== --- llvm/trunk/include/llvm/CompilerDriver/Common.td (original) +++ llvm/trunk/include/llvm/CompilerDriver/Common.td Mon Nov 17 11:30:25 2008 @@ -65,6 +65,11 @@ def inc_weight; def dec_weight; +// Used to specify plugin priority. +class PluginPriority { + int priority = p; +} + // Option list - used to specify aliases and sometimes help strings. class OptionList l> { list options = l; Modified: llvm/trunk/include/llvm/CompilerDriver/Plugin.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CompilerDriver/Plugin.h?rev=59449&r1=59448&r2=59449&view=diff ============================================================================== --- llvm/trunk/include/llvm/CompilerDriver/Plugin.h (original) +++ llvm/trunk/include/llvm/CompilerDriver/Plugin.h Mon Nov 17 11:30:25 2008 @@ -24,6 +24,11 @@ /// BasePlugin - An abstract base class for all LLVMC plugins. struct BasePlugin { + /// Priority - Plugin priority, useful for handling dependencies + /// between plugins. Plugins with lower priorities are loaded + /// first. + virtual int Priority() const = 0; + /// PopulateLanguageMap - The auto-generated function that fills in /// the language map (map from file extensions to language names). virtual void PopulateLanguageMap(LanguageMap&) const = 0; Modified: llvm/trunk/tools/llvmc2/driver/Plugin.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/driver/Plugin.cpp?rev=59449&r1=59448&r2=59449&view=diff ============================================================================== --- llvm/trunk/tools/llvmc2/driver/Plugin.cpp (original) +++ llvm/trunk/tools/llvmc2/driver/Plugin.cpp Mon Nov 17 11:30:25 2008 @@ -13,6 +13,7 @@ #include "llvm/CompilerDriver/Plugin.h" +#include #include namespace { @@ -27,6 +28,13 @@ static bool pluginListInitialized = false; typedef std::vector PluginList; static PluginList Plugins; + + struct ByPriority { + bool operator()(const llvmc::BasePlugin* lhs, + const llvmc::BasePlugin* rhs) { + return lhs->Priority() < rhs->Priority(); + } + }; } namespace llvmc { @@ -36,6 +44,7 @@ for (PluginRegistry::iterator B = PluginRegistry::begin(), E = PluginRegistry::end(); B != E; ++B) Plugins.push_back(B->instantiate()); + std::sort(Plugins.begin(), Plugins.end(), ByPriority()); } pluginListInitialized = true; } Modified: llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp?rev=59449&r1=59448&r2=59449&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Mon Nov 17 11:30:25 2008 @@ -771,7 +771,7 @@ GlobalOptionDescriptions& OptDescs) { // Iterate over a properties list of every Tool definition - for (;B!=E;++B) { + for (; B!=E; ++B) { RecordVector::value_type T = *B; // Throws an exception if the value does not exist. ListInit* PropList = T->getValueAsListInit("options"); @@ -1701,9 +1701,10 @@ } /// EmitRegisterPlugin - Emit code to register this plugin. -void EmitRegisterPlugin(std::ostream& O) { +void EmitRegisterPlugin(int Priority, std::ostream& O) { O << "namespace {\n\n" - << "struct Plugin : public llvmc::BasePlugin {\n" + << "struct Plugin : public llvmc::BasePlugin {\n\n" + << Indent1 << "int Priority() const { return " << Priority << "; }\n\n" << Indent1 << "void PopulateLanguageMap(LanguageMap& langMap) const\n" << Indent1 << "{ PopulateLanguageMapLocal(langMap); }\n\n" << Indent1 @@ -1777,6 +1778,15 @@ ToolProps.erase(new_end, ToolProps.end()); } +int CalculatePriority(RecordVector::const_iterator B, + RecordVector::const_iterator E) { + int total = 0; + for (; B!=E; ++B) { + total += static_cast((*B)->getValueAsInt("priority")); + } + return total; +} + // End of anonymous namespace } @@ -1799,7 +1809,8 @@ GlobalOptionDescriptions OptDescs; CollectToolProperties(Tools.begin(), Tools.end(), ToolProps, OptDescs); - RecordVector OptionLists = Records.getAllDerivedDefinitions("OptionList"); + const RecordVector& OptionLists = + Records.getAllDerivedDefinitions("OptionList"); CollectPropertiesFromOptionLists(OptionLists.begin(), OptionLists.end(), OptDescs); @@ -1841,7 +1852,10 @@ EmitPopulateCompilationGraph(CompilationGraphRecord, ToolProps, O); // Emit code for plugin registration. - EmitRegisterPlugin(O); + const RecordVector& Priorities = + Records.getAllDerivedDefinitions("PluginPriority"); + EmitRegisterPlugin(CalculatePriority(Priorities.begin(), Priorities.end()), + O); // EOF } catch (std::exception& Error) { From richard at xmos.com Mon Nov 17 11:34:31 2008 From: richard at xmos.com (Richard Osborne) Date: Mon, 17 Nov 2008 17:34:31 -0000 Subject: [llvm-commits] [llvm] r59450 - in /llvm/trunk: lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp test/CodeGen/XCore/2008-11-17-Shl64.ll Message-ID: <200811171734.mAHHYW5u011095@zion.cs.uiuc.edu> Author: friedgold Date: Mon Nov 17 11:34:31 2008 New Revision: 59450 URL: http://llvm.org/viewvc/llvm-project?rev=59450&view=rev Log: Don't produce ADDC/ADDE when expanding SHL unless they are legal for the target. This fixes PR3080. Added: llvm/trunk/test/CodeGen/XCore/2008-11-17-Shl64.ll Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp?rev=59450&r1=59449&r2=59450&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp Mon Nov 17 11:34:31 2008 @@ -1073,7 +1073,8 @@ } else if (Amt == NVTBits) { Lo = DAG.getConstant(0, NVT); Hi = InL; - } else if (Amt == 1) { + } else if (Amt == 1 && + TLI.isOperationLegal(ISD::ADDC, TLI.getTypeToExpandTo(NVT))) { // Emit this X << 1 as X+X. SDVTList VTList = DAG.getVTList(NVT, MVT::Flag); SDValue LoOps[2] = { InL, InL }; Added: llvm/trunk/test/CodeGen/XCore/2008-11-17-Shl64.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/XCore/2008-11-17-Shl64.ll?rev=59450&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/XCore/2008-11-17-Shl64.ll (added) +++ llvm/trunk/test/CodeGen/XCore/2008-11-17-Shl64.ll Mon Nov 17 11:34:31 2008 @@ -0,0 +1,6 @@ +; RUN: llvm-as < %s | llc -march=xcore > %t1.s +; PR3080 +define i64 @test(i64 %a) { + %result = shl i64 %a, 1 + ret i64 %result +} From dpatel at apple.com Mon Nov 17 11:58:27 2008 From: dpatel at apple.com (Devang Patel) Date: Mon, 17 Nov 2008 09:58:27 -0800 Subject: [llvm-commits] [llvm] r59011 - in /llvm/trunk: include/llvm/Transforms/Utils/DbgInfoUtils.h lib/Transforms/Utils/DbgInfoUtils.cpp In-Reply-To: References: <200811110053.mAB0r3Iq013378@zion.cs.uiuc.edu> Message-ID: <54A3C2D3-D92D-496A-BAEA-E19E6F7B55D5@apple.com> On Nov 15, 2008, at 10:41 PM, Chris Lattner wrote: > > On Nov 10, 2008, at 4:53 PM, Devang Patel wrote: > >> Author: dpatel >> Date: Mon Nov 10 18:53:02 2008 >> New Revision: 59011 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=59011&view=rev >> Log: >> Add utility routines to remove dead debug info. > > Hi Devang, > > Instead of making this a "minipass" which is called by other passes, > why not just make instcombine (and only instcombine) do this? > Instcombine runs many times in a typical compilation, and it can do > this very cheaply (cost proportional to the number of debug > intrinsics, instead of scanning entire functions even when there are > none). However we want $ opt -adce foo.bc -o foo.optimzed.bc to preserve valid debug info. >> + // If a llvm.dbg.stoppoint is placed just before an >> unconditional >> + // branch then remove the llvm.dbg.stoppoint intrinsic. >> + else if (BranchInst *UC = dyn_cast(Next)) { >> + if (UC->isUnconditional() > > Why? This doesn't seem right. If it is a unconditional branch then sooner or later the cfg will be simplified and this may get in a way for a pass doing simple clean. - Devang From dalej at apple.com Mon Nov 17 12:23:30 2008 From: dalej at apple.com (Dale Johannesen) Date: Mon, 17 Nov 2008 10:23:30 -0800 Subject: [llvm-commits] [llvm] r59266 - in /llvm/trunk: include/llvm/Target/TargetLowering.h lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86RegisterInfo.td In-Reply-To: References: <200811132152.mADLqcPa015827@zion.cs.uiuc.edu> <5FBF1CA4-27ED-4B71-B733-FFF6093E840D@apple.com> <96A12729-6628-4FBE-890B-7FCACA7F2DB4@apple.com> Message-ID: On Nov 16, 2008, at 9:23 PMPST, Evan Cheng wrote: > I have mixed feelings about this solution. That said, why does isel > need to pre-assign registers if the new register class ensures the > right allocation is done? > > Evan ISel (or, if you prefer, the FE) preassigns registers when there is only one register that fits the constraint, as with "d". This is no different except that two registers are involved instead of one. Handling "d" and "A" similarly is clearly right. IMO doing fixed-register allocations early is the right idea; this should prevent RAs from assigning conflicting registers across the asm and having to spill them, at least sometimes, and there's no upside to delaying the assignment. (Early allocation for tied constraints is inferior, though; that's a matter of the RAs not being able to do them right.) > On Nov 16, 2008, at 4:48 PM, Dale Johannesen wrote: > >> >> On Nov 15, 2008, at 7:32 PM, Chris Lattner wrote: >>>>> Does llc slow down >>>>> at "-O0" by adding another register class? >>>> >>>>> Finally, how does this fix the bug? Is isel still doing the >>>>> 'register >>>>> allocation' of the 'A' constraint, or is it turning it into vregs >>>>> from >>>>> the GRAD reg class? I thought the bug was that the isel regalloc >>>>> was >>>>> assigning the tied register to EAX and then it just wasn't >>>>> available >>>>> when handling the A constraint. >>>> >>>> >>>> ISel is allocating the registers for both arguments before and >>>> after >>>> the patch. Since 'A' and the tied register were both previously >>>> treated as C_RegisterClass, they were allocated in argument order, >>>> which led to the problem you say. Now that 'A' is marked as >>>> using a >>>> specific hard register, it gets allocated before the tied register, >>>> which then knows it cannot use EAX and EDX. >>> >>> Ok. My problem with this is that adding register classes to the >>> target *just* to support inline asm seems bad. Inline is an evil >>> menace to the code generator, and IMO it should have as minimal >>> impact >>> on it as possible. >> >> I don't like inline asm either. I don't know a compiler person who >> does. That's irrelevant; we need to support it, and supporting it >> badly is not going to make it go away. I'm strongly of the opinion >> this is the cleanest and most elegant solution for this problem. >> >>> I'd be much happier with changing the SDISel code to do an extra >>> pass >>> over the input/output list of the asm to look for these and handle >>> them early if that would solve the problem. This way, only inline >>> asm >>> pays the compile-time cost, and the targets don't have to sprout new >>> reg classes to match the GCC constraint letters. Do you think this >>> is >>> a reasonable approach? >> >> It is already doing a pass to handle fixed-register constraint >> letters. In other cases these are marked specially by the front end, >> as "{eax}". I did consider extending that notation to allow "{eax >> +edx}", but the register class solution is much simpler and cleaner >> than changing all front ends, plural. Further, it handles a target- >> dependent problem in the target code, where it belongs. >> >> I really don't understand your objection to adding register classes. >> This is free aside from an unnoticeable amount of compile time, and a >> good general mechanism. Actually I think it would be preferable to >> handle the other fixed-register constraints, like "d", with register >> classes and rip all that conversion crap out of the front end (or >> ends, if it's gotten into clang already). Not that I'm planning to >> do >> that. >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From kremenek at apple.com Mon Nov 17 12:25:45 2008 From: kremenek at apple.com (Ted Kremenek) Date: Mon, 17 Nov 2008 18:25:45 -0000 Subject: [llvm-commits] [llvm] r59452 - /llvm/tags/checker/checker-128/ Message-ID: <200811171825.mAHIPjMi013093@zion.cs.uiuc.edu> Author: kremenek Date: Mon Nov 17 12:25:45 2008 New Revision: 59452 URL: http://llvm.org/viewvc/llvm-project?rev=59452&view=rev Log: Tagging checker-128. Added: llvm/tags/checker/checker-128/ - copied from r59451, llvm/trunk/ From dpatel at apple.com Mon Nov 17 12:37:54 2008 From: dpatel at apple.com (Devang Patel) Date: Mon, 17 Nov 2008 18:37:54 -0000 Subject: [llvm-commits] [llvm] r59454 - /llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp Message-ID: <200811171837.mAHIbsGa013591@zion.cs.uiuc.edu> Author: dpatel Date: Mon Nov 17 12:37:53 2008 New Revision: 59454 URL: http://llvm.org/viewvc/llvm-project?rev=59454&view=rev Log: Let AnalyzeAlloca() remove debug intrinsics. Modified: llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp Modified: llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp?rev=59454&r1=59453&r2=59454&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp Mon Nov 17 12:37:53 2008 @@ -277,21 +277,6 @@ AllocaPointerVal = 0; } - /// RemoveDebugUses - Remove uses of the alloca in DbgInfoInstrinsics. - void RemoveDebugUses(AllocaInst *AI) { - for (Value::use_iterator U = AI->use_begin(), E = AI->use_end(); - U != E;) { - Instruction *User = cast(*U); - ++U; - if (BitCastInst *BC = dyn_cast(User)) { - assert(BC->hasOneUse() && "Unexpected alloca uses!"); - DbgInfoIntrinsic *DI = cast(*BC->use_begin()); - DI->eraseFromParent(); - BC->eraseFromParent(); - } - } - } - /// AnalyzeAlloca - Scan the uses of the specified alloca, filling in our /// ivars. void AnalyzeAlloca(AllocaInst *AI) { @@ -301,9 +286,18 @@ // and decide whether all of the loads and stores to the alloca are within // the same basic block. for (Value::use_iterator U = AI->use_begin(), E = AI->use_end(); - U != E; ++U) { + U != E;) { Instruction *User = cast(*U); - if (StoreInst *SI = dyn_cast(User)) { + ++U; + if (BitCastInst *BC = dyn_cast(User)) { + // Remove any uses of this alloca in DbgInfoInstrinsics. + assert(BC->hasOneUse() && "Unexpected alloca uses!"); + DbgInfoIntrinsic *DI = cast(*BC->use_begin()); + DI->eraseFromParent(); + BC->eraseFromParent(); + continue; + } + else if (StoreInst *SI = dyn_cast(User)) { // Remember the basic blocks which define new values for the alloca DefiningBlocks.push_back(SI->getParent()); AllocaPointerVal = SI->getOperand(0); @@ -344,9 +338,6 @@ assert(AI->getParent()->getParent() == &F && "All allocas should be in the same function, which is same as DF!"); - // Remove any uses of this alloca in DbgInfoInstrinsics. - Info.RemoveDebugUses(AI); - if (AI->use_empty()) { // If there are no uses of the alloca, just delete it now. if (AST) AST->deleteValue(AI); From dpatel at apple.com Mon Nov 17 12:38:07 2008 From: dpatel at apple.com (Devang Patel) Date: Mon, 17 Nov 2008 10:38:07 -0800 Subject: [llvm-commits] [llvm] r58887 - /llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp In-Reply-To: References: <200811080412.mA84CJfD015867@zion.cs.uiuc.edu> Message-ID: On Nov 16, 2008, at 9:58 AM, Chris Lattner wrote: > > On Nov 7, 2008, at 8:12 PM, Daniel Dunbar wrote: > >> Author: ddunbar >> Date: Fri Nov 7 22:12:17 2008 >> New Revision: 58887 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=58887&view=rev >> Log: >> Rework r58829, allowing removal of dbg info intrinsics during alloca >> promotion. >> - Eliminate uses after free and simplify tests. > > Thanks Daniel and Devang. > > One request: this is now doing a whole extra pass over all of the > load/stores to an alloca just to check for debug info (in > RemoveDebugUses). Could you make AnalyzeAlloca do the "removing of > debug intrinsic" logic instead? This should restore the speed of > mem2reg at -O2/-O3 etc. Done. - Devang From daniel at zuster.org Mon Nov 17 12:44:39 2008 From: daniel at zuster.org (Daniel Dunbar) Date: Mon, 17 Nov 2008 10:44:39 -0800 Subject: [llvm-commits] [llvm] r59454 - /llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp In-Reply-To: <200811171837.mAHIbsGa013591@zion.cs.uiuc.edu> References: <200811171837.mAHIbsGa013591@zion.cs.uiuc.edu> Message-ID: <6a8523d60811171044h543b0c53p77a6178e4af90a10@mail.gmail.com> On Mon, Nov 17, 2008 at 10:37 AM, Devang Patel wrote: > Author: dpatel > Date: Mon Nov 17 12:37:53 2008 > New Revision: 59454 > > URL: http://llvm.org/viewvc/llvm-project?rev=59454&view=rev > Log: > Let AnalyzeAlloca() remove debug intrinsics. > > Modified: > llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp > > Modified: llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp?rev=59454&r1=59453&r2=59454&view=diff > > ============================================================================== > --- llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp (original) > +++ llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp Mon Nov 17 12:37:53 2008 > @@ -277,21 +277,6 @@ > AllocaPointerVal = 0; > } > > - /// RemoveDebugUses - Remove uses of the alloca in DbgInfoInstrinsics. > - void RemoveDebugUses(AllocaInst *AI) { > - for (Value::use_iterator U = AI->use_begin(), E = AI->use_end(); > - U != E;) { > - Instruction *User = cast(*U); > - ++U; > - if (BitCastInst *BC = dyn_cast(User)) { > - assert(BC->hasOneUse() && "Unexpected alloca uses!"); > - DbgInfoIntrinsic *DI = cast(*BC->use_begin()); > - DI->eraseFromParent(); > - BC->eraseFromParent(); > - } > - } > - } > - > /// AnalyzeAlloca - Scan the uses of the specified alloca, filling in our > /// ivars. > void AnalyzeAlloca(AllocaInst *AI) { > @@ -301,9 +286,18 @@ > // and decide whether all of the loads and stores to the alloca are within > // the same basic block. > for (Value::use_iterator U = AI->use_begin(), E = AI->use_end(); > - U != E; ++U) { > + U != E;) { > Instruction *User = cast(*U); > - if (StoreInst *SI = dyn_cast(User)) { > + ++U; > + if (BitCastInst *BC = dyn_cast(User)) { > + // Remove any uses of this alloca in DbgInfoInstrinsics. > + assert(BC->hasOneUse() && "Unexpected alloca uses!"); > + DbgInfoIntrinsic *DI = cast(*BC->use_begin()); > + DI->eraseFromParent(); > + BC->eraseFromParent(); > + continue; > + } > + else if (StoreInst *SI = dyn_cast(User)) { > // Remember the basic blocks which define new values for the alloca > DefiningBlocks.push_back(SI->getParent()); > AllocaPointerVal = SI->getOperand(0); > @@ -344,9 +338,6 @@ > assert(AI->getParent()->getParent() == &F && > "All allocas should be in the same function, which is same as DF!"); > > - // Remove any uses of this alloca in DbgInfoInstrinsics. > - Info.RemoveDebugUses(AI); > - > if (AI->use_empty()) { > // If there are no uses of the alloca, just delete it now. > if (AST) AST->deleteValue(AI); Note that this is still doing a lot of work when removing the debug info leaves the alloca with no uses. I believe the right thing is just to move the AnalyzeAlloca() call above this test here. - Daniel From dalej at apple.com Mon Nov 17 12:56:34 2008 From: dalej at apple.com (Dale Johannesen) Date: Mon, 17 Nov 2008 18:56:34 -0000 Subject: [llvm-commits] [llvm] r59455 - /llvm/trunk/lib/Target/PowerPC/README.txt Message-ID: <200811171856.mAHIuZbh014197@zion.cs.uiuc.edu> Author: johannes Date: Mon Nov 17 12:56:34 2008 New Revision: 59455 URL: http://llvm.org/viewvc/llvm-project?rev=59455&view=rev Log: Move some former testcases (low-probability codegen optimizations) into this wishlist. Modified: llvm/trunk/lib/Target/PowerPC/README.txt Modified: llvm/trunk/lib/Target/PowerPC/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/README.txt?rev=59455&r1=59454&r2=59455&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/README.txt (original) +++ llvm/trunk/lib/Target/PowerPC/README.txt Mon Nov 17 12:56:34 2008 @@ -752,3 +752,48 @@ The 'mr' could be eliminated to folding the add into the cmp better. //===---------------------------------------------------------------------===// +Codegen for the following (low-probability) case deteriorated considerably +when the correctness fixes for unordered comparisons went in (PR 642, 58871). +It should be possible to recover the code quality described in the comments. + +; RUN: llvm-as < %s | llc -march=ppc32 | grep or | count 3 +; This should produce one 'or' or 'cror' instruction per function. + +; RUN: llvm-as < %s | llc -march=ppc32 | grep mfcr | count 3 +; PR2964 + +define i32 @test(double %x, double %y) nounwind { +entry: + %tmp3 = fcmp ole double %x, %y ; [#uses=1] + %tmp345 = zext i1 %tmp3 to i32 ; [#uses=1] + ret i32 %tmp345 +} + +define i32 @test2(double %x, double %y) nounwind { +entry: + %tmp3 = fcmp one double %x, %y ; [#uses=1] + %tmp345 = zext i1 %tmp3 to i32 ; [#uses=1] + ret i32 %tmp345 +} + +define i32 @test3(double %x, double %y) nounwind { +entry: + %tmp3 = fcmp ugt double %x, %y ; [#uses=1] + %tmp34 = zext i1 %tmp3 to i32 ; [#uses=1] + ret i32 %tmp34 +} +//===----------------------------------------------------------------------===// +; RUN: llvm-as < %s | llc -march=ppc32 | not grep fneg + +; This could generate FSEL with appropriate flags (FSEL is not IEEE-safe, and +; should not be generated except with -enable-finite-only-fp-math or the like). +; With the correctness fixes for PR642 (58871) LowerSELECT_CC would need to +; recognize a more elaborate tree than a simple SETxx. + +define double @test_FNEG_sel(double %A, double %B, double %C) { + %D = sub double -0.000000e+00, %A ; [#uses=1] + %Cond = fcmp ugt double %D, -0.000000e+00 ; [#uses=1] + %E = select i1 %Cond, double %B, double %C ; [#uses=1] + ret double %E +} + From dalej at apple.com Mon Nov 17 12:57:46 2008 From: dalej at apple.com (Dale Johannesen) Date: Mon, 17 Nov 2008 18:57:46 -0000 Subject: [llvm-commits] [llvm] r59456 - in /llvm/trunk/test/CodeGen/PowerPC: compare-fcmp-ord.ll fnegsel.ll Message-ID: <200811171857.mAHIvkdT014249@zion.cs.uiuc.edu> Author: johannes Date: Mon Nov 17 12:57:45 2008 New Revision: 59456 URL: http://llvm.org/viewvc/llvm-project?rev=59456&view=rev Log: Remove these, which test for optimizations that are not currently done (cf PowerPC/README.txt). Removed: llvm/trunk/test/CodeGen/PowerPC/compare-fcmp-ord.ll llvm/trunk/test/CodeGen/PowerPC/fnegsel.ll Removed: llvm/trunk/test/CodeGen/PowerPC/compare-fcmp-ord.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/compare-fcmp-ord.ll?rev=59455&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/PowerPC/compare-fcmp-ord.ll (original) +++ llvm/trunk/test/CodeGen/PowerPC/compare-fcmp-ord.ll (removed) @@ -1,29 +0,0 @@ -; RUN: llvm-as < %s | llc -march=ppc32 | grep or | count 3 -; This should produce one 'or' or 'cror' instruction per function. - -; XFAIL: * - -; RUN: llvm-as < %s | llc -march=ppc32 | grep mfcr | count 3 -; PR2964 - -define i32 @test(double %x, double %y) nounwind { -entry: - %tmp3 = fcmp ole double %x, %y ; [#uses=1] - %tmp345 = zext i1 %tmp3 to i32 ; [#uses=1] - ret i32 %tmp345 -} - -define i32 @test2(double %x, double %y) nounwind { -entry: - %tmp3 = fcmp one double %x, %y ; [#uses=1] - %tmp345 = zext i1 %tmp3 to i32 ; [#uses=1] - ret i32 %tmp345 -} - -define i32 @test3(double %x, double %y) nounwind { -entry: - %tmp3 = fcmp ugt double %x, %y ; [#uses=1] - %tmp34 = zext i1 %tmp3 to i32 ; [#uses=1] - ret i32 %tmp34 -} - Removed: llvm/trunk/test/CodeGen/PowerPC/fnegsel.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/fnegsel.ll?rev=59455&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/PowerPC/fnegsel.ll (original) +++ llvm/trunk/test/CodeGen/PowerPC/fnegsel.ll (removed) @@ -1,16 +0,0 @@ -; RUN: llvm-as < %s | llc -march=ppc32 | not grep fneg - -; FSEL is not IEEE-safe, and should not be generated except with -; -enable-finite-only-fp-math. Further, it can't be generated for -; GT ever; it tests for GE. Leaving in the test for now as it may -; be useful as a basis for a correct test. -; -; XFAIL: * - -define double @test_FNEG_sel(double %A, double %B, double %C) { - %D = sub double -0.000000e+00, %A ; [#uses=1] - %Cond = fcmp ugt double %D, -0.000000e+00 ; [#uses=1] - %E = select i1 %Cond, double %B, double %C ; [#uses=1] - ret double %E -} - From clattner at apple.com Mon Nov 17 13:19:59 2008 From: clattner at apple.com (Chris Lattner) Date: Mon, 17 Nov 2008 11:19:59 -0800 Subject: [llvm-commits] [llvm] r59011 - in /llvm/trunk: include/llvm/Transforms/Utils/DbgInfoUtils.h lib/Transforms/Utils/DbgInfoUtils.cpp In-Reply-To: <54A3C2D3-D92D-496A-BAEA-E19E6F7B55D5@apple.com> References: <200811110053.mAB0r3Iq013378@zion.cs.uiuc.edu> <54A3C2D3-D92D-496A-BAEA-E19E6F7B55D5@apple.com> Message-ID: <9F356AF5-E16F-477F-BE78-886427813F42@apple.com> On Nov 17, 2008, at 9:58 AM, Devang Patel wrote: > > On Nov 15, 2008, at 10:41 PM, Chris Lattner wrote: > >> >> On Nov 10, 2008, at 4:53 PM, Devang Patel wrote: >> >>> Author: dpatel >>> Date: Mon Nov 10 18:53:02 2008 >>> New Revision: 59011 >>> >>> URL: http://llvm.org/viewvc/llvm-project?rev=59011&view=rev >>> Log: >>> Add utility routines to remove dead debug info. >> >> Hi Devang, >> >> Instead of making this a "minipass" which is called by other >> passes, why not just make instcombine (and only instcombine) do >> this? Instcombine runs many times in a typical compilation, and it >> can do this very cheaply (cost proportional to the number of debug >> intrinsics, instead of scanning entire functions even when there >> are none). > > However we want > $ opt -adce foo.bc -o foo.optimzed.bc > to preserve valid debug info. How wouldn't it? >>> + // If a llvm.dbg.stoppoint is placed just before an >>> unconditional >>> + // branch then remove the llvm.dbg.stoppoint intrinsic. >>> + else if (BranchInst *UC = dyn_cast(Next)) { >>> + if (UC->isUnconditional() >> >> Why? This doesn't seem right. > > If it is a unconditional branch then sooner or later the cfg will be > simplified and this may get in a way for a pass doing simple clean. I don't understand. You're saying that the intrinsic will prevent simplifycfg from doing a transformation? That seems like a problem that should be fixed in the simplifycfg pass. -Chris From dpatel at apple.com Mon Nov 17 13:29:09 2008 From: dpatel at apple.com (Devang Patel) Date: Mon, 17 Nov 2008 11:29:09 -0800 Subject: [llvm-commits] [llvm] r59011 - in /llvm/trunk: include/llvm/Transforms/Utils/DbgInfoUtils.h lib/Transforms/Utils/DbgInfoUtils.cpp In-Reply-To: <9F356AF5-E16F-477F-BE78-886427813F42@apple.com> References: <200811110053.mAB0r3Iq013378@zion.cs.uiuc.edu> <54A3C2D3-D92D-496A-BAEA-E19E6F7B55D5@apple.com> <9F356AF5-E16F-477F-BE78-886427813F42@apple.com> Message-ID: <626078D7-1C1D-483F-819F-A87CA0FEB928@apple.com> On Nov 17, 2008, at 11:19 AM, Chris Lattner wrote: > > On Nov 17, 2008, at 9:58 AM, Devang Patel wrote: > >> >> On Nov 15, 2008, at 10:41 PM, Chris Lattner wrote: >> >>> >>> On Nov 10, 2008, at 4:53 PM, Devang Patel wrote: >>> >>>> Author: dpatel >>>> Date: Mon Nov 10 18:53:02 2008 >>>> New Revision: 59011 >>>> >>>> URL: http://llvm.org/viewvc/llvm-project?rev=59011&view=rev >>>> Log: >>>> Add utility routines to remove dead debug info. >>> >>> Hi Devang, >>> >>> Instead of making this a "minipass" which is called by other >>> passes, why not just make instcombine (and only instcombine) do >>> this? Instcombine runs many times in a typical compilation, and >>> it can do this very cheaply (cost proportional to the number of >>> debug intrinsics, instead of scanning entire functions even when >>> there are none). >> >> However we want >> $ opt -adce foo.bc -o foo.optimzed.bc >> to preserve valid debug info. > > How wouldn't it? Well, this routine will be used by adce and any other pass that removes dead instructions. If we just make instcombine responsible for this cleanup then we are requiring that instcombine is always scheduled after such passes. Is that OK ? > > > >>>> + // If a llvm.dbg.stoppoint is placed just before an >>>> unconditional >>>> + // branch then remove the llvm.dbg.stoppoint intrinsic. >>>> + else if (BranchInst *UC = dyn_cast(Next)) { >>>> + if (UC->isUnconditional() >>> >>> Why? This doesn't seem right. >> >> If it is a unconditional branch then sooner or later the cfg will >> be simplified and this may get in a way for a pass doing simple >> clean. > > I don't understand. You're saying that the intrinsic will prevent > simplifycfg from doing a transformation? That seems like a problem > that should be fixed in the simplifycfg pass. Yes, simplifycfg pass should be fixed (if that is the case, I need to verify it thoroughly). But many passes do their own little cleanups. On the other side, unconditional branches are usually removed by the optimizer, which means associated debug info is also gone. > > > -Chris - Devang From clattner at apple.com Mon Nov 17 13:37:07 2008 From: clattner at apple.com (Chris Lattner) Date: Mon, 17 Nov 2008 11:37:07 -0800 Subject: [llvm-commits] [llvm] r59011 - in /llvm/trunk: include/llvm/Transforms/Utils/DbgInfoUtils.h lib/Transforms/Utils/DbgInfoUtils.cpp In-Reply-To: <626078D7-1C1D-483F-819F-A87CA0FEB928@apple.com> References: <200811110053.mAB0r3Iq013378@zion.cs.uiuc.edu> <54A3C2D3-D92D-496A-BAEA-E19E6F7B55D5@apple.com> <9F356AF5-E16F-477F-BE78-886427813F42@apple.com> <626078D7-1C1D-483F-819F-A87CA0FEB928@apple.com> Message-ID: On Nov 17, 2008, at 11:29 AM, Devang Patel wrote: >>>> Instead of making this a "minipass" which is called by other >>>> passes, why not just make instcombine (and only instcombine) do >>>> this? Instcombine runs many times in a typical compilation, and >>>> it can do this very cheaply (cost proportional to the number of >>>> debug intrinsics, instead of scanning entire functions even when >>>> there are none). >>> >>> However we want >>> $ opt -adce foo.bc -o foo.optimzed.bc >>> to preserve valid debug info. >> >> How wouldn't it? > > Well, this routine will be used by adce and any other pass that > removes dead instructions. If we just make instcombine responsible > for this cleanup then we are requiring that instcombine is always > scheduled after such passes. Is that OK ? One of us is missing something here. The change that this makes is an *optimization*, it isn't required for correctness, right? If so, instcombine should be the only thing that does it. ADCE doesn't do constant folding or many other possible cleanups, why would it do this one? If this is required for correctness, then something else is seriously wrong. >>>>> >>>>> + // If a llvm.dbg.stoppoint is placed just before an >>>>> unconditional >>>>> + // branch then remove the llvm.dbg.stoppoint intrinsic. >>>>> + else if (BranchInst *UC = dyn_cast(Next)) { >>>>> + if (UC->isUnconditional() >>>> >>>> Why? This doesn't seem right. >>> >>> If it is a unconditional branch then sooner or later the cfg will >>> be simplified and this may get in a way for a pass doing simple >>> clean. >> >> I don't understand. You're saying that the intrinsic will prevent >> simplifycfg from doing a transformation? That seems like a problem >> that should be fixed in the simplifycfg pass. > > Yes, simplifycfg pass should be fixed (if that is the case, I need > to verify it thoroughly). But many passes do their own little > cleanups. On the other side, unconditional branches are usually > removed by the optimizer, which means associated debug info is also > gone. I can easily make LLVM IR that requires the stoppoint for valid debug info. Something silly like this: stoppoint() br next next: call bar() stoppoint() You need the stoppoint before the branch to be able to stop on the call. Zapping these unconditionally is not acceptable. -Chris From gohman at apple.com Mon Nov 17 13:45:20 2008 From: gohman at apple.com (Dan Gohman) Date: Mon, 17 Nov 2008 19:45:20 -0000 Subject: [llvm-commits] [llvm] r59458 - /llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Message-ID: <200811171945.mAHJjKfu015883@zion.cs.uiuc.edu> Author: djg Date: Mon Nov 17 13:45:19 2008 New Revision: 59458 URL: http://llvm.org/viewvc/llvm-project?rev=59458&view=rev Log: Use SUnit's CycleBound field instead of duplicating it in a side-car datastructure Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp?rev=59458&r1=59457&r2=59458&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Mon Nov 17 13:45:19 2008 @@ -55,9 +55,8 @@ /// PendingQueue - This contains all of the instructions whose operands have /// been issued, but their results are not ready yet (due to the latency of /// the operation). Once the operands becomes available, the instruction is - /// added to the AvailableQueue. This keeps track of each SUnit and the - /// number of cycles left to execute before the operation is available. - std::vector > PendingQueue; + /// added to the AvailableQueue. + std::vector PendingQueue; /// HazardRec - The hazard recognizer to use. HazardRecognizer *HazardRec; @@ -134,7 +133,9 @@ AvailableCycle = std::max(AvailableCycle, PredDoneCycle); } - PendingQueue.push_back(std::make_pair(AvailableCycle, SuccSU)); + assert(SuccSU->CycleBound == 0 && "CycleBound already assigned!"); + SuccSU->CycleBound = AvailableCycle; + PendingQueue.push_back(SuccSU); } } @@ -176,14 +177,14 @@ // Check to see if any of the pending instructions are ready to issue. If // so, add them to the available queue. for (unsigned i = 0, e = PendingQueue.size(); i != e; ++i) { - if (PendingQueue[i].first == CurCycle) { - AvailableQueue->push(PendingQueue[i].second); - PendingQueue[i].second->isAvailable = true; + if (PendingQueue[i]->CycleBound == CurCycle) { + AvailableQueue->push(PendingQueue[i]); + PendingQueue[i]->isAvailable = true; PendingQueue[i] = PendingQueue.back(); PendingQueue.pop_back(); --i; --e; } else { - assert(PendingQueue[i].first > CurCycle && "Negative latency?"); + assert(PendingQueue[i]->CycleBound > CurCycle && "Negative latency?"); } } From gohman at apple.com Mon Nov 17 13:52:36 2008 From: gohman at apple.com (Dan Gohman) Date: Mon, 17 Nov 2008 19:52:36 -0000 Subject: [llvm-commits] [llvm] r59461 - /llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp Message-ID: <200811171952.mAHJqaqY016115@zion.cs.uiuc.edu> Author: djg Date: Mon Nov 17 13:52:36 2008 New Revision: 59461 URL: http://llvm.org/viewvc/llvm-project?rev=59461&view=rev Log: Don't bother doing latency calculations in the "fast" scheduler. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp?rev=59461&r1=59460&r2=59461&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp Mon Nov 17 13:52:36 2008 @@ -139,12 +139,6 @@ /// the AvailableQueue if the count reaches zero. Also update its cycle bound. void ScheduleDAGFast::ReleasePred(SUnit *PredSU, bool isChain, unsigned CurCycle) { - // FIXME: the distance between two nodes is not always == the predecessor's - // latency. For example, the reader can very well read the register written - // by the predecessor later than the issue cycle. It also depends on the - // interrupt model (drain vs. freeze). - PredSU->CycleBound = std::max(PredSU->CycleBound, CurCycle + PredSU->Latency); - --PredSU->NumSuccsLeft; #ifndef NDEBUG @@ -277,7 +271,6 @@ // FIXME: Calculate height / depth and propagate the changes? NewSU->Depth = SU->Depth; NewSU->Height = SU->Height; - ComputeLatency(NewSU); // LoadNode may already exist. This can happen when there is another // load from the same location and producing the same type of value @@ -293,7 +286,6 @@ LoadSU->Depth = SU->Depth; LoadSU->Height = SU->Height; - ComputeLatency(LoadSU); } SUnit *ChainPred = NULL; @@ -530,13 +522,11 @@ LRegsMap.clear(); SUnit *CurSU = AvailableQueue.pop(); while (CurSU) { - if (CurSU->CycleBound <= CurCycle) { - SmallVector LRegs; - if (!DelayForLiveRegsBottomUp(CurSU, LRegs)) - break; - Delayed = true; - LRegsMap.insert(std::make_pair(CurSU, LRegs)); - } + SmallVector LRegs; + if (!DelayForLiveRegsBottomUp(CurSU, LRegs)) + break; + Delayed = true; + LRegsMap.insert(std::make_pair(CurSU, LRegs)); CurSU->isPending = true; // This SU is not in AvailableQueue right now. NotReady.push_back(CurSU); From baldrick at free.fr Mon Nov 17 14:52:39 2008 From: baldrick at free.fr (Duncan Sands) Date: Mon, 17 Nov 2008 20:52:39 -0000 Subject: [llvm-commits] [llvm] r59464 - in /llvm/trunk: lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp lib/CodeGen/SelectionDAG/LegalizeTypes.h test/CodeGen/XCore/cos.ll test/CodeGen/XCore/exp.ll test/CodeGen/XCore/exp2.ll test/CodeGen/XCore/fneg.ll test/CodeGen/XCore/log.ll test/CodeGen/XCore/log10.ll test/CodeGen/XCore/log2.ll test/CodeGen/XCore/pow.ll test/CodeGen/XCore/powi.ll test/CodeGen/XCore/sin.ll test/CodeGen/XCore/sqrt.ll Message-ID: <200811172052.mAHKqd5M018376@zion.cs.uiuc.edu> Author: baldrick Date: Mon Nov 17 14:52:38 2008 New Revision: 59464 URL: http://llvm.org/viewvc/llvm-project?rev=59464&view=rev Log: Add soft float support for a bunch more operations. Original patch by Richard Osborne, tweaked and extended by your humble servant. Added: llvm/trunk/test/CodeGen/XCore/cos.ll llvm/trunk/test/CodeGen/XCore/exp.ll llvm/trunk/test/CodeGen/XCore/exp2.ll llvm/trunk/test/CodeGen/XCore/fneg.ll llvm/trunk/test/CodeGen/XCore/log.ll llvm/trunk/test/CodeGen/XCore/log10.ll llvm/trunk/test/CodeGen/XCore/log2.ll llvm/trunk/test/CodeGen/XCore/pow.ll llvm/trunk/test/CodeGen/XCore/powi.ll llvm/trunk/test/CodeGen/XCore/sin.ll llvm/trunk/test/CodeGen/XCore/sqrt.ll Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp?rev=59464&r1=59463&r2=59464&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp Mon Nov 17 14:52:38 2008 @@ -61,14 +61,28 @@ break; case ISD::FABS: R = SoftenFloatRes_FABS(N); break; case ISD::FADD: R = SoftenFloatRes_FADD(N); break; + case ISD::FCEIL: R = SoftenFloatRes_FCEIL(N); break; case ISD::FCOPYSIGN: R = SoftenFloatRes_FCOPYSIGN(N); break; + case ISD::FCOS: R = SoftenFloatRes_FCOS(N); break; case ISD::FDIV: R = SoftenFloatRes_FDIV(N); break; + case ISD::FEXP: R = SoftenFloatRes_FEXP(N); break; + case ISD::FEXP2: R = SoftenFloatRes_FEXP2(N); break; + case ISD::FFLOOR: R = SoftenFloatRes_FFLOOR(N); break; + case ISD::FLOG: R = SoftenFloatRes_FLOG(N); break; + case ISD::FLOG2: R = SoftenFloatRes_FLOG2(N); break; + case ISD::FLOG10: R = SoftenFloatRes_FLOG10(N); break; case ISD::FMUL: R = SoftenFloatRes_FMUL(N); break; + case ISD::FNEARBYINT: R = SoftenFloatRes_FNEARBYINT(N); break; + case ISD::FNEG: R = SoftenFloatRes_FNEG(N); break; case ISD::FP_EXTEND: R = SoftenFloatRes_FP_EXTEND(N); break; case ISD::FP_ROUND: R = SoftenFloatRes_FP_ROUND(N); break; case ISD::FPOW: R = SoftenFloatRes_FPOW(N); break; case ISD::FPOWI: R = SoftenFloatRes_FPOWI(N); break; + case ISD::FRINT: R = SoftenFloatRes_FRINT(N); break; + case ISD::FSIN: R = SoftenFloatRes_FSIN(N); break; + case ISD::FSQRT: R = SoftenFloatRes_FSQRT(N); break; case ISD::FSUB: R = SoftenFloatRes_FSUB(N); break; + case ISD::FTRUNC: R = SoftenFloatRes_FTRUNC(N); break; case ISD::LOAD: R = SoftenFloatRes_LOAD(N); break; case ISD::SELECT: R = SoftenFloatRes_SELECT(N); break; case ISD::SELECT_CC: R = SoftenFloatRes_SELECT_CC(N); break; @@ -103,7 +117,7 @@ unsigned Size = NVT.getSizeInBits(); // Mask = ~(1 << (Size-1)) - SDValue Mask = DAG.getConstant(APInt::getAllOnesValue(Size).clear(Size-1), + SDValue Mask = DAG.getConstant(APInt::getAllOnesValue(Size).clear(Size-1), NVT); SDValue Op = GetSoftenedFloat(N->getOperand(0)); return DAG.getNode(ISD::AND, NVT, Op, Mask); @@ -121,6 +135,17 @@ NVT, Ops, 2, false); } +SDValue DAGTypeLegalizer::SoftenFloatRes_FCEIL(SDNode *N) { + MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); + SDValue Op = GetSoftenedFloat(N->getOperand(0)); + return MakeLibCall(GetFPLibCall(N->getValueType(0), + RTLIB::CEIL_F32, + RTLIB::CEIL_F64, + RTLIB::CEIL_F80, + RTLIB::CEIL_PPCF128), + NVT, &Op, 1, false); +} + SDValue DAGTypeLegalizer::SoftenFloatRes_FCOPYSIGN(SDNode *N) { SDValue LHS = GetSoftenedFloat(N->getOperand(0)); SDValue RHS = BitConvertToInteger(N->getOperand(1)); @@ -160,6 +185,17 @@ return DAG.getNode(ISD::OR, LVT, LHS, SignBit); } +SDValue DAGTypeLegalizer::SoftenFloatRes_FCOS(SDNode *N) { + MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); + SDValue Op = GetSoftenedFloat(N->getOperand(0)); + return MakeLibCall(GetFPLibCall(N->getValueType(0), + RTLIB::COS_F32, + RTLIB::COS_F64, + RTLIB::COS_F80, + RTLIB::COS_PPCF128), + NVT, &Op, 1, false); +} + SDValue DAGTypeLegalizer::SoftenFloatRes_FDIV(SDNode *N) { MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)), @@ -172,6 +208,72 @@ NVT, Ops, 2, false); } +SDValue DAGTypeLegalizer::SoftenFloatRes_FEXP(SDNode *N) { + MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); + SDValue Op = GetSoftenedFloat(N->getOperand(0)); + return MakeLibCall(GetFPLibCall(N->getValueType(0), + RTLIB::EXP_F32, + RTLIB::EXP_F64, + RTLIB::EXP_F80, + RTLIB::EXP_PPCF128), + NVT, &Op, 1, false); +} + +SDValue DAGTypeLegalizer::SoftenFloatRes_FEXP2(SDNode *N) { + MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); + SDValue Op = GetSoftenedFloat(N->getOperand(0)); + return MakeLibCall(GetFPLibCall(N->getValueType(0), + RTLIB::EXP2_F32, + RTLIB::EXP2_F64, + RTLIB::EXP2_F80, + RTLIB::EXP2_PPCF128), + NVT, &Op, 1, false); +} + +SDValue DAGTypeLegalizer::SoftenFloatRes_FFLOOR(SDNode *N) { + MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); + SDValue Op = GetSoftenedFloat(N->getOperand(0)); + return MakeLibCall(GetFPLibCall(N->getValueType(0), + RTLIB::FLOOR_F32, + RTLIB::FLOOR_F64, + RTLIB::FLOOR_F80, + RTLIB::FLOOR_PPCF128), + NVT, &Op, 1, false); +} + +SDValue DAGTypeLegalizer::SoftenFloatRes_FLOG(SDNode *N) { + MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); + SDValue Op = GetSoftenedFloat(N->getOperand(0)); + return MakeLibCall(GetFPLibCall(N->getValueType(0), + RTLIB::LOG_F32, + RTLIB::LOG_F64, + RTLIB::LOG_F80, + RTLIB::LOG_PPCF128), + NVT, &Op, 1, false); +} + +SDValue DAGTypeLegalizer::SoftenFloatRes_FLOG2(SDNode *N) { + MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); + SDValue Op = GetSoftenedFloat(N->getOperand(0)); + return MakeLibCall(GetFPLibCall(N->getValueType(0), + RTLIB::LOG2_F32, + RTLIB::LOG2_F64, + RTLIB::LOG2_F80, + RTLIB::LOG2_PPCF128), + NVT, &Op, 1, false); +} + +SDValue DAGTypeLegalizer::SoftenFloatRes_FLOG10(SDNode *N) { + MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); + SDValue Op = GetSoftenedFloat(N->getOperand(0)); + return MakeLibCall(GetFPLibCall(N->getValueType(0), + RTLIB::LOG10_F32, + RTLIB::LOG10_F64, + RTLIB::LOG10_F80, + RTLIB::LOG10_PPCF128), + NVT, &Op, 1, false); +} + SDValue DAGTypeLegalizer::SoftenFloatRes_FMUL(SDNode *N) { MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)), @@ -184,6 +286,30 @@ NVT, Ops, 2, false); } +SDValue DAGTypeLegalizer::SoftenFloatRes_FNEARBYINT(SDNode *N) { + MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); + SDValue Op = GetSoftenedFloat(N->getOperand(0)); + return MakeLibCall(GetFPLibCall(N->getValueType(0), + RTLIB::NEARBYINT_F32, + RTLIB::NEARBYINT_F64, + RTLIB::NEARBYINT_F80, + RTLIB::NEARBYINT_PPCF128), + NVT, &Op, 1, false); +} + +SDValue DAGTypeLegalizer::SoftenFloatRes_FNEG(SDNode *N) { + MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); + // Expand Y = FNEG(X) -> Y = SUB -0.0, X + SDValue Ops[2] = { DAG.getConstantFP(-0.0, NVT), + GetSoftenedFloat(N->getOperand(0)) }; + return MakeLibCall(GetFPLibCall(N->getValueType(0), + RTLIB::SUB_F32, + RTLIB::SUB_F64, + RTLIB::SUB_F80, + RTLIB::SUB_PPCF128), + NVT, Ops, 2, false); +} + SDValue DAGTypeLegalizer::SoftenFloatRes_FP_EXTEND(SDNode *N) { MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); SDValue Op = N->getOperand(0); @@ -225,6 +351,39 @@ NVT, Ops, 2, false); } +SDValue DAGTypeLegalizer::SoftenFloatRes_FRINT(SDNode *N) { + MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); + SDValue Op = GetSoftenedFloat(N->getOperand(0)); + return MakeLibCall(GetFPLibCall(N->getValueType(0), + RTLIB::RINT_F32, + RTLIB::RINT_F64, + RTLIB::RINT_F80, + RTLIB::RINT_PPCF128), + NVT, &Op, 1, false); +} + +SDValue DAGTypeLegalizer::SoftenFloatRes_FSIN(SDNode *N) { + MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); + SDValue Op = GetSoftenedFloat(N->getOperand(0)); + return MakeLibCall(GetFPLibCall(N->getValueType(0), + RTLIB::SIN_F32, + RTLIB::SIN_F64, + RTLIB::SIN_F80, + RTLIB::SIN_PPCF128), + NVT, &Op, 1, false); +} + +SDValue DAGTypeLegalizer::SoftenFloatRes_FSQRT(SDNode *N) { + MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); + SDValue Op = GetSoftenedFloat(N->getOperand(0)); + return MakeLibCall(GetFPLibCall(N->getValueType(0), + RTLIB::SQRT_F32, + RTLIB::SQRT_F64, + RTLIB::SQRT_F80, + RTLIB::SQRT_PPCF128), + NVT, &Op, 1, false); +} + SDValue DAGTypeLegalizer::SoftenFloatRes_FSUB(SDNode *N) { MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)), @@ -237,6 +396,17 @@ NVT, Ops, 2, false); } +SDValue DAGTypeLegalizer::SoftenFloatRes_FTRUNC(SDNode *N) { + MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); + SDValue Op = GetSoftenedFloat(N->getOperand(0)); + return MakeLibCall(GetFPLibCall(N->getValueType(0), + RTLIB::TRUNC_F32, + RTLIB::TRUNC_F64, + RTLIB::TRUNC_F80, + RTLIB::TRUNC_PPCF128), + NVT, &Op, 1, false); +} + SDValue DAGTypeLegalizer::SoftenFloatRes_LOAD(SDNode *N) { LoadSDNode *L = cast(N); MVT VT = N->getValueType(0); @@ -607,7 +777,7 @@ case ISD::FPOW: ExpandFloatRes_FPOW(N, Lo, Hi); break; case ISD::FPOWI: ExpandFloatRes_FPOWI(N, Lo, Hi); break; case ISD::FRINT: ExpandFloatRes_FRINT(N, Lo, Hi); break; - case ISD::FSIN: ExpandFloatRes_FABS(N, Lo, Hi); break; + case ISD::FSIN: ExpandFloatRes_FSIN(N, Lo, Hi); break; case ISD::FSQRT: ExpandFloatRes_FSQRT(N, Lo, Hi); break; case ISD::FSUB: ExpandFloatRes_FSUB(N, Lo, Hi); break; case ISD::FTRUNC: ExpandFloatRes_FTRUNC(N, Lo, Hi); break; @@ -926,14 +1096,14 @@ // though. if (SrcVT.bitsLE(MVT::i32)) { // The integer can be represented exactly in an f64. - Src = DAG.getNode(isSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, + Src = DAG.getNode(isSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, MVT::i32, Src); Lo = DAG.getConstantFP(APFloat(APInt(NVT.getSizeInBits(), 0)), NVT); Hi = DAG.getNode(ISD::SINT_TO_FP, NVT, Src); } else { RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; if (SrcVT.bitsLE(MVT::i64)) { - Src = DAG.getNode(isSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, + Src = DAG.getNode(isSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, MVT::i64, Src); LC = RTLIB::SINTTOFP_I64_PPCF128; } else if (SrcVT.bitsLE(MVT::i128)) { Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h?rev=59464&r1=59463&r2=59464&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h Mon Nov 17 14:52:38 2008 @@ -351,14 +351,28 @@ SDValue SoftenFloatRes_ConstantFP(ConstantFPSDNode *N); SDValue SoftenFloatRes_FABS(SDNode *N); SDValue SoftenFloatRes_FADD(SDNode *N); + SDValue SoftenFloatRes_FCEIL(SDNode *N); SDValue SoftenFloatRes_FCOPYSIGN(SDNode *N); + SDValue SoftenFloatRes_FCOS(SDNode *N); SDValue SoftenFloatRes_FDIV(SDNode *N); + SDValue SoftenFloatRes_FEXP(SDNode *N); + SDValue SoftenFloatRes_FEXP2(SDNode *N); + SDValue SoftenFloatRes_FFLOOR(SDNode *N); + SDValue SoftenFloatRes_FLOG(SDNode *N); + SDValue SoftenFloatRes_FLOG2(SDNode *N); + SDValue SoftenFloatRes_FLOG10(SDNode *N); SDValue SoftenFloatRes_FMUL(SDNode *N); + SDValue SoftenFloatRes_FNEARBYINT(SDNode *N); + SDValue SoftenFloatRes_FNEG(SDNode *N); SDValue SoftenFloatRes_FP_EXTEND(SDNode *N); SDValue SoftenFloatRes_FP_ROUND(SDNode *N); SDValue SoftenFloatRes_FPOW(SDNode *N); SDValue SoftenFloatRes_FPOWI(SDNode *N); + SDValue SoftenFloatRes_FRINT(SDNode *N); + SDValue SoftenFloatRes_FSIN(SDNode *N); + SDValue SoftenFloatRes_FSQRT(SDNode *N); SDValue SoftenFloatRes_FSUB(SDNode *N); + SDValue SoftenFloatRes_FTRUNC(SDNode *N); SDValue SoftenFloatRes_LOAD(SDNode *N); SDValue SoftenFloatRes_SELECT(SDNode *N); SDValue SoftenFloatRes_SELECT_CC(SDNode *N); Added: llvm/trunk/test/CodeGen/XCore/cos.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/XCore/cos.ll?rev=59464&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/XCore/cos.ll (added) +++ llvm/trunk/test/CodeGen/XCore/cos.ll Mon Nov 17 14:52:38 2008 @@ -0,0 +1,16 @@ +; RUN: llvm-as < %s | llc -march=xcore > %t1.s +; RUN: grep "bl cosf" %t1.s | count 1 +; RUN: grep "bl cos" %t1.s | count 2 +declare double @llvm.cos.f64(double) + +define double @test(double %F) { + %result = call double @llvm.cos.f64(double %F) + ret double %result +} + +declare float @llvm.cos.f32(float) + +define float @testf(float %F) { + %result = call float @llvm.cos.f32(float %F) + ret float %result +} Added: llvm/trunk/test/CodeGen/XCore/exp.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/XCore/exp.ll?rev=59464&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/XCore/exp.ll (added) +++ llvm/trunk/test/CodeGen/XCore/exp.ll Mon Nov 17 14:52:38 2008 @@ -0,0 +1,16 @@ +; RUN: llvm-as < %s | llc -march=xcore > %t1.s +; RUN: grep "bl expf" %t1.s | count 1 +; RUN: grep "bl exp" %t1.s | count 2 +declare double @llvm.exp.f64(double) + +define double @test(double %F) { + %result = call double @llvm.exp.f64(double %F) + ret double %result +} + +declare float @llvm.exp.f32(float) + +define float @testf(float %F) { + %result = call float @llvm.exp.f32(float %F) + ret float %result +} Added: llvm/trunk/test/CodeGen/XCore/exp2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/XCore/exp2.ll?rev=59464&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/XCore/exp2.ll (added) +++ llvm/trunk/test/CodeGen/XCore/exp2.ll Mon Nov 17 14:52:38 2008 @@ -0,0 +1,16 @@ +; RUN: llvm-as < %s | llc -march=xcore > %t1.s +; RUN: grep "bl exp2f" %t1.s | count 1 +; RUN: grep "bl exp2" %t1.s | count 2 +declare double @llvm.exp2.f64(double) + +define double @test(double %F) { + %result = call double @llvm.exp2.f64(double %F) + ret double %result +} + +declare float @llvm.exp2.f32(float) + +define float @testf(float %F) { + %result = call float @llvm.exp2.f32(float %F) + ret float %result +} Added: llvm/trunk/test/CodeGen/XCore/fneg.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/XCore/fneg.ll?rev=59464&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/XCore/fneg.ll (added) +++ llvm/trunk/test/CodeGen/XCore/fneg.ll Mon Nov 17 14:52:38 2008 @@ -0,0 +1,8 @@ +; RUN: llvm-as < %s | llc -march=xcore > %t1.s +; RUN: grep "bl __subdf3" %t1.s | count 1 +define i1 @test(double %F) nounwind { +entry: + %0 = sub double -0.000000e+00, %F + %1 = fcmp olt double 0.000000e+00, %0 + ret i1 %1 +} Added: llvm/trunk/test/CodeGen/XCore/log.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/XCore/log.ll?rev=59464&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/XCore/log.ll (added) +++ llvm/trunk/test/CodeGen/XCore/log.ll Mon Nov 17 14:52:38 2008 @@ -0,0 +1,16 @@ +; RUN: llvm-as < %s | llc -march=xcore > %t1.s +; RUN: grep "bl logf" %t1.s | count 1 +; RUN: grep "bl log" %t1.s | count 2 +declare double @llvm.log.f64(double) + +define double @test(double %F) { + %result = call double @llvm.log.f64(double %F) + ret double %result +} + +declare float @llvm.log.f32(float) + +define float @testf(float %F) { + %result = call float @llvm.log.f32(float %F) + ret float %result +} Added: llvm/trunk/test/CodeGen/XCore/log10.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/XCore/log10.ll?rev=59464&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/XCore/log10.ll (added) +++ llvm/trunk/test/CodeGen/XCore/log10.ll Mon Nov 17 14:52:38 2008 @@ -0,0 +1,16 @@ +; RUN: llvm-as < %s | llc -march=xcore > %t1.s +; RUN: grep "bl log10f" %t1.s | count 1 +; RUN: grep "bl log10" %t1.s | count 2 +declare double @llvm.log10.f64(double) + +define double @test(double %F) { + %result = call double @llvm.log10.f64(double %F) + ret double %result +} + +declare float @llvm.log10.f32(float) + +define float @testf(float %F) { + %result = call float @llvm.log10.f32(float %F) + ret float %result +} Added: llvm/trunk/test/CodeGen/XCore/log2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/XCore/log2.ll?rev=59464&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/XCore/log2.ll (added) +++ llvm/trunk/test/CodeGen/XCore/log2.ll Mon Nov 17 14:52:38 2008 @@ -0,0 +1,16 @@ +; RUN: llvm-as < %s | llc -march=xcore > %t1.s +; RUN: grep "bl log2f" %t1.s | count 1 +; RUN: grep "bl log2" %t1.s | count 2 +declare double @llvm.log2.f64(double) + +define double @test(double %F) { + %result = call double @llvm.log2.f64(double %F) + ret double %result +} + +declare float @llvm.log2.f32(float) + +define float @testf(float %F) { + %result = call float @llvm.log2.f32(float %F) + ret float %result +} Added: llvm/trunk/test/CodeGen/XCore/pow.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/XCore/pow.ll?rev=59464&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/XCore/pow.ll (added) +++ llvm/trunk/test/CodeGen/XCore/pow.ll Mon Nov 17 14:52:38 2008 @@ -0,0 +1,16 @@ +; RUN: llvm-as < %s | llc -march=xcore > %t1.s +; RUN: grep "bl powf" %t1.s | count 1 +; RUN: grep "bl pow" %t1.s | count 2 +declare double @llvm.pow.f64(double, double) + +define double @test(double %F, double %power) { + %result = call double @llvm.pow.f64(double %F, double %power) + ret double %result +} + +declare float @llvm.pow.f32(float, float) + +define float @testf(float %F, float %power) { + %result = call float @llvm.pow.f32(float %F, float %power) + ret float %result +} Added: llvm/trunk/test/CodeGen/XCore/powi.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/XCore/powi.ll?rev=59464&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/XCore/powi.ll (added) +++ llvm/trunk/test/CodeGen/XCore/powi.ll Mon Nov 17 14:52:38 2008 @@ -0,0 +1,16 @@ +; RUN: llvm-as < %s | llc -march=xcore > %t1.s +; RUN: grep "bl __powidf2" %t1.s | count 1 +; RUN: grep "bl __powisf2" %t1.s | count 1 +declare double @llvm.powi.f64(double, i32) + +define double @test(double %F, i32 %power) { + %result = call double @llvm.powi.f64(double %F, i32 %power) + ret double %result +} + +declare float @llvm.powi.f32(float, i32) + +define float @testf(float %F, i32 %power) { + %result = call float @llvm.powi.f32(float %F, i32 %power) + ret float %result +} Added: llvm/trunk/test/CodeGen/XCore/sin.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/XCore/sin.ll?rev=59464&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/XCore/sin.ll (added) +++ llvm/trunk/test/CodeGen/XCore/sin.ll Mon Nov 17 14:52:38 2008 @@ -0,0 +1,16 @@ +; RUN: llvm-as < %s | llc -march=xcore > %t1.s +; RUN: grep "bl sinf" %t1.s | count 1 +; RUN: grep "bl sin" %t1.s | count 2 +declare double @llvm.sin.f64(double) + +define double @test(double %F) { + %result = call double @llvm.sin.f64(double %F) + ret double %result +} + +declare float @llvm.sin.f32(float) + +define float @testf(float %F) { + %result = call float @llvm.sin.f32(float %F) + ret float %result +} Added: llvm/trunk/test/CodeGen/XCore/sqrt.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/XCore/sqrt.ll?rev=59464&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/XCore/sqrt.ll (added) +++ llvm/trunk/test/CodeGen/XCore/sqrt.ll Mon Nov 17 14:52:38 2008 @@ -0,0 +1,16 @@ +; RUN: llvm-as < %s | llc -march=xcore > %t1.s +; RUN: grep "bl sqrtf" %t1.s | count 1 +; RUN: grep "bl sqrt" %t1.s | count 2 +declare double @llvm.sqrt.f64(double) + +define double @test(double %F) { + %result = call double @llvm.sqrt.f64(double %F) + ret double %result +} + +declare float @llvm.sqrt.f32(float) + +define float @testf(float %F) { + %result = call float @llvm.sqrt.f32(float %F) + ret float %result +} From baldrick at free.fr Mon Nov 17 14:53:39 2008 From: baldrick at free.fr (Duncan Sands) Date: Mon, 17 Nov 2008 21:53:39 +0100 Subject: [llvm-commits] [patch] Add support for softening FNEG In-Reply-To: <4921711E.5010605@xmos.com> References: <4921711E.5010605@xmos.com> Message-ID: <200811172153.39666.baldrick@free.fr> Hi Richard, I applied it after adjusting the logic for FNEG (subtract from negative zero), putting the methods in alphabetical order, and adding a few more cases. Thanks for the patch! Ciao, Duncan. From gohman at apple.com Mon Nov 17 15:31:14 2008 From: gohman at apple.com (Dan Gohman) Date: Mon, 17 Nov 2008 21:31:14 -0000 Subject: [llvm-commits] [llvm] r59465 - in /llvm/trunk/lib/CodeGen/SelectionDAG: ScheduleDAGList.cpp ScheduleDAGRRList.cpp Message-ID: <200811172131.mAHLVGn6019720@zion.cs.uiuc.edu> Author: djg Date: Mon Nov 17 15:31:02 2008 New Revision: 59465 URL: http://llvm.org/viewvc/llvm-project?rev=59465&view=rev Log: Eliminate some trivial differences between the ScheduleNodeTopDown functions in these two schedulers. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp?rev=59465&r1=59464&r2=59465&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Mon Nov 17 15:31:02 2008 @@ -148,11 +148,14 @@ Sequence.push_back(SU); SU->Cycle = CurCycle; - + // Top down: release successors. for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); I != E; ++I) ReleaseSucc(I->Dep, I->isCtrl); + + SU->isScheduled = true; + AvailableQueue->ScheduledNode(SU); } /// ListScheduleTopDown - The main loop of list scheduling for top-down @@ -235,8 +238,6 @@ if (FoundSUnit) { ScheduleNodeTopDown(FoundSUnit, CurCycle); HazardRec->EmitInstruction(FoundNode); - FoundSUnit->isScheduled = true; - AvailableQueue->ScheduledNode(FoundSUnit); // If this is a pseudo-op node, we don't want to increment the current // cycle. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp?rev=59465&r1=59464&r2=59465&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Mon Nov 17 15:31:02 2008 @@ -1137,15 +1137,17 @@ void ScheduleDAGRRList::ScheduleNodeTopDown(SUnit *SU, unsigned CurCycle) { DOUT << "*** Scheduling [" << CurCycle << "]: "; DEBUG(SU->dump(DAG)); - SU->Cycle = CurCycle; - AvailableQueue->ScheduledNode(SU); + SU->Cycle = CurCycle; + Sequence.push_back(SU); // Top down: release successors for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); I != E; ++I) ReleaseSucc(I->Dep, I->isCtrl, CurCycle); + SU->isScheduled = true; + AvailableQueue->ScheduledNode(SU); } /// ListScheduleTopDown - The main loop of list scheduling for top-down @@ -1181,7 +1183,6 @@ Sequence.push_back(0); else { ScheduleNodeTopDown(CurSU, CurCycle); - Sequence.push_back(CurSU); } ++CurCycle; } From dpatel at apple.com Mon Nov 17 15:32:02 2008 From: dpatel at apple.com (Devang Patel) Date: Mon, 17 Nov 2008 21:32:02 -0000 Subject: [llvm-commits] [llvm] r59466 - /llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp Message-ID: <200811172132.mAHLW3xs019756@zion.cs.uiuc.edu> Author: dpatel Date: Mon Nov 17 15:32:02 2008 New Revision: 59466 URL: http://llvm.org/viewvc/llvm-project?rev=59466&view=rev Log: Handle floating point ivs during doInitialization(). Modified: llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp Modified: llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp?rev=59466&r1=59465&r2=59466&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp Mon Nov 17 15:32:02 2008 @@ -96,7 +96,8 @@ void DeleteTriviallyDeadInstructions(SmallPtrSet &Insts); void OptimizeCanonicalIVType(Loop *L); - void HandleFloatingPointIV(Loop *L); + void HandleFloatingPointIV(Loop *L, PHINode *PH, + SmallPtrSet &DeadInsts); }; } @@ -433,6 +434,8 @@ PHINode *PN = cast(I); if (isa(PN->getType())) EliminatePointerRecurrence(PN, Preheader, DeadInsts); + else + HandleFloatingPointIV(L, PN, DeadInsts); } if (!DeadInsts.empty()) @@ -468,7 +471,6 @@ // auxillary induction variables. std::vector > IndVars; - HandleFloatingPointIV(L); for (BasicBlock::iterator I = Header->begin(); isa(I); ++I) { PHINode *PN = cast(I); if (PN->getType()->isInteger()) { // FIXME: when we have fast-math, enable! @@ -723,149 +725,133 @@ /// HandleFloatingPointIV - If the loop has floating induction variable /// then insert corresponding integer induction variable if possible. -void IndVarSimplify::HandleFloatingPointIV(Loop *L) { - BasicBlock *Header = L->getHeader(); - SmallVector FPHIs; - Instruction *NonPHIInsn = NULL; - - // Collect all floating point IVs first. - BasicBlock::iterator I = Header->begin(); - while(true) { - if (!isa(I)) { - NonPHIInsn = I; - break; - } - PHINode *PH = cast(I); - if (PH->getType()->isFloatingPoint()) - FPHIs.push_back(PH); - ++I; - } - - for (SmallVector::iterator I = FPHIs.begin(), E = FPHIs.end(); - I != E; ++I) { - PHINode *PH = *I; - unsigned IncomingEdge = L->contains(PH->getIncomingBlock(0)); - unsigned BackEdge = IncomingEdge^1; - - // Check incoming value. - ConstantFP *CZ = dyn_cast(PH->getIncomingValue(IncomingEdge)); - if (!CZ) continue; - APFloat PHInit = CZ->getValueAPF(); - if (!PHInit.isPosZero()) continue; - - // Check IV increment. - BinaryOperator *Incr = - dyn_cast(PH->getIncomingValue(BackEdge)); - if (!Incr) continue; - if (Incr->getOpcode() != Instruction::Add) continue; - ConstantFP *IncrValue = NULL; - unsigned IncrVIndex = 1; - if (Incr->getOperand(1) == PH) - IncrVIndex = 0; - IncrValue = dyn_cast(Incr->getOperand(IncrVIndex)); - if (!IncrValue) continue; - APFloat IVAPF = IncrValue->getValueAPF(); - APFloat One = APFloat(IVAPF.getSemantics(), 1); - if (!IVAPF.bitwiseIsEqual(One)) continue; - - // Check Incr uses. - Value::use_iterator IncrUse = Incr->use_begin(); - Instruction *U1 = cast(IncrUse++); - if (IncrUse == Incr->use_end()) continue; - Instruction *U2 = cast(IncrUse++); - if (IncrUse != Incr->use_end()) continue; - - // Find exict condition. - FCmpInst *EC = dyn_cast(U1); - if (!EC) - EC = dyn_cast(U2); - if (!EC) continue; - bool skip = false; - Instruction *Terminator = EC->getParent()->getTerminator(); - for(Value::use_iterator ECUI = EC->use_begin(), ECUE = EC->use_end(); - ECUI != ECUE; ++ECUI) { - Instruction *U = cast(ECUI); - if (U != Terminator) { - skip = true; - break; - } - } - if (skip) continue; - - // Find exit value. - ConstantFP *EV = NULL; - unsigned EVIndex = 1; - if (EC->getOperand(1) == Incr) - EVIndex = 0; - EV = dyn_cast(EC->getOperand(EVIndex)); - if (!EV) continue; - APFloat EVAPF = EV->getValueAPF(); - if (EVAPF.isNegative()) continue; - - // Find corresponding integer exit value. - uint64_t integerVal = Type::Int32Ty->getPrimitiveSizeInBits(); - bool isExact = false; - if (EVAPF.convertToInteger(&integerVal, 32, false, APFloat::rmTowardZero, &isExact) - != APFloat::opOK) - continue; - if (!isExact) continue; - - // Find new predicate for integer comparison. - CmpInst::Predicate NewPred = CmpInst::BAD_ICMP_PREDICATE; - switch (EC->getPredicate()) { - case CmpInst::FCMP_OEQ: - case CmpInst::FCMP_UEQ: - NewPred = CmpInst::ICMP_EQ; - break; - case CmpInst::FCMP_OGT: - case CmpInst::FCMP_UGT: - NewPred = CmpInst::ICMP_UGT; - break; - case CmpInst::FCMP_OGE: - case CmpInst::FCMP_UGE: - NewPred = CmpInst::ICMP_UGE; - break; - case CmpInst::FCMP_OLT: - case CmpInst::FCMP_ULT: - NewPred = CmpInst::ICMP_ULT; - break; - case CmpInst::FCMP_OLE: - case CmpInst::FCMP_ULE: - NewPred = CmpInst::ICMP_ULE; - break; - default: - break; - } - if (NewPred == CmpInst::BAD_ICMP_PREDICATE) continue; +/// For example, +/// for(double i = 0; i < 10000; ++i) +/// bar(i) +/// is converted into +/// for(int i = 0; i < 10000; ++i) +/// bar((double)i); +/// +void IndVarSimplify::HandleFloatingPointIV(Loop *L, PHINode *PH, + SmallPtrSet &DeadInsts) { - // Insert new integer induction variable. - SCEVExpander Rewriter(*SE, *LI); - PHINode *NewIV = - cast(Rewriter.getOrInsertCanonicalInductionVariable(L,Type::Int32Ty)); - ConstantInt *NewEV = ConstantInt::get(Type::Int32Ty, integerVal); - Value *LHS = (EVIndex == 1 ? NewIV->getIncomingValue(BackEdge) : NewEV); - Value *RHS = (EVIndex == 1 ? NewEV : NewIV->getIncomingValue(BackEdge)); - ICmpInst *NewEC = new ICmpInst(NewPred, LHS, RHS, EC->getNameStart(), - EC->getParent()->getTerminator()); - - // Delete old, floating point, exit comparision instruction. - SE->deleteValueFromRecords(EC); - EC->replaceAllUsesWith(NewEC); - EC->eraseFromParent(); - - // Delete old, floating point, increment instruction. - SE->deleteValueFromRecords(Incr); - Incr->replaceAllUsesWith(UndefValue::get(Incr->getType())); - Incr->eraseFromParent(); - - // Replace floating induction variable. - UIToFPInst *Conv = new UIToFPInst(NewIV, PH->getType(), "indvar.conv", - NonPHIInsn); - PH->replaceAllUsesWith(Conv); - - SE->deleteValueFromRecords(PH); - PH->removeIncomingValue((unsigned)0); - PH->removeIncomingValue((unsigned)0); + unsigned IncomingEdge = L->contains(PH->getIncomingBlock(0)); + unsigned BackEdge = IncomingEdge^1; + + // Check incoming value. + ConstantFP *CZ = dyn_cast(PH->getIncomingValue(IncomingEdge)); + if (!CZ) return; + APFloat PHInit = CZ->getValueAPF(); + if (!PHInit.isPosZero()) return; + + // Check IV increment. + BinaryOperator *Incr = + dyn_cast(PH->getIncomingValue(BackEdge)); + if (!Incr) return; + if (Incr->getOpcode() != Instruction::Add) return; + ConstantFP *IncrValue = NULL; + unsigned IncrVIndex = 1; + if (Incr->getOperand(1) == PH) + IncrVIndex = 0; + IncrValue = dyn_cast(Incr->getOperand(IncrVIndex)); + if (!IncrValue) return; + APFloat IVAPF = IncrValue->getValueAPF(); + APFloat One = APFloat(IVAPF.getSemantics(), 1); + if (!IVAPF.bitwiseIsEqual(One)) return; + + // Check Incr uses. + Value::use_iterator IncrUse = Incr->use_begin(); + Instruction *U1 = cast(IncrUse++); + if (IncrUse == Incr->use_end()) return; + Instruction *U2 = cast(IncrUse++); + if (IncrUse != Incr->use_end()) return; + + // Find exit condition. + FCmpInst *EC = dyn_cast(U1); + if (!EC) + EC = dyn_cast(U2); + if (!EC) return; + + if (BranchInst *BI = dyn_cast(EC->getParent()->getTerminator())) { + if (!BI->isConditional()) return; + if (BI->getCondition() != EC) return; + } + + // Find exit value. + ConstantFP *EV = NULL; + unsigned EVIndex = 1; + if (EC->getOperand(1) == Incr) + EVIndex = 0; + EV = dyn_cast(EC->getOperand(EVIndex)); + if (!EV) return; + APFloat EVAPF = EV->getValueAPF(); + if (EVAPF.isNegative()) return; + + // Find corresponding integer exit value. + uint64_t intEV = Type::Int32Ty->getPrimitiveSizeInBits(); + bool isExact = false; + if (EVAPF.convertToInteger(&intEV, 32, false, APFloat::rmTowardZero, &isExact) + != APFloat::opOK) + return; + if (!isExact) return; + + // Find new predicate for integer comparison. + CmpInst::Predicate NewPred = CmpInst::BAD_ICMP_PREDICATE; + switch (EC->getPredicate()) { + case CmpInst::FCMP_OEQ: + case CmpInst::FCMP_UEQ: + NewPred = CmpInst::ICMP_EQ; + break; + case CmpInst::FCMP_OGT: + case CmpInst::FCMP_UGT: + NewPred = CmpInst::ICMP_UGT; + break; + case CmpInst::FCMP_OGE: + case CmpInst::FCMP_UGE: + NewPred = CmpInst::ICMP_UGE; + break; + case CmpInst::FCMP_OLT: + case CmpInst::FCMP_ULT: + NewPred = CmpInst::ICMP_ULT; + break; + case CmpInst::FCMP_OLE: + case CmpInst::FCMP_ULE: + NewPred = CmpInst::ICMP_ULE; + break; + default: + break; } + if (NewPred == CmpInst::BAD_ICMP_PREDICATE) return; + + // Insert new integer induction variable. + PHINode *NewPHI = PHINode::Create(Type::Int32Ty, + PH->getName()+".int", PH); + NewPHI->addIncoming(Constant::getNullValue(NewPHI->getType()), + PH->getIncomingBlock(IncomingEdge)); + + Value *NewAdd = BinaryOperator::CreateAdd(NewPHI, + ConstantInt::get(Type::Int32Ty, 1), + Incr->getName()+".int", Incr); + NewPHI->addIncoming(NewAdd, PH->getIncomingBlock(BackEdge)); + + ConstantInt *NewEV = ConstantInt::get(Type::Int32Ty, intEV); + Value *LHS = (EVIndex == 1 ? NewPHI->getIncomingValue(BackEdge) : NewEV); + Value *RHS = (EVIndex == 1 ? NewEV : NewPHI->getIncomingValue(BackEdge)); + ICmpInst *NewEC = new ICmpInst(NewPred, LHS, RHS, EC->getNameStart(), + EC->getParent()->getTerminator()); + + // Delete old, floating point, exit comparision instruction. + EC->replaceAllUsesWith(NewEC); + DeadInsts.insert(EC); + + // Delete old, floating point, increment instruction. + Incr->replaceAllUsesWith(UndefValue::get(Incr->getType())); + DeadInsts.insert(Incr); + + // Replace floating induction variable. + UIToFPInst *Conv = new UIToFPInst(NewPHI, PH->getType(), "indvar.conv", + PH->getParent()->getFirstNonPHI()); + PH->replaceAllUsesWith(Conv); + DeadInsts.insert(PH); } From dpatel at apple.com Mon Nov 17 15:34:02 2008 From: dpatel at apple.com (Devang Patel) Date: Mon, 17 Nov 2008 13:34:02 -0800 Subject: [llvm-commits] [llvm] r58625 - in /llvm/trunk: lib/Transforms/Scalar/IndVarSimplify.cpp test/Transforms/IndVarsSimplify/2008-11-03-Floating.ll In-Reply-To: <48427B3A-CFA4-458E-8960-D8D6656DADDA@apple.com> References: <200811031832.mA3IWJL2019277@zion.cs.uiuc.edu> <48427B3A-CFA4-458E-8960-D8D6656DADDA@apple.com> Message-ID: <1ECF8EF4-AC9F-40D9-B293-38FEE66EE76D@apple.com> On Nov 15, 2008, at 11:30 PM, Chris Lattner wrote: > > On Nov 3, 2008, at 10:32 AM, Devang Patel wrote: > >> Author: dpatel >> Date: Mon Nov 3 12:32:19 2008 >> New Revision: 58625 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=58625&view=rev >> Log: >> Turn floating point IVs into integer IVs where possible. >> This allows SCEV users to effectively calculate trip count. >> LSR later on transforms back integer IVs to floating point IVs >> later on to avoid int-to-float casts inside the loop. > > Very nice! This does great things to simple loops. > >> @@ -466,6 +467,7 @@ >> // auxillary induction variables. >> std::vector > IndVars; >> >> + HandleFloatingPointIV(L); >> for (BasicBlock::iterator I = Header->begin(); isa(I); + >> +I) { >> PHINode *PN = cast(I); >> if (PN->getType()->isInteger()) { // FIXME: when we have fast- >> math, enable! > > This does an extra pass over all phi nodes in a loop. Since there > can be many many of them, this is suboptimal. Would it be > reasonable to make this happen at the same time when > EliminatePointerRecurrence is called? yes. done. > > >> +/// HandleFloatingPointIV - If the loop has floating induction >> variable >> +/// then insert corresponding integer induction variable if >> possible. >> +void IndVarSimplify::HandleFloatingPointIV(Loop *L) { > > Please add a comment giving an example of the sort of loop this > benefits. Something like this is sufficient: > > for (double i = 0; i < 10000; ++i) > bar((int)i); done. > > >> >> + BasicBlock *Header = L->getHeader(); >> + SmallVector FPHIs; >> + Instruction *NonPHIInsn = NULL; >> + >> + // Collect all floating point IVs first. >> + BasicBlock::iterator I = Header->begin(); >> + while(true) { >> + if (!isa(I)) { >> + NonPHIInsn = I; >> + break; >> + } >> + PHINode *PH = cast(I); >> + if (PH->getType()->isFloatingPoint()) >> + FPHIs.push_back(PH); >> + ++I; >> + } > > Why collect into a list and then handle all at once? It seems that > you can just handle them on the fly like EliminatePointerRecurrence > does. done. >> + FCmpInst *EC = dyn_cast(U1); >> + if (!EC) >> + EC = dyn_cast(U2); >> + if (!EC) continue; >> + bool skip = false; >> + Instruction *Terminator = EC->getParent()->getTerminator(); >> + for(Value::use_iterator ECUI = EC->use_begin(), ECUE = EC- >> >use_end(); >> + ECUI != ECUE; ++ECUI) { >> + Instruction *U = cast(ECUI); >> + if (U != Terminator) { >> + skip = true; >> + break; >> + } >> + } >> + if (skip) continue; > > Instead of using a 'skip' bool, please factor this inner loop out > into a static helper function. However, why do you even do this at > all? Why not just see if Terminator is a cond branch whose > condition is EC? yup, why not :). Fixed. I'll address rest of your comments in a separate commit. Thanks! - Devang From dpatel at apple.com Mon Nov 17 17:27:14 2008 From: dpatel at apple.com (Devang Patel) Date: Mon, 17 Nov 2008 23:27:14 -0000 Subject: [llvm-commits] [llvm] r59471 - in /llvm/trunk: lib/Transforms/Scalar/IndVarSimplify.cpp test/Transforms/IndVarsSimplify/2008-11-03-Floating.ll Message-ID: <200811172327.mAHNRE28023728@zion.cs.uiuc.edu> Author: dpatel Date: Mon Nov 17 17:27:13 2008 New Revision: 59471 URL: http://llvm.org/viewvc/llvm-project?rev=59471&view=rev Log: While handling floating point IVs lift restrictions on initial value and increment value. Modified: llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp llvm/trunk/test/Transforms/IndVarsSimplify/2008-11-03-Floating.ll Modified: llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp?rev=59471&r1=59470&r2=59471&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp Mon Nov 17 17:27:13 2008 @@ -446,7 +446,6 @@ bool IndVarSimplify::runOnLoop(Loop *L, LPPassManager &LPM) { - LI = &getAnalysis(); SE = &getAnalysis(); @@ -723,6 +722,19 @@ Incr->eraseFromParent(); } +static bool convertToInt(const APFloat &APF, uint64_t *intVal) { + + bool isExact = false; + if (APF.convertToInteger(intVal, 32, APF.isNegative(), + APFloat::rmTowardZero, &isExact) + != APFloat::opOK) + return false; + if (!isExact) + return false; + return true; + +} + /// HandleFloatingPointIV - If the loop has floating induction variable /// then insert corresponding integer induction variable if possible. /// For example, @@ -739,12 +751,14 @@ unsigned BackEdge = IncomingEdge^1; // Check incoming value. - ConstantFP *CZ = dyn_cast(PH->getIncomingValue(IncomingEdge)); - if (!CZ) return; - APFloat PHInit = CZ->getValueAPF(); - if (!PHInit.isPosZero()) return; - - // Check IV increment. + ConstantFP *InitValue = dyn_cast(PH->getIncomingValue(IncomingEdge)); + if (!InitValue) return; + uint64_t newInitValue = Type::Int32Ty->getPrimitiveSizeInBits(); + if (!convertToInt(InitValue->getValueAPF(), &newInitValue)) + return; + + // Check IV increment. Reject this PH if increement operation is not + // an add or increment value can not be represented by an integer. BinaryOperator *Incr = dyn_cast(PH->getIncomingValue(BackEdge)); if (!Incr) return; @@ -755,11 +769,12 @@ IncrVIndex = 0; IncrValue = dyn_cast(Incr->getOperand(IncrVIndex)); if (!IncrValue) return; - APFloat IVAPF = IncrValue->getValueAPF(); - APFloat One = APFloat(IVAPF.getSemantics(), 1); - if (!IVAPF.bitwiseIsEqual(One)) return; + uint64_t newIncrValue = Type::Int32Ty->getPrimitiveSizeInBits(); + if (!convertToInt(IncrValue->getValueAPF(), &newIncrValue)) + return; - // Check Incr uses. + // Check Incr uses. One user is PH and the other users is exit condition used + // by the conditional terminator. Value::use_iterator IncrUse = Incr->use_begin(); Instruction *U1 = cast(IncrUse++); if (IncrUse == Incr->use_end()) return; @@ -777,23 +792,17 @@ if (BI->getCondition() != EC) return; } - // Find exit value. + // Find exit value. If exit value can not be represented as an interger then + // do not handle this floating point PH. ConstantFP *EV = NULL; unsigned EVIndex = 1; if (EC->getOperand(1) == Incr) EVIndex = 0; EV = dyn_cast(EC->getOperand(EVIndex)); if (!EV) return; - APFloat EVAPF = EV->getValueAPF(); - if (EVAPF.isNegative()) return; - - // Find corresponding integer exit value. uint64_t intEV = Type::Int32Ty->getPrimitiveSizeInBits(); - bool isExact = false; - if (EVAPF.convertToInteger(&intEV, 32, false, APFloat::rmTowardZero, &isExact) - != APFloat::opOK) + if (!convertToInt(EV->getValueAPF(), &intEV)) return; - if (!isExact) return; // Find new predicate for integer comparison. CmpInst::Predicate NewPred = CmpInst::BAD_ICMP_PREDICATE; @@ -826,11 +835,12 @@ // Insert new integer induction variable. PHINode *NewPHI = PHINode::Create(Type::Int32Ty, PH->getName()+".int", PH); - NewPHI->addIncoming(Constant::getNullValue(NewPHI->getType()), + NewPHI->addIncoming(ConstantInt::get(Type::Int32Ty, newInitValue), PH->getIncomingBlock(IncomingEdge)); Value *NewAdd = BinaryOperator::CreateAdd(NewPHI, - ConstantInt::get(Type::Int32Ty, 1), + ConstantInt::get(Type::Int32Ty, + newIncrValue), Incr->getName()+".int", Incr); NewPHI->addIncoming(NewAdd, PH->getIncomingBlock(BackEdge)); @@ -849,9 +859,16 @@ DeadInsts.insert(Incr); // Replace floating induction variable. - UIToFPInst *Conv = new UIToFPInst(NewPHI, PH->getType(), "indvar.conv", - PH->getParent()->getFirstNonPHI()); - PH->replaceAllUsesWith(Conv); + if (EV->getValueAPF().isNegative() + || InitValue->getValueAPF().isNegative()) { + SIToFPInst *Conv = new SIToFPInst(NewPHI, PH->getType(), "indvar.conv", + PH->getParent()->getFirstNonPHI()); + PH->replaceAllUsesWith(Conv); + } else { + UIToFPInst *Conv = new UIToFPInst(NewPHI, PH->getType(), "indvar.conv", + PH->getParent()->getFirstNonPHI()); + PH->replaceAllUsesWith(Conv); + } DeadInsts.insert(PH); } Modified: llvm/trunk/test/Transforms/IndVarsSimplify/2008-11-03-Floating.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/IndVarsSimplify/2008-11-03-Floating.ll?rev=59471&r1=59470&r2=59471&view=diff ============================================================================== --- llvm/trunk/test/Transforms/IndVarsSimplify/2008-11-03-Floating.ll (original) +++ llvm/trunk/test/Transforms/IndVarsSimplify/2008-11-03-Floating.ll Mon Nov 17 17:27:13 2008 @@ -1,4 +1,4 @@ -; RUN: llvm-as < %s | opt -indvars | llvm-dis | grep icmp | count 1 +; RUN: llvm-as < %s | opt -indvars | llvm-dis | grep icmp | count 4 define void @bar() nounwind { entry: br label %bb @@ -15,3 +15,51 @@ } declare i32 @foo(double) + +define void @bar2() nounwind { +entry: + br label %bb + +bb: ; preds = %bb, %entry + %x.0.reg2mem.0 = phi double [ -10.000000e+00, %entry ], [ %1, %bb ] ; [#uses=2] + %0 = tail call i32 @foo(double %x.0.reg2mem.0) nounwind ; [#uses=0] + %1 = add double %x.0.reg2mem.0, 2.000000e+00 ; [#uses=2] + %2 = fcmp olt double %1, -1.000000e+00 ; [#uses=1] + br i1 %2, label %bb, label %return + +return: ; preds = %bb + ret void +} + + +define void @bar3() nounwind { +entry: + br label %bb + +bb: ; preds = %bb, %entry + %x.0.reg2mem.0 = phi double [ 0.000000e+00, %entry ], [ %1, %bb ] ; [#uses=2] + %0 = tail call i32 @foo(double %x.0.reg2mem.0) nounwind ; [#uses=0] + %1 = add double %x.0.reg2mem.0, 1.000000e+00 ; [#uses=2] + %2 = fcmp olt double %1, -1.000000e+00 ; [#uses=1] + br i1 %2, label %bb, label %return + +return: ; preds = %bb + ret void +} + +define void @bar4() nounwind { +entry: + br label %bb + +bb: ; preds = %bb, %entry + %x.0.reg2mem.0 = phi double [ 40.000000e+00, %entry ], [ %1, %bb ] ; [#uses=2] + %0 = tail call i32 @foo(double %x.0.reg2mem.0) nounwind ; [#uses=0] + %1 = add double %x.0.reg2mem.0, -1.000000e+00 ; [#uses=2] + %2 = fcmp olt double %1, 1.000000e+00 ; [#uses=1] + br i1 %2, label %bb, label %return + +return: ; preds = %bb + ret void +} + + From stuart at apple.com Mon Nov 17 18:08:19 2008 From: stuart at apple.com (Stuart Hastings) Date: Mon, 17 Nov 2008 16:08:19 -0800 Subject: [llvm-commits] discouraging use of x86_64 R12 and R13 In-Reply-To: References: Message-ID: <7D8710B0-A32E-4372-88F9-594568443D5D@apple.com> A trivial patch for a mild (and unproven) performance improvement. () The x86_64 R12 and R13 register encodings are related to the RBP and RSP encodings, and thus require slightly longer instructions than the other R8..R15 registers. Specifically, just like [RBP], the X86_64 cannot encode [R12] directly; this is expressed as [R12+0]. In like manner, [R13] resembles [RSP], and requires an SIB byte. Since R14 and R15 don't have these drawbacks, here is a patch for LLVM to prefer them over R12 & R13. By "prefer," we really mean "allocate R14 and R15 first." This has passed DejaGNU with no regressions, and some experimentation with a hacky testcase suggests that it works, at least for 32-bit integers. I haven't tested all the permutations (bytes, shorts, long longs). If this is acceptable, would someone kindly commit this? stuart Index: llvm.regorder/lib/Target/X86/X86RegisterInfo.td =================================================================== --- llvm.regorder/lib/Target/X86/X86RegisterInfo.td (revision 59450) +++ llvm.regorder/lib/Target/X86/X86RegisterInfo.td (working copy) @@ -181,9 +181,9 @@ def x86_subreg_16bit : PatLeaf<(i32 2) def x86_subreg_32bit : PatLeaf<(i32 3)>; def : SubRegSet<1, [AX, CX, DX, BX, SP, BP, SI, DI, - R8W, R9W, R10W, R11W, R12W, R13W, R14W, R15W], + R8W, R9W, R10W, R11W, R14W, R15W, R12W, R13W], [AL, CL, DL, BL, SPL, BPL, SIL, DIL, - R8B, R9B, R10B, R11B, R12B, R13B, R14B, R15B]>; + R8B, R9B, R10B, R11B, R14B, R15B, R12B, R13B]>; // It's unclear if this subreg set is safe, given that not all registers // in the class have an 'H' subreg. @@ -191,30 +191,30 @@ def : SubRegSet<1, [AX, CX, DX, BX, SP, // [AH, CH, DH, BH]>; def : SubRegSet<1, [EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI, - R8D, R9D, R10D, R11D, R12D, R13D, R14D, R15D], + R8D, R9D, R10D, R11D, R14D, R15D, R12D, R13D], [AL, CL, DL, BL, SPL, BPL, SIL, DIL, - R8B, R9B, R10B, R11B, R12B, R13B, R14B, R15B]>; + R8B, R9B, R10B, R11B, R14B, R15B, R12B, R13B]>; def : SubRegSet<2, [EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI, - R8D, R9D, R10D, R11D, R12D, R13D, R14D, R15D], + R8D, R9D, R10D, R11D, R14D, R15D, R12D, R13D], [AX, CX, DX, BX, SP, BP, SI, DI, - R8W, R9W, R10W, R11W, R12W, R13W, R14W, R15W]>; + R8W, R9W, R10W, R11W, R14W, R15W, R12W, R13W]>; def : SubRegSet<1, [RAX, RCX, RDX, RBX, RSP, RBP, RSI, RDI, - R8, R9, R10, R11, R12, R13, R14, R15], + R8, R9, R10, R11, R14, R15, R12, R13], [AL, CL, DL, BL, SPL, BPL, SIL, DIL, - R8B, R9B, R10B, R11B, R12B, R13B, R14B, R15B]>; + R8B, R9B, R10B, R11B, R14B, R15B, R12B, R13B]>; def : SubRegSet<2, [RAX, RCX, RDX, RBX, RSP, RBP, RSI, RDI, - R8, R9, R10, R11, R12, R13, R14, R15], + R8, R9, R10, R11, R14, R15, R12, R13], [AX, CX, DX, BX, SP, BP, SI, DI, - R8W, R9W, R10W, R11W, R12W, R13W, R14W, R15W]>; + R8W, R9W, R10W, R11W, R14W, R15W, R12W, R13W]>; def : SubRegSet<3, [RAX, RCX, RDX, RBX, RSP, RBP, RSI, RDI, - R8, R9, R10, R11, R12, R13, R14, R15], + R8, R9, R10, R11, R14, R15, R12, R13], [EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI, - R8D, R9D, R10D, R11D, R12D, R13D, R14D, R15D]>; + R8D, R9D, R10D, R11D, R14D, R15D, R12D, R13D]>; // = = =---------------------------------------------------------------------- ===// // Register Class Definitions... now that we have all of the pieces, define the @@ -229,7 +229,7 @@ def : SubRegSet<3, [RAX, RCX, RDX, RBX, // FIXME: Allow AH, CH, DH, BH in 64-mode for non-REX instructions, def GR8 : RegisterClass<"X86", [i8], 8, [AL, CL, DL, BL, AH, CH, DH, BH, SIL, DIL, BPL, SPL, - R8B, R9B, R10B, R11B, R12B, R13B, R14B, R15B]> { + R8B, R9B, R10B, R11B, R14B, R15B, R12B, R13B]> { let MethodProtos = [{ iterator allocation_order_begin(const MachineFunction &MF) const; iterator allocation_order_end(const MachineFunction &MF) const; @@ -240,12 +240,12 @@ def GR8 : RegisterClass<"X86", [i8], 8, static const unsigned X86_GR8_AO_64_fp[] = {X86::AL, X86::CL, X86::DL, X86::SIL, X86::DIL, X86::R8B, X86::R9B, X86::R10B, X86::R11B, - X86::BL, X86::R12B, X86::R13B, X86::R14B, X86::R15B}; + X86::BL, X86::R14B, X86::R15B, X86::R12B, X86::R13B}; // If not, just don't allocate SPL. static const unsigned X86_GR8_AO_64[] = {X86::AL, X86::CL, X86::DL, X86::SIL, X86::DIL, X86::R8B, X86::R9B, X86::R10B, X86::R11B, - X86::BL, X86::R12B, X86::R13B, X86::R14B, X86::R15B, X86::BPL}; + X86::BL, X86::R14B, X86::R15B, X86::R12B, X86::R13B, X86::BPL}; // In 32-mode, none of the 8-bit registers aliases EBP or ESP. static const unsigned X86_GR8_AO_32[] = {X86::AL, X86::CL, X86::DL, X86::AH, X86::CH, X86::DH, X86::BL, X86::BH}; @@ -281,7 +281,7 @@ def GR8 : RegisterClass<"X86", [i8], 8, def GR16 : RegisterClass<"X86", [i16], 16, [AX, CX, DX, SI, DI, BX, BP, SP, - R8W, R9W, R10W, R11W, R12W, R13W, R14W, R15W]> { + R8W, R9W, R10W, R11W, R14W, R15W, R12W, R13W]> { let SubRegClassList = [GR8]; let MethodProtos = [{ iterator allocation_order_begin(const MachineFunction &MF) const; @@ -293,14 +293,14 @@ def GR16 : RegisterClass<"X86", [i16], 1 static const unsigned X86_GR16_AO_64_fp[] = {X86::AX, X86::CX, X86::DX, X86::SI, X86::DI, X86::R8W, X86::R9W, X86::R10W, X86::R11W, - X86::BX, X86::R12W, X86::R13W, X86::R14W, X86::R15W}; + X86::BX, X86::R14W, X86::R15W, X86::R12W, X86::R13W}; static const unsigned X86_GR16_AO_32_fp[] = {X86::AX, X86::CX, X86::DX, X86::SI, X86::DI, X86::BX}; // If not, just don't allocate SPL. static const unsigned X86_GR16_AO_64[] = {X86::AX, X86::CX, X86::DX, X86::SI, X86::DI, X86::R8W, X86::R9W, X86::R10W, X86::R11W, - X86::BX, X86::R12W, X86::R13W, X86::R14W, X86::R15W, X86::BP}; + X86::BX, X86::R14W, X86::R15W, X86::R12W, X86::R13W, X86::BP}; static const unsigned X86_GR16_AO_32[] = {X86::AX, X86::CX, X86::DX, X86::SI, X86::DI, X86::BX, X86::BP}; @@ -345,7 +345,7 @@ def GR16 : RegisterClass<"X86", [i16], 1 def GR32 : RegisterClass<"X86", [i32], 32, [EAX, ECX, EDX, ESI, EDI, EBX, EBP, ESP, - R8D, R9D, R10D, R11D, R12D, R13D, R14D, R15D]> { + R8D, R9D, R10D, R11D, R14D, R15D, R12D, R13D]> { let SubRegClassList = [GR8, GR16]; let MethodProtos = [{ iterator allocation_order_begin(const MachineFunction &MF) const; @@ -357,14 +357,14 @@ def GR32 : RegisterClass<"X86", [i32], 3 static const unsigned X86_GR32_AO_64_fp[] = {X86::EAX, X86::ECX, X86::EDX, X86::ESI, X86::EDI, X86::R8D, X86::R9D, X86::R10D, X86::R11D, - X86::EBX, X86::R12D, X86::R13D, X86::R14D, X86::R15D}; + X86::EBX, X86::R14D, X86::R15D, X86::R12D, X86::R13D}; static const unsigned X86_GR32_AO_32_fp[] = {X86::EAX, X86::ECX, X86::EDX, X86::ESI, X86::EDI, X86::EBX}; // If not, just don't allocate SPL. static const unsigned X86_GR32_AO_64[] = {X86::EAX, X86::ECX, X86::EDX, X86::ESI, X86::EDI, X86::R8D, X86::R9D, X86::R10D, X86::R11D, - X86::EBX, X86::R12D, X86::R13D, X86::R14D, X86::R15D, X86::EBP}; + X86::EBX, X86::R14D, X86::R15D, X86::R12D, X86::R13D, X86::EBP}; static const unsigned X86_GR32_AO_32[] = {X86::EAX, X86::ECX, X86::EDX, X86::ESI, X86::EDI, X86::EBX, X86::EBP}; @@ -409,7 +409,7 @@ def GR32 : RegisterClass<"X86", [i32], 3 def GR64 : RegisterClass<"X86", [i64], 64, [RAX, RCX, RDX, RSI, RDI, R8, R9, R10, R11, - RBX, R12, R13, R14, R15, RBP, RSP]> { + RBX, R14, R15, R12, R13, RBP, RSP]> { let SubRegClassList = [GR8, GR16, GR32]; let MethodProtos = [{ iterator allocation_order_end(const MachineFunction &MF) const; From evan.cheng at apple.com Mon Nov 17 18:29:33 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 18 Nov 2008 00:29:33 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r59473 - /llvm-gcc-4.2/trunk/gcc/Makefile.in Message-ID: <200811180029.mAI0TX5g025736@zion.cs.uiuc.edu> Author: evancheng Date: Mon Nov 17 18:29:32 2008 New Revision: 59473 URL: http://llvm.org/viewvc/llvm-project?rev=59473&view=rev Log: Fix misplaced '$' in ifneq condition. Modified: llvm-gcc-4.2/trunk/gcc/Makefile.in Modified: llvm-gcc-4.2/trunk/gcc/Makefile.in URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/Makefile.in?rev=59473&r1=59472&r2=59473&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/Makefile.in (original) +++ llvm-gcc-4.2/trunk/gcc/Makefile.in Mon Nov 17 18:29:32 2008 @@ -937,7 +937,7 @@ ifneq ($(LLVMOBJDIR),) # If LLVM is built srcdir != objdir, include the objdir headers for configured # headers, like DataTypes.h. -ifneq (($LLVMOBJDIR),$(LLVMSRCDIR)) +ifneq ($(LLVMOBJDIR),$(LLVMSRCDIR)) INCLUDES += -I$(LLVMOBJDIR)/include endif From gohman at apple.com Mon Nov 17 18:39:00 2008 From: gohman at apple.com (Dan Gohman) Date: Tue, 18 Nov 2008 00:39:00 -0000 Subject: [llvm-commits] [llvm] r59475 - in /llvm/trunk/lib/CodeGen/SelectionDAG: ScheduleDAGFast.cpp ScheduleDAGList.cpp ScheduleDAGRRList.cpp Message-ID: <200811180039.mAI0d0iD026084@zion.cs.uiuc.edu> Author: djg Date: Mon Nov 17 18:38:59 2008 New Revision: 59475 URL: http://llvm.org/viewvc/llvm-project?rev=59475&view=rev Log: Avoid using a loop in ReleasePred and ReleaseSucc methods to compute the new CycleBound value. Instead, just update CycleBound on each call. Also, make ReleasePred and ReleaseSucc methods more consistent accross the various schedulers. This also happens to make ScheduleDAGRRList's CycleBound computation somewhat more interesting, though it still doesn't have any noticeable effect, because no current targets that use the register-pressure reduction scheduler provide pipeline models. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp?rev=59475&r1=59474&r2=59475&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp Mon Nov 17 18:38:59 2008 @@ -88,7 +88,7 @@ bool RemovePred(SUnit *M, SUnit *N, bool isCtrl, bool isSpecial); private: - void ReleasePred(SUnit*, bool, unsigned); + void ReleasePred(SUnit *SU, SUnit *PredSU, bool isChain); void ScheduleNodeBottomUp(SUnit*, unsigned); SUnit *CopyAndMoveSuccessors(SUnit*); void InsertCCCopiesAndMoveSuccs(SUnit*, unsigned, @@ -137,13 +137,12 @@ /// ReleasePred - Decrement the NumSuccsLeft count of a predecessor. Add it to /// the AvailableQueue if the count reaches zero. Also update its cycle bound. -void ScheduleDAGFast::ReleasePred(SUnit *PredSU, bool isChain, - unsigned CurCycle) { +void ScheduleDAGFast::ReleasePred(SUnit *SU, SUnit *PredSU, bool isChain) { --PredSU->NumSuccsLeft; #ifndef NDEBUG if (PredSU->NumSuccsLeft < 0) { - cerr << "*** List scheduling failed! ***\n"; + cerr << "*** Scheduling failed! ***\n"; PredSU->dump(DAG); cerr << " has been released too many times!\n"; assert(0); @@ -167,7 +166,7 @@ // Bottom up: release predecessors for (SUnit::pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); I != E; ++I) { - ReleasePred(I->Dep, I->isCtrl, CurCycle); + ReleasePred(SU, I->Dep, I->isCtrl); if (I->Cost < 0) { // This is a physical register dependency and it's impossible or // expensive to copy the register. Make sure nothing that can Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp?rev=59475&r1=59474&r2=59475&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Mon Nov 17 18:38:59 2008 @@ -78,7 +78,7 @@ void Schedule(); private: - void ReleaseSucc(SUnit *SuccSU, bool isChain); + void ReleaseSucc(SUnit *SU, SUnit *SuccSU, bool isChain); void ScheduleNodeTopDown(SUnit *SU, unsigned CurCycle); void ListScheduleTopDown(); }; @@ -106,35 +106,33 @@ //===----------------------------------------------------------------------===// /// ReleaseSucc - Decrement the NumPredsLeft count of a successor. Add it to -/// the PendingQueue if the count reaches zero. -void ScheduleDAGList::ReleaseSucc(SUnit *SuccSU, bool isChain) { - SuccSU->NumPredsLeft--; +/// the PendingQueue if the count reaches zero. Also update its cycle bound. +void ScheduleDAGList::ReleaseSucc(SUnit *SU, SUnit *SuccSU, bool isChain) { + --SuccSU->NumPredsLeft; - assert(SuccSU->NumPredsLeft >= 0 && - "List scheduling internal error"); +#ifndef NDEBUG + if (SuccSU->NumPredsLeft < 0) { + cerr << "*** Scheduling failed! ***\n"; + SuccSU->dump(DAG); + cerr << " has been released too many times!\n"; + assert(0); + } +#endif + + // Compute how many cycles it will be before this actually becomes + // available. This is the max of the start time of all predecessors plus + // their latencies. + // If this is a token edge, we don't need to wait for the latency of the + // preceeding instruction (e.g. a long-latency load) unless there is also + // some other data dependence. + unsigned PredDoneCycle = SU->Cycle; + if (!isChain) + PredDoneCycle += SU->Latency; + else if (SU->Latency) + PredDoneCycle += 1; + SuccSU->CycleBound = std::max(SuccSU->CycleBound, PredDoneCycle); if (SuccSU->NumPredsLeft == 0) { - // Compute how many cycles it will be before this actually becomes - // available. This is the max of the start time of all predecessors plus - // their latencies. - unsigned AvailableCycle = 0; - for (SUnit::pred_iterator I = SuccSU->Preds.begin(), - E = SuccSU->Preds.end(); I != E; ++I) { - // If this is a token edge, we don't need to wait for the latency of the - // preceeding instruction (e.g. a long-latency load) unless there is also - // some other data dependence. - SUnit &Pred = *I->Dep; - unsigned PredDoneCycle = Pred.Cycle; - if (!I->isCtrl) - PredDoneCycle += Pred.Latency; - else if (Pred.Latency) - PredDoneCycle += 1; - - AvailableCycle = std::max(AvailableCycle, PredDoneCycle); - } - - assert(SuccSU->CycleBound == 0 && "CycleBound already assigned!"); - SuccSU->CycleBound = AvailableCycle; PendingQueue.push_back(SuccSU); } } @@ -152,7 +150,7 @@ // Top down: release successors. for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); I != E; ++I) - ReleaseSucc(I->Dep, I->isCtrl); + ReleaseSucc(SU, I->Dep, I->isCtrl); SU->isScheduled = true; AvailableQueue->ScheduledNode(SU); Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp?rev=59475&r1=59474&r2=59475&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Mon Nov 17 18:38:59 2008 @@ -106,8 +106,8 @@ bool RemovePred(SUnit *M, SUnit *N, bool isCtrl, bool isSpecial); private: - void ReleasePred(SUnit*, bool, unsigned); - void ReleaseSucc(SUnit*, bool isChain, unsigned); + void ReleasePred(SUnit *SU, SUnit *PredSU, bool isChain); + void ReleaseSucc(SUnit *SU, SUnit *SuccSU, bool isChain); void CapturePred(SUnit*, SUnit*, bool); void ScheduleNodeBottomUp(SUnit*, unsigned); void ScheduleNodeTopDown(SUnit*, unsigned); @@ -265,25 +265,31 @@ /// ReleasePred - Decrement the NumSuccsLeft count of a predecessor. Add it to /// the AvailableQueue if the count reaches zero. Also update its cycle bound. -void ScheduleDAGRRList::ReleasePred(SUnit *PredSU, bool isChain, - unsigned CurCycle) { - // FIXME: the distance between two nodes is not always == the predecessor's - // latency. For example, the reader can very well read the register written - // by the predecessor later than the issue cycle. It also depends on the - // interrupt model (drain vs. freeze). - PredSU->CycleBound = std::max(PredSU->CycleBound, CurCycle + PredSU->Latency); - +void ScheduleDAGRRList::ReleasePred(SUnit *SU, SUnit *PredSU, bool isChain) { --PredSU->NumSuccsLeft; #ifndef NDEBUG if (PredSU->NumSuccsLeft < 0) { - cerr << "*** List scheduling failed! ***\n"; + cerr << "*** Scheduling failed! ***\n"; PredSU->dump(DAG); cerr << " has been released too many times!\n"; assert(0); } #endif + // Compute how many cycles it will be before this actually becomes + // available. This is the max of the start time of all predecessors plus + // their latencies. + // If this is a token edge, we don't need to wait for the latency of the + // preceeding instruction (e.g. a long-latency load) unless there is also + // some other data dependence. + unsigned PredDoneCycle = SU->Cycle; + if (!isChain) + PredDoneCycle += PredSU->Latency; + else if (SU->Latency) + PredDoneCycle += 1; + PredSU->CycleBound = std::max(PredSU->CycleBound, PredDoneCycle); + if (PredSU->NumSuccsLeft == 0) { PredSU->isAvailable = true; AvailableQueue->push(PredSU); @@ -303,7 +309,7 @@ // Bottom up: release predecessors for (SUnit::pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); I != E; ++I) { - ReleasePred(I->Dep, I->isCtrl, CurCycle); + ReleasePred(SU, I->Dep, I->isCtrl); if (I->Cost < 0) { // This is a physical register dependency and it's impossible or // expensive to copy the register. Make sure nothing that can @@ -1105,25 +1111,31 @@ /// ReleaseSucc - Decrement the NumPredsLeft count of a successor. Add it to /// the AvailableQueue if the count reaches zero. Also update its cycle bound. -void ScheduleDAGRRList::ReleaseSucc(SUnit *SuccSU, bool isChain, - unsigned CurCycle) { - // FIXME: the distance between two nodes is not always == the predecessor's - // latency. For example, the reader can very well read the register written - // by the predecessor later than the issue cycle. It also depends on the - // interrupt model (drain vs. freeze). - SuccSU->CycleBound = std::max(SuccSU->CycleBound, CurCycle + SuccSU->Latency); - +void ScheduleDAGRRList::ReleaseSucc(SUnit *SU, SUnit *SuccSU, bool isChain) { --SuccSU->NumPredsLeft; #ifndef NDEBUG if (SuccSU->NumPredsLeft < 0) { - cerr << "*** List scheduling failed! ***\n"; + cerr << "*** Scheduling failed! ***\n"; SuccSU->dump(DAG); cerr << " has been released too many times!\n"; assert(0); } #endif + // Compute how many cycles it will be before this actually becomes + // available. This is the max of the start time of all predecessors plus + // their latencies. + // If this is a token edge, we don't need to wait for the latency of the + // preceeding instruction (e.g. a long-latency load) unless there is also + // some other data dependence. + unsigned PredDoneCycle = SU->Cycle; + if (!isChain) + PredDoneCycle += SU->Latency; + else if (SU->Latency) + PredDoneCycle += 1; + SuccSU->CycleBound = std::max(SuccSU->CycleBound, PredDoneCycle); + if (SuccSU->NumPredsLeft == 0) { SuccSU->isAvailable = true; AvailableQueue->push(SuccSU); @@ -1144,7 +1156,7 @@ // Top down: release successors for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); I != E; ++I) - ReleaseSucc(I->Dep, I->isCtrl, CurCycle); + ReleaseSucc(SU, I->Dep, I->isCtrl); SU->isScheduled = true; AvailableQueue->ScheduledNode(SU); From dpatel at apple.com Mon Nov 17 18:40:03 2008 From: dpatel at apple.com (Devang Patel) Date: Tue, 18 Nov 2008 00:40:03 -0000 Subject: [llvm-commits] [llvm] r59476 - in /llvm/trunk: lib/Transforms/Scalar/IndVarSimplify.cpp test/Transforms/IndVarsSimplify/2008-11-17-Floating.ll Message-ID: <200811180040.mAI0e32a026133@zion.cs.uiuc.edu> Author: dpatel Date: Mon Nov 17 18:40:02 2008 New Revision: 59476 URL: http://llvm.org/viewvc/llvm-project?rev=59476&view=rev Log: Give SIToFPInst preference over UIToFPInst because it is faster on platforms that are widely used. Added: llvm/trunk/test/Transforms/IndVarsSimplify/2008-11-17-Floating.ll Modified: llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp Modified: llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp?rev=59476&r1=59475&r2=59476&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp Mon Nov 17 18:40:02 2008 @@ -722,6 +722,23 @@ Incr->eraseFromParent(); } +/// Return true if it is OK to use SIToFPInst for an inducation variable +/// with given inital and exit values. +static bool useSIToFPInst(ConstantFP &InitV, ConstantFP &ExitV, + uint64_t intIV, uint64_t intEV) { + + if (InitV.getValueAPF().isNegative() || ExitV.getValueAPF().isNegative()) + return true; + + // If the iteration range can be handled by SIToFPInst then use it. + APInt Max = APInt::getSignedMaxValue(32); + if (Max.getZExtValue() > abs(intEV - intIV)) + return true; + + return false; +} + +/// convertToInt - Convert APF to an integer, if possible. static bool convertToInt(const APFloat &APF, uint64_t *intVal) { bool isExact = false; @@ -858,9 +875,9 @@ Incr->replaceAllUsesWith(UndefValue::get(Incr->getType())); DeadInsts.insert(Incr); - // Replace floating induction variable. - if (EV->getValueAPF().isNegative() - || InitValue->getValueAPF().isNegative()) { + // Replace floating induction variable. Give SIToFPInst preference over + // UIToFPInst because it is faster on platforms that are widely used. + if (useSIToFPInst(*InitValue, *EV, newInitValue, intEV)) { SIToFPInst *Conv = new SIToFPInst(NewPHI, PH->getType(), "indvar.conv", PH->getParent()->getFirstNonPHI()); PH->replaceAllUsesWith(Conv); Added: llvm/trunk/test/Transforms/IndVarsSimplify/2008-11-17-Floating.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/IndVarsSimplify/2008-11-17-Floating.ll?rev=59476&view=auto ============================================================================== --- llvm/trunk/test/Transforms/IndVarsSimplify/2008-11-17-Floating.ll (added) +++ llvm/trunk/test/Transforms/IndVarsSimplify/2008-11-17-Floating.ll Mon Nov 17 18:40:02 2008 @@ -0,0 +1,35 @@ +; RUN: llvm-as < %s | opt -indvars | llvm-dis | grep icmp | count 2 +; RUN: llvm-as < %s | opt -indvars | llvm-dis | grep sitofp | count 1 +; RUN: llvm-as < %s | opt -indvars | llvm-dis | grep uitofp | count 1 + +define void @bar() nounwind { +entry: + br label %bb + +bb: ; preds = %bb, %entry + %x.0.reg2mem.0 = phi double [ 0.000000e+00, %entry ], [ %1, %bb ] ; [#uses=2] + %0 = tail call i32 @foo(double %x.0.reg2mem.0) nounwind ; [#uses=0] + %1 = add double %x.0.reg2mem.0, 1.0e+0 ; [#uses=2] + %2 = fcmp olt double %1, 2147483646.0e+0 ; [#uses=1] + br i1 %2, label %bb, label %return + +return: ; preds = %bb + ret void +} + +define void @bar1() nounwind { +entry: + br label %bb + +bb: ; preds = %bb, %entry + %x.0.reg2mem.0 = phi double [ 0.000000e+00, %entry ], [ %1, %bb ] ; [#uses=2] + %0 = tail call i32 @foo(double %x.0.reg2mem.0) nounwind ; [#uses=0] + %1 = add double %x.0.reg2mem.0, 1.0e+0 ; [#uses=2] + %2 = fcmp olt double %1, 2147483647.0e+0 ; [#uses=1] + br i1 %2, label %bb, label %return + +return: ; preds = %bb + ret void +} + +declare i32 @foo(double) From dpatel at apple.com Mon Nov 17 18:42:33 2008 From: dpatel at apple.com (Devang Patel) Date: Mon, 17 Nov 2008 16:42:33 -0800 Subject: [llvm-commits] [llvm] r59011 - in /llvm/trunk: include/llvm/Transforms/Utils/DbgInfoUtils.h lib/Transforms/Utils/DbgInfoUtils.cpp In-Reply-To: References: <200811110053.mAB0r3Iq013378@zion.cs.uiuc.edu> <54A3C2D3-D92D-496A-BAEA-E19E6F7B55D5@apple.com> <9F356AF5-E16F-477F-BE78-886427813F42@apple.com> <626078D7-1C1D-483F-819F-A87CA0FEB928@apple.com> Message-ID: <7FDF3EEC-DDB8-4753-AB00-B915BC5C187E@apple.com> On Nov 17, 2008, at 11:37 AM, Chris Lattner wrote: > On Nov 17, 2008, at 11:29 AM, Devang Patel wrote: >>>>> Instead of making this a "minipass" which is called by other >>>>> passes, why not just make instcombine (and only instcombine) do >>>>> this? Instcombine runs many times in a typical compilation, and >>>>> it can do this very cheaply (cost proportional to the number of >>>>> debug intrinsics, instead of scanning entire functions even when >>>>> there are none). >>>> >>>> However we want >>>> $ opt -adce foo.bc -o foo.optimzed.bc >>>> to preserve valid debug info. >>> >>> How wouldn't it? >> >> Well, this routine will be used by adce and any other pass that >> removes dead instructions. If we just make instcombine responsible >> for this cleanup then we are requiring that instcombine is always >> scheduled after such passes. Is that OK ? > > One of us is missing something here. The change that this makes is > an *optimization*, it isn't required for correctness, right? If so, > instcombine should be the only thing that does it. ADCE doesn't do > constant folding or many other possible cleanups, why would it do > this one? > > If this is required for correctness, then something else is > seriously wrong. series of stoppoint()s with different line number values can confuse debuggers. I understand your point. >>>>>> >>>>>> + // If a llvm.dbg.stoppoint is placed just before an >>>>>> unconditional >>>>>> + // branch then remove the llvm.dbg.stoppoint intrinsic. >>>>>> + else if (BranchInst *UC = dyn_cast(Next)) { >>>>>> + if (UC->isUnconditional() >>>>> >>>>> Why? This doesn't seem right. >>>> >>>> If it is a unconditional branch then sooner or later the cfg will >>>> be simplified and this may get in a way for a pass doing simple >>>> clean. >>> >>> I don't understand. You're saying that the intrinsic will prevent >>> simplifycfg from doing a transformation? That seems like a >>> problem that should be fixed in the simplifycfg pass. >> >> Yes, simplifycfg pass should be fixed (if that is the case, I need >> to verify it thoroughly). But many passes do their own little >> cleanups. On the other side, unconditional branches are usually >> removed by the optimizer, which means associated debug info is also >> gone. > > I can easily make LLVM IR that requires the stoppoint for valid > debug info. Something silly like this: > > stoppoint() > br next > > next: > call bar() > stoppoint() > > You need the stoppoint before the branch to be able to stop on the > call. Zapping these unconditionally is not acceptable. ok. - Devang From dpatel at apple.com Mon Nov 17 18:45:43 2008 From: dpatel at apple.com (Devang Patel) Date: Mon, 17 Nov 2008 16:45:43 -0800 Subject: [llvm-commits] [llvm] r59208 - /llvm/trunk/lib/Transforms/IPO/StripSymbols.cpp In-Reply-To: <0EB49BD7-8E9F-4675-97FD-7583F45A8FAB@apple.com> References: <200811130128.mAD1SfCx025350@zion.cs.uiuc.edu> <0EB49BD7-8E9F-4675-97FD-7583F45A8FAB@apple.com> Message-ID: On Nov 15, 2008, at 10:36 PM, Chris Lattner wrote: > On Nov 12, 2008, at 5:28 PM, Devang Patel wrote: >> URL: http://llvm.org/viewvc/llvm-project?rev=59208&view=rev >> Log: >> Really remove all debug information. > > Ok. > >> @@ -213,8 +220,30 @@ >> Declare->eraseFromParent(); >> } >> >> + // Delete all dbg variables. >> + const Type *DbgVTy = M.getTypeByName("llvm.dbg.variable.type"); >> + const Type *DbgGVTy = >> M.getTypeByName("llvm.dbg.global_variable.type"); > > This isn't safe. You can depend on the names of non-internal globals, > but not on the names of types. Type names can be stripped out. This is true for values also. We can remove debug info. if names are stripped out. > Also, > we may add new type names for debug info in the future. > >> + if (DbgVTy || DbgGVTy) >> + for (Module::global_iterator I = M.global_begin(), E = >> M.global_end(); >> + I != E; ++I) >> + if (GlobalVariable *GV = dyn_cast(I)) >> + if (GV->hasName() && GV->use_empty() >> + && !strncmp(GV->getNameStart(), "llvm.dbg", 8) >> + && (GV->getType()->getElementType() == DbgVTy >> + || GV->getType()->getElementType() == DbgGVTy)) >> + DeadGlobals.push_back(GV); >> + > > I don't think that matching on the names is really a sound way to go. > How about just looping over all the globals, removing dead globals in > the llvm.metadata section? If it start remove dead globals then it becomes difficult to compare "- strip-debug -std-compile-opts" output with "-std-compile-opts -strip- debug" output. - Devang From dpatel at apple.com Mon Nov 17 18:47:17 2008 From: dpatel at apple.com (Devang Patel) Date: Mon, 17 Nov 2008 16:47:17 -0800 Subject: [llvm-commits] [test-suite] r59329 - /test-suite/trunk/TEST.dbgopt.Makefile In-Reply-To: <9D471D17-1DEC-4878-89C5-A090FC57D1F4@apple.com> References: <200811142256.mAEMuOxZ016830@zion.cs.uiuc.edu> <9D471D17-1DEC-4878-89C5-A090FC57D1F4@apple.com> Message-ID: <139032D5-2AFC-4A18-B2D0-11BA2467CA7F@apple.com> On Nov 15, 2008, at 7:28 PM, Chris Lattner wrote: > > On Nov 14, 2008, at 2:56 PM, Devang Patel wrote: > >> Author: dpatel >> Date: Fri Nov 14 16:56:24 2008 >> New Revision: 59329 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=59329&view=rev >> Log: >> Test to check optimizer's behavior in presense of debugging >> information. >> >> If input.bc includes llvm.dbg intrinsics and llvm.dbg variables then >> first.bc and second.bc in following should match. Otherwise debugging >> information is influencing the optimizer. >> $ opt input.bc -strip -std-compile-output -o first.bc >> $ opt input.bc -std-compile-output -strip -o second.bc > > Nice! Devang, can you please add a section to docs/ > SourceLevelDebugging.html that describes how to use this and why it's > important? Thanks, Sure. I'll update docs after I do some adjustments in StripSymbols pass and do analysis of test runs. Right now, almost everything fails, which is not useful. - Devang From clattner at apple.com Mon Nov 17 19:00:08 2008 From: clattner at apple.com (Chris Lattner) Date: Mon, 17 Nov 2008 17:00:08 -0800 Subject: [llvm-commits] [llvm] r59208 - /llvm/trunk/lib/Transforms/IPO/StripSymbols.cpp In-Reply-To: References: <200811130128.mAD1SfCx025350@zion.cs.uiuc.edu> <0EB49BD7-8E9F-4675-97FD-7583F45A8FAB@apple.com> Message-ID: <7D48091E-9165-4B3E-9E1E-FEA922D4DC47@apple.com> On Nov 17, 2008, at 4:45 PM, Devang Patel wrote: >> I don't think that matching on the names is really a sound way to go. >> How about just looping over all the globals, removing dead globals in >> the llvm.metadata section? > > > If it start remove dead globals then it becomes difficult to compare > "- > strip-debug -std-compile-opts" output with "-std-compile-opts -strip- > debug" output. What other dead metadata can exist? -Chris From gohman at apple.com Mon Nov 17 19:05:04 2008 From: gohman at apple.com (Dan Gohman) Date: Tue, 18 Nov 2008 01:05:04 -0000 Subject: [llvm-commits] [llvm] r59480 - /llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h Message-ID: <200811180105.mAI154Si026965@zion.cs.uiuc.edu> Author: djg Date: Mon Nov 17 19:05:04 2008 New Revision: 59480 URL: http://llvm.org/viewvc/llvm-project?rev=59480&view=rev Log: There is no InstrStage class. Modified: llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h Modified: llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h?rev=59480&r1=59479&r2=59480&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h (original) +++ llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h Mon Nov 17 19:05:04 2008 @@ -22,7 +22,6 @@ #include "llvm/ADT/SmallSet.h" namespace llvm { - struct InstrStage; struct SUnit; class MachineConstantPool; class MachineFunction; From evan.cheng at apple.com Mon Nov 17 19:09:51 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 18 Nov 2008 01:09:51 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r59481 - /llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp Message-ID: <200811180109.mAI19p4t027108@zion.cs.uiuc.edu> Author: evancheng Date: Mon Nov 17 19:09:51 2008 New Revision: 59481 URL: http://llvm.org/viewvc/llvm-project?rev=59481&view=rev Log: For now, only pass _Complex long double as a first class aggregate in 64-bit. Passing other _Complex values as FCA break ABI compatibility. The issue is sdisel expand a _Complex FCA to two scalars. This means some _Complex values can have half of the value passed in a register and the other half in memory. Modified: llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp Modified: llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp?rev=59481&r1=59480&r2=59481&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp Mon Nov 17 19:09:51 2008 @@ -627,10 +627,13 @@ const StructType *STy = dyn_cast(Ty); if (!STy || STy->isPacked()) return false; - // FIXME: Currently codegen isn't lowering _Complex char / short and _Complex - // int in x86-64 in a way that makes it ABI compatible. + // FIXME: Currently codegen isn't lowering most _Complex types in a way that + // makes it ABI compatible for x86-64. Same for _Complex char and _Complex + // short in 32-bit. const Type *EltTy = STy->getElementType(0); - return !((TARGET_64BIT && EltTy == Type::Int32Ty) || + return !((TARGET_64BIT && (EltTy->isInteger() || + EltTy == Type::FloatTy || + EltTy == Type::DoubleTy)) || EltTy == Type::Int16Ty || EltTy == Type::Int8Ty); } From isanbard at gmail.com Mon Nov 17 19:40:43 2008 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 17 Nov 2008 17:40:43 -0800 Subject: [llvm-commits] [llvm] r59464 - in /llvm/trunk: lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp lib/CodeGen/SelectionDAG/LegalizeTypes.h test/CodeGen/XCore/cos.ll test/CodeGen/XCore/exp.ll test/CodeGen/XCore/exp2.ll test/CodeGen/XCore/fneg.ll test/CodeGen/XCore/log.ll test/CodeGen/XCore/log10.ll test/CodeGen/XCore/log2.ll test/CodeGen/XCore/pow.ll test/CodeGen/XCore/powi.ll test/CodeGen/XCore/sin.ll test/CodeGen/XCore/sqrt.ll In-Reply-To: <200811172052.mAHKqd5M018376@zion.cs.uiuc.edu> References: <200811172052.mAHKqd5M018376@zion.cs.uiuc.edu> Message-ID: Hi Duncan, This is causing a segfault in one of the XCore tests. Please investigate. Running /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvm.src/test/ CodeGen/XCore/dg.exp ... FAIL: /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvm.src/test/ CodeGen/XCore/fneg.ll Failed with signal(SIGABRT) at line 1 while running: llvm-as < /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvm.src/ test/CodeGen/XCore/fneg.ll | llc -march=xcore > fneg.ll.tmp1.s Assertion failed: (VT.isFloatingPoint() && "Cannot create integer FP constant!"), function getConstantFP, file /Volumes/Sandbox/Buildbot/ llvm/full-llvm/build/llvm.src/lib/CodeGen/SelectionDAG/ SelectionDAG.cpp, line 913. 0 llc 0x009210ec _ZN4llvm3sys18RemoveFileOnSignalERKNS0_4PathEPSs + 844 1 libSystem.B.dylib 0x9217809b _sigtramp + 43 ... I will revert this for now. -bw On Nov 17, 2008, at 12:52 PM, Duncan Sands wrote: > Author: baldrick > Date: Mon Nov 17 14:52:38 2008 > New Revision: 59464 > > URL: http://llvm.org/viewvc/llvm-project?rev=59464&view=rev > Log: > Add soft float support for a bunch more operations. Original > patch by Richard Osborne, tweaked and extended by your humble > servant. > > Added: > llvm/trunk/test/CodeGen/XCore/cos.ll > llvm/trunk/test/CodeGen/XCore/exp.ll > llvm/trunk/test/CodeGen/XCore/exp2.ll > llvm/trunk/test/CodeGen/XCore/fneg.ll > llvm/trunk/test/CodeGen/XCore/log.ll > llvm/trunk/test/CodeGen/XCore/log10.ll > llvm/trunk/test/CodeGen/XCore/log2.ll > llvm/trunk/test/CodeGen/XCore/pow.ll > llvm/trunk/test/CodeGen/XCore/powi.ll > llvm/trunk/test/CodeGen/XCore/sin.ll > llvm/trunk/test/CodeGen/XCore/sqrt.ll > Modified: > llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp > llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h > > Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp?rev=59464&r1=59463&r2=59464&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp > (original) > +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp Mon > Nov 17 14:52:38 2008 > @@ -61,14 +61,28 @@ > break; > case ISD::FABS: R = SoftenFloatRes_FABS(N); break; > case ISD::FADD: R = SoftenFloatRes_FADD(N); break; > + case ISD::FCEIL: R = SoftenFloatRes_FCEIL(N); break; > case ISD::FCOPYSIGN: R = SoftenFloatRes_FCOPYSIGN(N); break; > + case ISD::FCOS: R = SoftenFloatRes_FCOS(N); break; > case ISD::FDIV: R = SoftenFloatRes_FDIV(N); break; > + case ISD::FEXP: R = SoftenFloatRes_FEXP(N); break; > + case ISD::FEXP2: R = SoftenFloatRes_FEXP2(N); break; > + case ISD::FFLOOR: R = SoftenFloatRes_FFLOOR(N); break; > + case ISD::FLOG: R = SoftenFloatRes_FLOG(N); break; > + case ISD::FLOG2: R = SoftenFloatRes_FLOG2(N); break; > + case ISD::FLOG10: R = SoftenFloatRes_FLOG10(N); break; > case ISD::FMUL: R = SoftenFloatRes_FMUL(N); break; > + case ISD::FNEARBYINT: R = SoftenFloatRes_FNEARBYINT(N); break; > + case ISD::FNEG: R = SoftenFloatRes_FNEG(N); break; > case ISD::FP_EXTEND: R = SoftenFloatRes_FP_EXTEND(N); break; > case ISD::FP_ROUND: R = SoftenFloatRes_FP_ROUND(N); break; > case ISD::FPOW: R = SoftenFloatRes_FPOW(N); break; > case ISD::FPOWI: R = SoftenFloatRes_FPOWI(N); break; > + case ISD::FRINT: R = SoftenFloatRes_FRINT(N); break; > + case ISD::FSIN: R = SoftenFloatRes_FSIN(N); break; > + case ISD::FSQRT: R = SoftenFloatRes_FSQRT(N); break; > case ISD::FSUB: R = SoftenFloatRes_FSUB(N); break; > + case ISD::FTRUNC: R = SoftenFloatRes_FTRUNC(N); break; > case ISD::LOAD: R = SoftenFloatRes_LOAD(N); break; > case ISD::SELECT: R = SoftenFloatRes_SELECT(N); break; > case ISD::SELECT_CC: R = SoftenFloatRes_SELECT_CC(N); break; > @@ -103,7 +117,7 @@ > unsigned Size = NVT.getSizeInBits(); > > // Mask = ~(1 << (Size-1)) > - SDValue Mask = > DAG.getConstant(APInt::getAllOnesValue(Size).clear(Size-1), > + SDValue Mask = > DAG.getConstant(APInt::getAllOnesValue(Size).clear(Size-1), > NVT); > SDValue Op = GetSoftenedFloat(N->getOperand(0)); > return DAG.getNode(ISD::AND, NVT, Op, Mask); > @@ -121,6 +135,17 @@ > NVT, Ops, 2, false); > } > > +SDValue DAGTypeLegalizer::SoftenFloatRes_FCEIL(SDNode *N) { > + MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); > + SDValue Op = GetSoftenedFloat(N->getOperand(0)); > + return MakeLibCall(GetFPLibCall(N->getValueType(0), > + RTLIB::CEIL_F32, > + RTLIB::CEIL_F64, > + RTLIB::CEIL_F80, > + RTLIB::CEIL_PPCF128), > + NVT, &Op, 1, false); > +} > + > SDValue DAGTypeLegalizer::SoftenFloatRes_FCOPYSIGN(SDNode *N) { > SDValue LHS = GetSoftenedFloat(N->getOperand(0)); > SDValue RHS = BitConvertToInteger(N->getOperand(1)); > @@ -160,6 +185,17 @@ > return DAG.getNode(ISD::OR, LVT, LHS, SignBit); > } > > +SDValue DAGTypeLegalizer::SoftenFloatRes_FCOS(SDNode *N) { > + MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); > + SDValue Op = GetSoftenedFloat(N->getOperand(0)); > + return MakeLibCall(GetFPLibCall(N->getValueType(0), > + RTLIB::COS_F32, > + RTLIB::COS_F64, > + RTLIB::COS_F80, > + RTLIB::COS_PPCF128), > + NVT, &Op, 1, false); > +} > + > SDValue DAGTypeLegalizer::SoftenFloatRes_FDIV(SDNode *N) { > MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); > SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)), > @@ -172,6 +208,72 @@ > NVT, Ops, 2, false); > } > > +SDValue DAGTypeLegalizer::SoftenFloatRes_FEXP(SDNode *N) { > + MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); > + SDValue Op = GetSoftenedFloat(N->getOperand(0)); > + return MakeLibCall(GetFPLibCall(N->getValueType(0), > + RTLIB::EXP_F32, > + RTLIB::EXP_F64, > + RTLIB::EXP_F80, > + RTLIB::EXP_PPCF128), > + NVT, &Op, 1, false); > +} > + > +SDValue DAGTypeLegalizer::SoftenFloatRes_FEXP2(SDNode *N) { > + MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); > + SDValue Op = GetSoftenedFloat(N->getOperand(0)); > + return MakeLibCall(GetFPLibCall(N->getValueType(0), > + RTLIB::EXP2_F32, > + RTLIB::EXP2_F64, > + RTLIB::EXP2_F80, > + RTLIB::EXP2_PPCF128), > + NVT, &Op, 1, false); > +} > + > +SDValue DAGTypeLegalizer::SoftenFloatRes_FFLOOR(SDNode *N) { > + MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); > + SDValue Op = GetSoftenedFloat(N->getOperand(0)); > + return MakeLibCall(GetFPLibCall(N->getValueType(0), > + RTLIB::FLOOR_F32, > + RTLIB::FLOOR_F64, > + RTLIB::FLOOR_F80, > + RTLIB::FLOOR_PPCF128), > + NVT, &Op, 1, false); > +} > + > +SDValue DAGTypeLegalizer::SoftenFloatRes_FLOG(SDNode *N) { > + MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); > + SDValue Op = GetSoftenedFloat(N->getOperand(0)); > + return MakeLibCall(GetFPLibCall(N->getValueType(0), > + RTLIB::LOG_F32, > + RTLIB::LOG_F64, > + RTLIB::LOG_F80, > + RTLIB::LOG_PPCF128), > + NVT, &Op, 1, false); > +} > + > +SDValue DAGTypeLegalizer::SoftenFloatRes_FLOG2(SDNode *N) { > + MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); > + SDValue Op = GetSoftenedFloat(N->getOperand(0)); > + return MakeLibCall(GetFPLibCall(N->getValueType(0), > + RTLIB::LOG2_F32, > + RTLIB::LOG2_F64, > + RTLIB::LOG2_F80, > + RTLIB::LOG2_PPCF128), > + NVT, &Op, 1, false); > +} > + > +SDValue DAGTypeLegalizer::SoftenFloatRes_FLOG10(SDNode *N) { > + MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); > + SDValue Op = GetSoftenedFloat(N->getOperand(0)); > + return MakeLibCall(GetFPLibCall(N->getValueType(0), > + RTLIB::LOG10_F32, > + RTLIB::LOG10_F64, > + RTLIB::LOG10_F80, > + RTLIB::LOG10_PPCF128), > + NVT, &Op, 1, false); > +} > + > SDValue DAGTypeLegalizer::SoftenFloatRes_FMUL(SDNode *N) { > MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); > SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)), > @@ -184,6 +286,30 @@ > NVT, Ops, 2, false); > } > > +SDValue DAGTypeLegalizer::SoftenFloatRes_FNEARBYINT(SDNode *N) { > + MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); > + SDValue Op = GetSoftenedFloat(N->getOperand(0)); > + return MakeLibCall(GetFPLibCall(N->getValueType(0), > + RTLIB::NEARBYINT_F32, > + RTLIB::NEARBYINT_F64, > + RTLIB::NEARBYINT_F80, > + RTLIB::NEARBYINT_PPCF128), > + NVT, &Op, 1, false); > +} > + > +SDValue DAGTypeLegalizer::SoftenFloatRes_FNEG(SDNode *N) { > + MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); > + // Expand Y = FNEG(X) -> Y = SUB -0.0, X > + SDValue Ops[2] = { DAG.getConstantFP(-0.0, NVT), > + GetSoftenedFloat(N->getOperand(0)) }; > + return MakeLibCall(GetFPLibCall(N->getValueType(0), > + RTLIB::SUB_F32, > + RTLIB::SUB_F64, > + RTLIB::SUB_F80, > + RTLIB::SUB_PPCF128), > + NVT, Ops, 2, false); > +} > + > SDValue DAGTypeLegalizer::SoftenFloatRes_FP_EXTEND(SDNode *N) { > MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); > SDValue Op = N->getOperand(0); > @@ -225,6 +351,39 @@ > NVT, Ops, 2, false); > } > > +SDValue DAGTypeLegalizer::SoftenFloatRes_FRINT(SDNode *N) { > + MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); > + SDValue Op = GetSoftenedFloat(N->getOperand(0)); > + return MakeLibCall(GetFPLibCall(N->getValueType(0), > + RTLIB::RINT_F32, > + RTLIB::RINT_F64, > + RTLIB::RINT_F80, > + RTLIB::RINT_PPCF128), > + NVT, &Op, 1, false); > +} > + > +SDValue DAGTypeLegalizer::SoftenFloatRes_FSIN(SDNode *N) { > + MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); > + SDValue Op = GetSoftenedFloat(N->getOperand(0)); > + return MakeLibCall(GetFPLibCall(N->getValueType(0), > + RTLIB::SIN_F32, > + RTLIB::SIN_F64, > + RTLIB::SIN_F80, > + RTLIB::SIN_PPCF128), > + NVT, &Op, 1, false); > +} > + > +SDValue DAGTypeLegalizer::SoftenFloatRes_FSQRT(SDNode *N) { > + MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); > + SDValue Op = GetSoftenedFloat(N->getOperand(0)); > + return MakeLibCall(GetFPLibCall(N->getValueType(0), > + RTLIB::SQRT_F32, > + RTLIB::SQRT_F64, > + RTLIB::SQRT_F80, > + RTLIB::SQRT_PPCF128), > + NVT, &Op, 1, false); > +} > + > SDValue DAGTypeLegalizer::SoftenFloatRes_FSUB(SDNode *N) { > MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); > SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)), > @@ -237,6 +396,17 @@ > NVT, Ops, 2, false); > } > > +SDValue DAGTypeLegalizer::SoftenFloatRes_FTRUNC(SDNode *N) { > + MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); > + SDValue Op = GetSoftenedFloat(N->getOperand(0)); > + return MakeLibCall(GetFPLibCall(N->getValueType(0), > + RTLIB::TRUNC_F32, > + RTLIB::TRUNC_F64, > + RTLIB::TRUNC_F80, > + RTLIB::TRUNC_PPCF128), > + NVT, &Op, 1, false); > +} > + > SDValue DAGTypeLegalizer::SoftenFloatRes_LOAD(SDNode *N) { > LoadSDNode *L = cast(N); > MVT VT = N->getValueType(0); > @@ -607,7 +777,7 @@ > case ISD::FPOW: ExpandFloatRes_FPOW(N, Lo, Hi); break; > case ISD::FPOWI: ExpandFloatRes_FPOWI(N, Lo, Hi); break; > case ISD::FRINT: ExpandFloatRes_FRINT(N, Lo, Hi); break; > - case ISD::FSIN: ExpandFloatRes_FABS(N, Lo, Hi); break; > + case ISD::FSIN: ExpandFloatRes_FSIN(N, Lo, Hi); break; > case ISD::FSQRT: ExpandFloatRes_FSQRT(N, Lo, Hi); break; > case ISD::FSUB: ExpandFloatRes_FSUB(N, Lo, Hi); break; > case ISD::FTRUNC: ExpandFloatRes_FTRUNC(N, Lo, Hi); break; > @@ -926,14 +1096,14 @@ > // though. > if (SrcVT.bitsLE(MVT::i32)) { > // The integer can be represented exactly in an f64. > - Src = DAG.getNode(isSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, > + Src = DAG.getNode(isSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, > MVT::i32, Src); > Lo = DAG.getConstantFP(APFloat(APInt(NVT.getSizeInBits(), 0)), > NVT); > Hi = DAG.getNode(ISD::SINT_TO_FP, NVT, Src); > } else { > RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; > if (SrcVT.bitsLE(MVT::i64)) { > - Src = DAG.getNode(isSigned ? ISD::SIGN_EXTEND : > ISD::ZERO_EXTEND, > + Src = DAG.getNode(isSigned ? ISD::SIGN_EXTEND : > ISD::ZERO_EXTEND, > MVT::i64, Src); > LC = RTLIB::SINTTOFP_I64_PPCF128; > } else if (SrcVT.bitsLE(MVT::i128)) { > > Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h?rev=59464&r1=59463&r2=59464&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h (original) > +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h Mon Nov 17 > 14:52:38 2008 > @@ -351,14 +351,28 @@ > SDValue SoftenFloatRes_ConstantFP(ConstantFPSDNode *N); > SDValue SoftenFloatRes_FABS(SDNode *N); > SDValue SoftenFloatRes_FADD(SDNode *N); > + SDValue SoftenFloatRes_FCEIL(SDNode *N); > SDValue SoftenFloatRes_FCOPYSIGN(SDNode *N); > + SDValue SoftenFloatRes_FCOS(SDNode *N); > SDValue SoftenFloatRes_FDIV(SDNode *N); > + SDValue SoftenFloatRes_FEXP(SDNode *N); > + SDValue SoftenFloatRes_FEXP2(SDNode *N); > + SDValue SoftenFloatRes_FFLOOR(SDNode *N); > + SDValue SoftenFloatRes_FLOG(SDNode *N); > + SDValue SoftenFloatRes_FLOG2(SDNode *N); > + SDValue SoftenFloatRes_FLOG10(SDNode *N); > SDValue SoftenFloatRes_FMUL(SDNode *N); > + SDValue SoftenFloatRes_FNEARBYINT(SDNode *N); > + SDValue SoftenFloatRes_FNEG(SDNode *N); > SDValue SoftenFloatRes_FP_EXTEND(SDNode *N); > SDValue SoftenFloatRes_FP_ROUND(SDNode *N); > SDValue SoftenFloatRes_FPOW(SDNode *N); > SDValue SoftenFloatRes_FPOWI(SDNode *N); > + SDValue SoftenFloatRes_FRINT(SDNode *N); > + SDValue SoftenFloatRes_FSIN(SDNode *N); > + SDValue SoftenFloatRes_FSQRT(SDNode *N); > SDValue SoftenFloatRes_FSUB(SDNode *N); > + SDValue SoftenFloatRes_FTRUNC(SDNode *N); > SDValue SoftenFloatRes_LOAD(SDNode *N); > SDValue SoftenFloatRes_SELECT(SDNode *N); > SDValue SoftenFloatRes_SELECT_CC(SDNode *N); > > Added: llvm/trunk/test/CodeGen/XCore/cos.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/XCore/cos.ll?rev=59464&view=auto > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/test/CodeGen/XCore/cos.ll (added) > +++ llvm/trunk/test/CodeGen/XCore/cos.ll Mon Nov 17 14:52:38 2008 > @@ -0,0 +1,16 @@ > +; RUN: llvm-as < %s | llc -march=xcore > %t1.s > +; RUN: grep "bl cosf" %t1.s | count 1 > +; RUN: grep "bl cos" %t1.s | count 2 > +declare double @llvm.cos.f64(double) > + > +define double @test(double %F) { > + %result = call double @llvm.cos.f64(double %F) > + ret double %result > +} > + > +declare float @llvm.cos.f32(float) > + > +define float @testf(float %F) { > + %result = call float @llvm.cos.f32(float %F) > + ret float %result > +} > > Added: llvm/trunk/test/CodeGen/XCore/exp.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/XCore/exp.ll?rev=59464&view=auto > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/test/CodeGen/XCore/exp.ll (added) > +++ llvm/trunk/test/CodeGen/XCore/exp.ll Mon Nov 17 14:52:38 2008 > @@ -0,0 +1,16 @@ > +; RUN: llvm-as < %s | llc -march=xcore > %t1.s > +; RUN: grep "bl expf" %t1.s | count 1 > +; RUN: grep "bl exp" %t1.s | count 2 > +declare double @llvm.exp.f64(double) > + > +define double @test(double %F) { > + %result = call double @llvm.exp.f64(double %F) > + ret double %result > +} > + > +declare float @llvm.exp.f32(float) > + > +define float @testf(float %F) { > + %result = call float @llvm.exp.f32(float %F) > + ret float %result > +} > > Added: llvm/trunk/test/CodeGen/XCore/exp2.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/XCore/exp2.ll?rev=59464&view=auto > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/test/CodeGen/XCore/exp2.ll (added) > +++ llvm/trunk/test/CodeGen/XCore/exp2.ll Mon Nov 17 14:52:38 2008 > @@ -0,0 +1,16 @@ > +; RUN: llvm-as < %s | llc -march=xcore > %t1.s > +; RUN: grep "bl exp2f" %t1.s | count 1 > +; RUN: grep "bl exp2" %t1.s | count 2 > +declare double @llvm.exp2.f64(double) > + > +define double @test(double %F) { > + %result = call double @llvm.exp2.f64(double %F) > + ret double %result > +} > + > +declare float @llvm.exp2.f32(float) > + > +define float @testf(float %F) { > + %result = call float @llvm.exp2.f32(float %F) > + ret float %result > +} > > Added: llvm/trunk/test/CodeGen/XCore/fneg.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/XCore/fneg.ll?rev=59464&view=auto > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/test/CodeGen/XCore/fneg.ll (added) > +++ llvm/trunk/test/CodeGen/XCore/fneg.ll Mon Nov 17 14:52:38 2008 > @@ -0,0 +1,8 @@ > +; RUN: llvm-as < %s | llc -march=xcore > %t1.s > +; RUN: grep "bl __subdf3" %t1.s | count 1 > +define i1 @test(double %F) nounwind { > +entry: > + %0 = sub double -0.000000e+00, %F > + %1 = fcmp olt double 0.000000e+00, %0 > + ret i1 %1 > +} > > Added: llvm/trunk/test/CodeGen/XCore/log.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/XCore/log.ll?rev=59464&view=auto > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/test/CodeGen/XCore/log.ll (added) > +++ llvm/trunk/test/CodeGen/XCore/log.ll Mon Nov 17 14:52:38 2008 > @@ -0,0 +1,16 @@ > +; RUN: llvm-as < %s | llc -march=xcore > %t1.s > +; RUN: grep "bl logf" %t1.s | count 1 > +; RUN: grep "bl log" %t1.s | count 2 > +declare double @llvm.log.f64(double) > + > +define double @test(double %F) { > + %result = call double @llvm.log.f64(double %F) > + ret double %result > +} > + > +declare float @llvm.log.f32(float) > + > +define float @testf(float %F) { > + %result = call float @llvm.log.f32(float %F) > + ret float %result > +} > > Added: llvm/trunk/test/CodeGen/XCore/log10.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/XCore/log10.ll?rev=59464&view=auto > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/test/CodeGen/XCore/log10.ll (added) > +++ llvm/trunk/test/CodeGen/XCore/log10.ll Mon Nov 17 14:52:38 2008 > @@ -0,0 +1,16 @@ > +; RUN: llvm-as < %s | llc -march=xcore > %t1.s > +; RUN: grep "bl log10f" %t1.s | count 1 > +; RUN: grep "bl log10" %t1.s | count 2 > +declare double @llvm.log10.f64(double) > + > +define double @test(double %F) { > + %result = call double @llvm.log10.f64(double %F) > + ret double %result > +} > + > +declare float @llvm.log10.f32(float) > + > +define float @testf(float %F) { > + %result = call float @llvm.log10.f32(float %F) > + ret float %result > +} > > Added: llvm/trunk/test/CodeGen/XCore/log2.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/XCore/log2.ll?rev=59464&view=auto > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/test/CodeGen/XCore/log2.ll (added) > +++ llvm/trunk/test/CodeGen/XCore/log2.ll Mon Nov 17 14:52:38 2008 > @@ -0,0 +1,16 @@ > +; RUN: llvm-as < %s | llc -march=xcore > %t1.s > +; RUN: grep "bl log2f" %t1.s | count 1 > +; RUN: grep "bl log2" %t1.s | count 2 > +declare double @llvm.log2.f64(double) > + > +define double @test(double %F) { > + %result = call double @llvm.log2.f64(double %F) > + ret double %result > +} > + > +declare float @llvm.log2.f32(float) > + > +define float @testf(float %F) { > + %result = call float @llvm.log2.f32(float %F) > + ret float %result > +} > > Added: llvm/trunk/test/CodeGen/XCore/pow.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/XCore/pow.ll?rev=59464&view=auto > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/test/CodeGen/XCore/pow.ll (added) > +++ llvm/trunk/test/CodeGen/XCore/pow.ll Mon Nov 17 14:52:38 2008 > @@ -0,0 +1,16 @@ > +; RUN: llvm-as < %s | llc -march=xcore > %t1.s > +; RUN: grep "bl powf" %t1.s | count 1 > +; RUN: grep "bl pow" %t1.s | count 2 > +declare double @llvm.pow.f64(double, double) > + > +define double @test(double %F, double %power) { > + %result = call double @llvm.pow.f64(double %F, double %power) > + ret double %result > +} > + > +declare float @llvm.pow.f32(float, float) > + > +define float @testf(float %F, float %power) { > + %result = call float @llvm.pow.f32(float %F, float %power) > + ret float %result > +} > > Added: llvm/trunk/test/CodeGen/XCore/powi.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/XCore/powi.ll?rev=59464&view=auto > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/test/CodeGen/XCore/powi.ll (added) > +++ llvm/trunk/test/CodeGen/XCore/powi.ll Mon Nov 17 14:52:38 2008 > @@ -0,0 +1,16 @@ > +; RUN: llvm-as < %s | llc -march=xcore > %t1.s > +; RUN: grep "bl __powidf2" %t1.s | count 1 > +; RUN: grep "bl __powisf2" %t1.s | count 1 > +declare double @llvm.powi.f64(double, i32) > + > +define double @test(double %F, i32 %power) { > + %result = call double @llvm.powi.f64(double %F, i32 %power) > + ret double %result > +} > + > +declare float @llvm.powi.f32(float, i32) > + > +define float @testf(float %F, i32 %power) { > + %result = call float @llvm.powi.f32(float %F, i32 %power) > + ret float %result > +} > > Added: llvm/trunk/test/CodeGen/XCore/sin.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/XCore/sin.ll?rev=59464&view=auto > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/test/CodeGen/XCore/sin.ll (added) > +++ llvm/trunk/test/CodeGen/XCore/sin.ll Mon Nov 17 14:52:38 2008 > @@ -0,0 +1,16 @@ > +; RUN: llvm-as < %s | llc -march=xcore > %t1.s > +; RUN: grep "bl sinf" %t1.s | count 1 > +; RUN: grep "bl sin" %t1.s | count 2 > +declare double @llvm.sin.f64(double) > + > +define double @test(double %F) { > + %result = call double @llvm.sin.f64(double %F) > + ret double %result > +} > + > +declare float @llvm.sin.f32(float) > + > +define float @testf(float %F) { > + %result = call float @llvm.sin.f32(float %F) > + ret float %result > +} > > Added: llvm/trunk/test/CodeGen/XCore/sqrt.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/XCore/sqrt.ll?rev=59464&view=auto > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/test/CodeGen/XCore/sqrt.ll (added) > +++ llvm/trunk/test/CodeGen/XCore/sqrt.ll Mon Nov 17 14:52:38 2008 > @@ -0,0 +1,16 @@ > +; RUN: llvm-as < %s | llc -march=xcore > %t1.s > +; RUN: grep "bl sqrtf" %t1.s | count 1 > +; RUN: grep "bl sqrt" %t1.s | count 2 > +declare double @llvm.sqrt.f64(double) > + > +define double @test(double %F) { > + %result = call double @llvm.sqrt.f64(double %F) > + ret double %result > +} > + > +declare float @llvm.sqrt.f32(float) > + > +define float @testf(float %F) { > + %result = call float @llvm.sqrt.f32(float %F) > + ret float %result > +} > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From isanbard at gmail.com Mon Nov 17 19:49:25 2008 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 18 Nov 2008 01:49:25 -0000 Subject: [llvm-commits] [llvm] r59487 - in /llvm/trunk: lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp lib/CodeGen/SelectionDAG/LegalizeTypes.h test/CodeGen/XCore/cos.ll test/CodeGen/XCore/exp.ll test/CodeGen/XCore/exp2.ll test/CodeGen/XCore/fneg.ll test/CodeGen/XCore/log.ll test/CodeGen/XCore/log10.ll test/CodeGen/XCore/log2.ll test/CodeGen/XCore/sin.ll test/CodeGen/XCore/sqrt.ll Message-ID: <200811180149.mAI1nQ81028533@zion.cs.uiuc.edu> Author: void Date: Mon Nov 17 19:49:24 2008 New Revision: 59487 URL: http://llvm.org/viewvc/llvm-project?rev=59487&view=rev Log: Revert r59464. It was causing this failure: Running /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvm.src/test/CodeGen/XCore/dg.exp ... FAIL: /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvm.src/test/CodeGen/XCore/fneg.ll Failed with signal(SIGABRT) at line 1 while running: llvm-as < /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvm.src/test/CodeGen/XCore/fneg.ll | llc -march=xcore > fneg.ll.tmp1.s Assertion failed: (VT.isFloatingPoint() && "Cannot create integer FP constant!"), function getConstantFP, file /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvm.src/lib/CodeGen/SelectionDAG/SelectionDAG.cpp, line 913. 0 llc 0x0092115c _ZN4llvm3sys18RemoveFileOnSignalERKNS0_4PathEPSs + 844 1 libSystem.B.dylib 0x9217809b _sigtramp + 43 2 ??? 0xffffffff 0x0 + 4294967295 3 libSystem.B.dylib 0x921f0ec2 raise + 26 4 libSystem.B.dylib 0x9220047f abort + 73 5 libSystem.B.dylib 0x921f2063 __assert_rtn + 101 6 llc 0x005a5b0a _ZN4llvm12SelectionDAG13getConmake[1]: *** [check-local] Error 1 make: *** [check] Error 2 Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h llvm/trunk/test/CodeGen/XCore/cos.ll llvm/trunk/test/CodeGen/XCore/exp.ll llvm/trunk/test/CodeGen/XCore/exp2.ll llvm/trunk/test/CodeGen/XCore/fneg.ll llvm/trunk/test/CodeGen/XCore/log.ll llvm/trunk/test/CodeGen/XCore/log10.ll llvm/trunk/test/CodeGen/XCore/log2.ll llvm/trunk/test/CodeGen/XCore/sin.ll llvm/trunk/test/CodeGen/XCore/sqrt.ll Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp?rev=59487&r1=59486&r2=59487&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp Mon Nov 17 19:49:24 2008 @@ -61,28 +61,14 @@ break; case ISD::FABS: R = SoftenFloatRes_FABS(N); break; case ISD::FADD: R = SoftenFloatRes_FADD(N); break; - case ISD::FCEIL: R = SoftenFloatRes_FCEIL(N); break; case ISD::FCOPYSIGN: R = SoftenFloatRes_FCOPYSIGN(N); break; - case ISD::FCOS: R = SoftenFloatRes_FCOS(N); break; case ISD::FDIV: R = SoftenFloatRes_FDIV(N); break; - case ISD::FEXP: R = SoftenFloatRes_FEXP(N); break; - case ISD::FEXP2: R = SoftenFloatRes_FEXP2(N); break; - case ISD::FFLOOR: R = SoftenFloatRes_FFLOOR(N); break; - case ISD::FLOG: R = SoftenFloatRes_FLOG(N); break; - case ISD::FLOG2: R = SoftenFloatRes_FLOG2(N); break; - case ISD::FLOG10: R = SoftenFloatRes_FLOG10(N); break; case ISD::FMUL: R = SoftenFloatRes_FMUL(N); break; - case ISD::FNEARBYINT: R = SoftenFloatRes_FNEARBYINT(N); break; - case ISD::FNEG: R = SoftenFloatRes_FNEG(N); break; case ISD::FP_EXTEND: R = SoftenFloatRes_FP_EXTEND(N); break; case ISD::FP_ROUND: R = SoftenFloatRes_FP_ROUND(N); break; case ISD::FPOW: R = SoftenFloatRes_FPOW(N); break; case ISD::FPOWI: R = SoftenFloatRes_FPOWI(N); break; - case ISD::FRINT: R = SoftenFloatRes_FRINT(N); break; - case ISD::FSIN: R = SoftenFloatRes_FSIN(N); break; - case ISD::FSQRT: R = SoftenFloatRes_FSQRT(N); break; case ISD::FSUB: R = SoftenFloatRes_FSUB(N); break; - case ISD::FTRUNC: R = SoftenFloatRes_FTRUNC(N); break; case ISD::LOAD: R = SoftenFloatRes_LOAD(N); break; case ISD::SELECT: R = SoftenFloatRes_SELECT(N); break; case ISD::SELECT_CC: R = SoftenFloatRes_SELECT_CC(N); break; @@ -117,7 +103,7 @@ unsigned Size = NVT.getSizeInBits(); // Mask = ~(1 << (Size-1)) - SDValue Mask = DAG.getConstant(APInt::getAllOnesValue(Size).clear(Size-1), + SDValue Mask = DAG.getConstant(APInt::getAllOnesValue(Size).clear(Size-1), NVT); SDValue Op = GetSoftenedFloat(N->getOperand(0)); return DAG.getNode(ISD::AND, NVT, Op, Mask); @@ -135,17 +121,6 @@ NVT, Ops, 2, false); } -SDValue DAGTypeLegalizer::SoftenFloatRes_FCEIL(SDNode *N) { - MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); - SDValue Op = GetSoftenedFloat(N->getOperand(0)); - return MakeLibCall(GetFPLibCall(N->getValueType(0), - RTLIB::CEIL_F32, - RTLIB::CEIL_F64, - RTLIB::CEIL_F80, - RTLIB::CEIL_PPCF128), - NVT, &Op, 1, false); -} - SDValue DAGTypeLegalizer::SoftenFloatRes_FCOPYSIGN(SDNode *N) { SDValue LHS = GetSoftenedFloat(N->getOperand(0)); SDValue RHS = BitConvertToInteger(N->getOperand(1)); @@ -185,17 +160,6 @@ return DAG.getNode(ISD::OR, LVT, LHS, SignBit); } -SDValue DAGTypeLegalizer::SoftenFloatRes_FCOS(SDNode *N) { - MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); - SDValue Op = GetSoftenedFloat(N->getOperand(0)); - return MakeLibCall(GetFPLibCall(N->getValueType(0), - RTLIB::COS_F32, - RTLIB::COS_F64, - RTLIB::COS_F80, - RTLIB::COS_PPCF128), - NVT, &Op, 1, false); -} - SDValue DAGTypeLegalizer::SoftenFloatRes_FDIV(SDNode *N) { MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)), @@ -208,72 +172,6 @@ NVT, Ops, 2, false); } -SDValue DAGTypeLegalizer::SoftenFloatRes_FEXP(SDNode *N) { - MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); - SDValue Op = GetSoftenedFloat(N->getOperand(0)); - return MakeLibCall(GetFPLibCall(N->getValueType(0), - RTLIB::EXP_F32, - RTLIB::EXP_F64, - RTLIB::EXP_F80, - RTLIB::EXP_PPCF128), - NVT, &Op, 1, false); -} - -SDValue DAGTypeLegalizer::SoftenFloatRes_FEXP2(SDNode *N) { - MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); - SDValue Op = GetSoftenedFloat(N->getOperand(0)); - return MakeLibCall(GetFPLibCall(N->getValueType(0), - RTLIB::EXP2_F32, - RTLIB::EXP2_F64, - RTLIB::EXP2_F80, - RTLIB::EXP2_PPCF128), - NVT, &Op, 1, false); -} - -SDValue DAGTypeLegalizer::SoftenFloatRes_FFLOOR(SDNode *N) { - MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); - SDValue Op = GetSoftenedFloat(N->getOperand(0)); - return MakeLibCall(GetFPLibCall(N->getValueType(0), - RTLIB::FLOOR_F32, - RTLIB::FLOOR_F64, - RTLIB::FLOOR_F80, - RTLIB::FLOOR_PPCF128), - NVT, &Op, 1, false); -} - -SDValue DAGTypeLegalizer::SoftenFloatRes_FLOG(SDNode *N) { - MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); - SDValue Op = GetSoftenedFloat(N->getOperand(0)); - return MakeLibCall(GetFPLibCall(N->getValueType(0), - RTLIB::LOG_F32, - RTLIB::LOG_F64, - RTLIB::LOG_F80, - RTLIB::LOG_PPCF128), - NVT, &Op, 1, false); -} - -SDValue DAGTypeLegalizer::SoftenFloatRes_FLOG2(SDNode *N) { - MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); - SDValue Op = GetSoftenedFloat(N->getOperand(0)); - return MakeLibCall(GetFPLibCall(N->getValueType(0), - RTLIB::LOG2_F32, - RTLIB::LOG2_F64, - RTLIB::LOG2_F80, - RTLIB::LOG2_PPCF128), - NVT, &Op, 1, false); -} - -SDValue DAGTypeLegalizer::SoftenFloatRes_FLOG10(SDNode *N) { - MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); - SDValue Op = GetSoftenedFloat(N->getOperand(0)); - return MakeLibCall(GetFPLibCall(N->getValueType(0), - RTLIB::LOG10_F32, - RTLIB::LOG10_F64, - RTLIB::LOG10_F80, - RTLIB::LOG10_PPCF128), - NVT, &Op, 1, false); -} - SDValue DAGTypeLegalizer::SoftenFloatRes_FMUL(SDNode *N) { MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)), @@ -286,30 +184,6 @@ NVT, Ops, 2, false); } -SDValue DAGTypeLegalizer::SoftenFloatRes_FNEARBYINT(SDNode *N) { - MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); - SDValue Op = GetSoftenedFloat(N->getOperand(0)); - return MakeLibCall(GetFPLibCall(N->getValueType(0), - RTLIB::NEARBYINT_F32, - RTLIB::NEARBYINT_F64, - RTLIB::NEARBYINT_F80, - RTLIB::NEARBYINT_PPCF128), - NVT, &Op, 1, false); -} - -SDValue DAGTypeLegalizer::SoftenFloatRes_FNEG(SDNode *N) { - MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); - // Expand Y = FNEG(X) -> Y = SUB -0.0, X - SDValue Ops[2] = { DAG.getConstantFP(-0.0, NVT), - GetSoftenedFloat(N->getOperand(0)) }; - return MakeLibCall(GetFPLibCall(N->getValueType(0), - RTLIB::SUB_F32, - RTLIB::SUB_F64, - RTLIB::SUB_F80, - RTLIB::SUB_PPCF128), - NVT, Ops, 2, false); -} - SDValue DAGTypeLegalizer::SoftenFloatRes_FP_EXTEND(SDNode *N) { MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); SDValue Op = N->getOperand(0); @@ -351,39 +225,6 @@ NVT, Ops, 2, false); } -SDValue DAGTypeLegalizer::SoftenFloatRes_FRINT(SDNode *N) { - MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); - SDValue Op = GetSoftenedFloat(N->getOperand(0)); - return MakeLibCall(GetFPLibCall(N->getValueType(0), - RTLIB::RINT_F32, - RTLIB::RINT_F64, - RTLIB::RINT_F80, - RTLIB::RINT_PPCF128), - NVT, &Op, 1, false); -} - -SDValue DAGTypeLegalizer::SoftenFloatRes_FSIN(SDNode *N) { - MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); - SDValue Op = GetSoftenedFloat(N->getOperand(0)); - return MakeLibCall(GetFPLibCall(N->getValueType(0), - RTLIB::SIN_F32, - RTLIB::SIN_F64, - RTLIB::SIN_F80, - RTLIB::SIN_PPCF128), - NVT, &Op, 1, false); -} - -SDValue DAGTypeLegalizer::SoftenFloatRes_FSQRT(SDNode *N) { - MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); - SDValue Op = GetSoftenedFloat(N->getOperand(0)); - return MakeLibCall(GetFPLibCall(N->getValueType(0), - RTLIB::SQRT_F32, - RTLIB::SQRT_F64, - RTLIB::SQRT_F80, - RTLIB::SQRT_PPCF128), - NVT, &Op, 1, false); -} - SDValue DAGTypeLegalizer::SoftenFloatRes_FSUB(SDNode *N) { MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)), @@ -396,17 +237,6 @@ NVT, Ops, 2, false); } -SDValue DAGTypeLegalizer::SoftenFloatRes_FTRUNC(SDNode *N) { - MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); - SDValue Op = GetSoftenedFloat(N->getOperand(0)); - return MakeLibCall(GetFPLibCall(N->getValueType(0), - RTLIB::TRUNC_F32, - RTLIB::TRUNC_F64, - RTLIB::TRUNC_F80, - RTLIB::TRUNC_PPCF128), - NVT, &Op, 1, false); -} - SDValue DAGTypeLegalizer::SoftenFloatRes_LOAD(SDNode *N) { LoadSDNode *L = cast(N); MVT VT = N->getValueType(0); @@ -777,7 +607,7 @@ case ISD::FPOW: ExpandFloatRes_FPOW(N, Lo, Hi); break; case ISD::FPOWI: ExpandFloatRes_FPOWI(N, Lo, Hi); break; case ISD::FRINT: ExpandFloatRes_FRINT(N, Lo, Hi); break; - case ISD::FSIN: ExpandFloatRes_FSIN(N, Lo, Hi); break; + case ISD::FSIN: ExpandFloatRes_FABS(N, Lo, Hi); break; case ISD::FSQRT: ExpandFloatRes_FSQRT(N, Lo, Hi); break; case ISD::FSUB: ExpandFloatRes_FSUB(N, Lo, Hi); break; case ISD::FTRUNC: ExpandFloatRes_FTRUNC(N, Lo, Hi); break; @@ -1096,14 +926,14 @@ // though. if (SrcVT.bitsLE(MVT::i32)) { // The integer can be represented exactly in an f64. - Src = DAG.getNode(isSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, + Src = DAG.getNode(isSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, MVT::i32, Src); Lo = DAG.getConstantFP(APFloat(APInt(NVT.getSizeInBits(), 0)), NVT); Hi = DAG.getNode(ISD::SINT_TO_FP, NVT, Src); } else { RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; if (SrcVT.bitsLE(MVT::i64)) { - Src = DAG.getNode(isSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, + Src = DAG.getNode(isSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, MVT::i64, Src); LC = RTLIB::SINTTOFP_I64_PPCF128; } else if (SrcVT.bitsLE(MVT::i128)) { Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h?rev=59487&r1=59486&r2=59487&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h Mon Nov 17 19:49:24 2008 @@ -351,28 +351,14 @@ SDValue SoftenFloatRes_ConstantFP(ConstantFPSDNode *N); SDValue SoftenFloatRes_FABS(SDNode *N); SDValue SoftenFloatRes_FADD(SDNode *N); - SDValue SoftenFloatRes_FCEIL(SDNode *N); SDValue SoftenFloatRes_FCOPYSIGN(SDNode *N); - SDValue SoftenFloatRes_FCOS(SDNode *N); SDValue SoftenFloatRes_FDIV(SDNode *N); - SDValue SoftenFloatRes_FEXP(SDNode *N); - SDValue SoftenFloatRes_FEXP2(SDNode *N); - SDValue SoftenFloatRes_FFLOOR(SDNode *N); - SDValue SoftenFloatRes_FLOG(SDNode *N); - SDValue SoftenFloatRes_FLOG2(SDNode *N); - SDValue SoftenFloatRes_FLOG10(SDNode *N); SDValue SoftenFloatRes_FMUL(SDNode *N); - SDValue SoftenFloatRes_FNEARBYINT(SDNode *N); - SDValue SoftenFloatRes_FNEG(SDNode *N); SDValue SoftenFloatRes_FP_EXTEND(SDNode *N); SDValue SoftenFloatRes_FP_ROUND(SDNode *N); SDValue SoftenFloatRes_FPOW(SDNode *N); SDValue SoftenFloatRes_FPOWI(SDNode *N); - SDValue SoftenFloatRes_FRINT(SDNode *N); - SDValue SoftenFloatRes_FSIN(SDNode *N); - SDValue SoftenFloatRes_FSQRT(SDNode *N); SDValue SoftenFloatRes_FSUB(SDNode *N); - SDValue SoftenFloatRes_FTRUNC(SDNode *N); SDValue SoftenFloatRes_LOAD(SDNode *N); SDValue SoftenFloatRes_SELECT(SDNode *N); SDValue SoftenFloatRes_SELECT_CC(SDNode *N); Modified: llvm/trunk/test/CodeGen/XCore/cos.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/XCore/cos.ll?rev=59487&r1=59486&r2=59487&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/XCore/cos.ll (original) +++ llvm/trunk/test/CodeGen/XCore/cos.ll Mon Nov 17 19:49:24 2008 @@ -1,6 +1,7 @@ ; RUN: llvm-as < %s | llc -march=xcore > %t1.s ; RUN: grep "bl cosf" %t1.s | count 1 ; RUN: grep "bl cos" %t1.s | count 2 +; XFAIL: * declare double @llvm.cos.f64(double) define double @test(double %F) { Modified: llvm/trunk/test/CodeGen/XCore/exp.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/XCore/exp.ll?rev=59487&r1=59486&r2=59487&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/XCore/exp.ll (original) +++ llvm/trunk/test/CodeGen/XCore/exp.ll Mon Nov 17 19:49:24 2008 @@ -1,6 +1,7 @@ ; RUN: llvm-as < %s | llc -march=xcore > %t1.s ; RUN: grep "bl expf" %t1.s | count 1 ; RUN: grep "bl exp" %t1.s | count 2 +; XFAIL: * declare double @llvm.exp.f64(double) define double @test(double %F) { Modified: llvm/trunk/test/CodeGen/XCore/exp2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/XCore/exp2.ll?rev=59487&r1=59486&r2=59487&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/XCore/exp2.ll (original) +++ llvm/trunk/test/CodeGen/XCore/exp2.ll Mon Nov 17 19:49:24 2008 @@ -1,6 +1,7 @@ ; RUN: llvm-as < %s | llc -march=xcore > %t1.s ; RUN: grep "bl exp2f" %t1.s | count 1 ; RUN: grep "bl exp2" %t1.s | count 2 +; XFAIL: * declare double @llvm.exp2.f64(double) define double @test(double %F) { Modified: llvm/trunk/test/CodeGen/XCore/fneg.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/XCore/fneg.ll?rev=59487&r1=59486&r2=59487&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/XCore/fneg.ll (original) +++ llvm/trunk/test/CodeGen/XCore/fneg.ll Mon Nov 17 19:49:24 2008 @@ -1,5 +1,6 @@ ; RUN: llvm-as < %s | llc -march=xcore > %t1.s ; RUN: grep "bl __subdf3" %t1.s | count 1 +; XFAIL: * define i1 @test(double %F) nounwind { entry: %0 = sub double -0.000000e+00, %F Modified: llvm/trunk/test/CodeGen/XCore/log.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/XCore/log.ll?rev=59487&r1=59486&r2=59487&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/XCore/log.ll (original) +++ llvm/trunk/test/CodeGen/XCore/log.ll Mon Nov 17 19:49:24 2008 @@ -1,6 +1,7 @@ ; RUN: llvm-as < %s | llc -march=xcore > %t1.s ; RUN: grep "bl logf" %t1.s | count 1 ; RUN: grep "bl log" %t1.s | count 2 +; XFAIL: * declare double @llvm.log.f64(double) define double @test(double %F) { Modified: llvm/trunk/test/CodeGen/XCore/log10.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/XCore/log10.ll?rev=59487&r1=59486&r2=59487&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/XCore/log10.ll (original) +++ llvm/trunk/test/CodeGen/XCore/log10.ll Mon Nov 17 19:49:24 2008 @@ -1,6 +1,7 @@ ; RUN: llvm-as < %s | llc -march=xcore > %t1.s ; RUN: grep "bl log10f" %t1.s | count 1 ; RUN: grep "bl log10" %t1.s | count 2 +; XFAIL: * declare double @llvm.log10.f64(double) define double @test(double %F) { Modified: llvm/trunk/test/CodeGen/XCore/log2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/XCore/log2.ll?rev=59487&r1=59486&r2=59487&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/XCore/log2.ll (original) +++ llvm/trunk/test/CodeGen/XCore/log2.ll Mon Nov 17 19:49:24 2008 @@ -1,6 +1,7 @@ ; RUN: llvm-as < %s | llc -march=xcore > %t1.s ; RUN: grep "bl log2f" %t1.s | count 1 ; RUN: grep "bl log2" %t1.s | count 2 +; XFAIL: * declare double @llvm.log2.f64(double) define double @test(double %F) { Modified: llvm/trunk/test/CodeGen/XCore/sin.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/XCore/sin.ll?rev=59487&r1=59486&r2=59487&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/XCore/sin.ll (original) +++ llvm/trunk/test/CodeGen/XCore/sin.ll Mon Nov 17 19:49:24 2008 @@ -1,6 +1,7 @@ ; RUN: llvm-as < %s | llc -march=xcore > %t1.s ; RUN: grep "bl sinf" %t1.s | count 1 ; RUN: grep "bl sin" %t1.s | count 2 +; XFAIL: * declare double @llvm.sin.f64(double) define double @test(double %F) { Modified: llvm/trunk/test/CodeGen/XCore/sqrt.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/XCore/sqrt.ll?rev=59487&r1=59486&r2=59487&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/XCore/sqrt.ll (original) +++ llvm/trunk/test/CodeGen/XCore/sqrt.ll Mon Nov 17 19:49:24 2008 @@ -1,6 +1,7 @@ ; RUN: llvm-as < %s | llc -march=xcore > %t1.s ; RUN: grep "bl sqrtf" %t1.s | count 1 ; RUN: grep "bl sqrt" %t1.s | count 2 +; XFAIL: * declare double @llvm.sqrt.f64(double) define double @test(double %F) { From gohman at apple.com Mon Nov 17 20:06:40 2008 From: gohman at apple.com (Dan Gohman) Date: Tue, 18 Nov 2008 02:06:40 -0000 Subject: [llvm-commits] [llvm] r59488 - in /llvm/trunk: include/llvm/CodeGen/ScheduleDAG.h lib/CodeGen/SelectionDAG/ScheduleDAG.cpp lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Message-ID: <200811180206.mAI26f8L029131@zion.cs.uiuc.edu> Author: djg Date: Mon Nov 17 20:06:40 2008 New Revision: 59488 URL: http://llvm.org/viewvc/llvm-project?rev=59488&view=rev Log: Change SUnit's dump method to take a ScheduleDAG* instead of a SelectionDAG*. Modified: llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Modified: llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h?rev=59488&r1=59487&r2=59488&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h (original) +++ llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h Mon Nov 17 20:06:40 2008 @@ -29,6 +29,7 @@ class MachineRegisterInfo; class MachineInstr; class TargetRegisterInfo; + class ScheduleDAG; class SelectionDAG; class SelectionDAGISel; class TargetInstrInfo; @@ -239,8 +240,8 @@ return false; } - void dump(const SelectionDAG *G) const; - void dumpAll(const SelectionDAG *G) const; + void dump(const ScheduleDAG *G) const; + void dumpAll(const ScheduleDAG *G) const; }; //===--------------------------------------------------------------------===// Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp?rev=59488&r1=59487&r2=59488&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Mon Nov 17 20:06:40 2008 @@ -440,7 +440,7 @@ void ScheduleDAG::dumpSchedule() const { for (unsigned i = 0, e = Sequence.size(); i != e; i++) { if (SUnit *SU = Sequence[i]) - SU->dump(DAG); + SU->dump(this); else cerr << "**** NOOP ****\n"; } @@ -459,10 +459,10 @@ /// SUnit - Scheduling unit. It's an wrapper around either a single SDNode or /// a group of nodes flagged together. -void SUnit::dump(const SelectionDAG *G) const { +void SUnit::dump(const ScheduleDAG *G) const { cerr << "SU(" << NodeNum << "): "; if (getNode()) - getNode()->dump(G); + getNode()->dump(G->DAG); else cerr << "CROSS RC COPY "; cerr << "\n"; @@ -471,13 +471,13 @@ FlaggedNodes.push_back(N); while (!FlaggedNodes.empty()) { cerr << " "; - FlaggedNodes.back()->dump(G); + FlaggedNodes.back()->dump(G->DAG); cerr << "\n"; FlaggedNodes.pop_back(); } } -void SUnit::dumpAll(const SelectionDAG *G) const { +void SUnit::dumpAll(const ScheduleDAG *G) const { dump(G); cerr << " # preds left : " << NumPredsLeft << "\n"; Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp?rev=59488&r1=59487&r2=59488&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp Mon Nov 17 20:06:40 2008 @@ -125,7 +125,7 @@ BuildSchedUnits(); DEBUG(for (unsigned su = 0, e = SUnits.size(); su != e; ++su) - SUnits[su].dumpAll(DAG)); + SUnits[su].dumpAll(this)); // Execute the actual scheduling loop. ListScheduleBottomUp(); @@ -143,7 +143,7 @@ #ifndef NDEBUG if (PredSU->NumSuccsLeft < 0) { cerr << "*** Scheduling failed! ***\n"; - PredSU->dump(DAG); + PredSU->dump(this); cerr << " has been released too many times!\n"; assert(0); } @@ -160,7 +160,7 @@ /// the Available queue. void ScheduleDAGFast::ScheduleNodeBottomUp(SUnit *SU, unsigned CurCycle) { DOUT << "*** Scheduling [" << CurCycle << "]: "; - DEBUG(SU->dump(DAG)); + DEBUG(SU->dump(this)); SU->Cycle = CurCycle; // Bottom up: release predecessors @@ -613,14 +613,14 @@ } if (!AnyNotSched) cerr << "*** List scheduling failed! ***\n"; - SUnits[i].dump(DAG); + SUnits[i].dump(this); cerr << "has not been scheduled!\n"; AnyNotSched = true; } if (SUnits[i].NumSuccsLeft != 0) { if (!AnyNotSched) cerr << "*** List scheduling failed! ***\n"; - SUnits[i].dump(DAG); + SUnits[i].dump(this); cerr << "has successors left!\n"; AnyNotSched = true; } Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp?rev=59488&r1=59487&r2=59488&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Mon Nov 17 20:06:40 2008 @@ -113,7 +113,7 @@ #ifndef NDEBUG if (SuccSU->NumPredsLeft < 0) { cerr << "*** Scheduling failed! ***\n"; - SuccSU->dump(DAG); + SuccSU->dump(this); cerr << " has been released too many times!\n"; assert(0); } @@ -142,7 +142,7 @@ /// the Available queue. void ScheduleDAGList::ScheduleNodeTopDown(SUnit *SU, unsigned CurCycle) { DOUT << "*** Scheduling [" << CurCycle << "]: "; - DEBUG(SU->dump(DAG)); + DEBUG(SU->dump(this)); Sequence.push_back(SU); SU->Cycle = CurCycle; @@ -267,7 +267,7 @@ if (SUnits[i].NumPredsLeft != 0) { if (!AnyNotSched) cerr << "*** List scheduling failed! ***\n"; - SUnits[i].dump(DAG); + SUnits[i].dump(this); cerr << "has not been scheduled!\n"; AnyNotSched = true; } Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp?rev=59488&r1=59487&r2=59488&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Mon Nov 17 20:06:40 2008 @@ -186,7 +186,7 @@ BuildSchedUnits(); DEBUG(for (unsigned su = 0, e = SUnits.size(); su != e; ++su) - SUnits[su].dumpAll(DAG)); + SUnits[su].dumpAll(this)); if (!Fast) { CalculateDepths(); CalculateHeights(); @@ -271,7 +271,7 @@ #ifndef NDEBUG if (PredSU->NumSuccsLeft < 0) { cerr << "*** Scheduling failed! ***\n"; - PredSU->dump(DAG); + PredSU->dump(this); cerr << " has been released too many times!\n"; assert(0); } @@ -301,7 +301,7 @@ /// the Available queue. void ScheduleDAGRRList::ScheduleNodeBottomUp(SUnit *SU, unsigned CurCycle) { DOUT << "*** Scheduling [" << CurCycle << "]: "; - DEBUG(SU->dump(DAG)); + DEBUG(SU->dump(this)); SU->Cycle = CurCycle; AvailableQueue->ScheduledNode(SU); @@ -368,7 +368,7 @@ /// its predecessor states to reflect the change. void ScheduleDAGRRList::UnscheduleNodeBottomUp(SUnit *SU) { DOUT << "*** Unscheduling [" << SU->Cycle << "]: "; - DEBUG(SU->dump(DAG)); + DEBUG(SU->dump(this)); AvailableQueue->UnscheduledNode(SU); @@ -1084,14 +1084,14 @@ } if (!AnyNotSched) cerr << "*** List scheduling failed! ***\n"; - SUnits[i].dump(DAG); + SUnits[i].dump(this); cerr << "has not been scheduled!\n"; AnyNotSched = true; } if (SUnits[i].NumSuccsLeft != 0) { if (!AnyNotSched) cerr << "*** List scheduling failed! ***\n"; - SUnits[i].dump(DAG); + SUnits[i].dump(this); cerr << "has successors left!\n"; AnyNotSched = true; } @@ -1117,7 +1117,7 @@ #ifndef NDEBUG if (SuccSU->NumPredsLeft < 0) { cerr << "*** Scheduling failed! ***\n"; - SuccSU->dump(DAG); + SuccSU->dump(this); cerr << " has been released too many times!\n"; assert(0); } @@ -1148,7 +1148,7 @@ /// the Available queue. void ScheduleDAGRRList::ScheduleNodeTopDown(SUnit *SU, unsigned CurCycle) { DOUT << "*** Scheduling [" << CurCycle << "]: "; - DEBUG(SU->dump(DAG)); + DEBUG(SU->dump(this)); SU->Cycle = CurCycle; Sequence.push_back(SU); @@ -1213,14 +1213,14 @@ } if (!AnyNotSched) cerr << "*** List scheduling failed! ***\n"; - SUnits[i].dump(DAG); + SUnits[i].dump(this); cerr << "has not been scheduled!\n"; AnyNotSched = true; } if (SUnits[i].NumPredsLeft != 0) { if (!AnyNotSched) cerr << "*** List scheduling failed! ***\n"; - SUnits[i].dump(DAG); + SUnits[i].dump(this); cerr << "has predecessors left!\n"; AnyNotSched = true; } From evan.cheng at apple.com Mon Nov 17 20:08:31 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 17 Nov 2008 18:08:31 -0800 Subject: [llvm-commits] discouraging use of x86_64 R12 and R13 In-Reply-To: <7D8710B0-A32E-4372-88F9-594568443D5D@apple.com> References: <7D8710B0-A32E-4372-88F9-594568443D5D@apple.com> Message-ID: <21E41E9F-98D9-4409-BDFE-BEA77709E542@apple.com> On Nov 17, 2008, at 4:08 PM, Stuart Hastings wrote: > A trivial patch for a mild (and unproven) performance improvement. > (> ) > > The x86_64 R12 and R13 register encodings are related to the RBP and > RSP encodings, and thus require slightly longer instructions than the > other R8..R15 registers. Specifically, just like [RBP], the X86_64 > cannot encode [R12] directly; this is expressed as [R12+0]. In like > manner, [R13] resembles [RSP], and requires an SIB byte. > > Since R14 and R15 don't have these drawbacks, here is a patch for LLVM > to prefer them over R12 & R13. By "prefer," we really mean "allocate > R14 and R15 first." > > This has passed DejaGNU with no regressions, and some experimentation > with a hacky testcase suggests that it works, at least for 32-bit > integers. I haven't tested all the permutations (bytes, shorts, long > longs). > > If this is acceptable, would someone kindly commit this? Thanks. Comments below. > > > stuart > > Index: llvm.regorder/lib/Target/X86/X86RegisterInfo.td > =================================================================== > --- llvm.regorder/lib/Target/X86/X86RegisterInfo.td (revision 59450) > +++ llvm.regorder/lib/Target/X86/X86RegisterInfo.td (working copy) > @@ -181,9 +181,9 @@ def x86_subreg_16bit : PatLeaf<(i32 2) > def x86_subreg_32bit : PatLeaf<(i32 3)>; > You don't need to touch these SubRegSet defs. They have nothing to do with allocation orders. Otherwise, the patch is fine. Please avoid inlining the patch though. It makes it difficult to extract it out of the email message. Thanks, Evan > def : SubRegSet<1, [AX, CX, DX, BX, SP, BP, SI, DI, > - R8W, R9W, R10W, R11W, R12W, R13W, R14W, R15W], > + R8W, R9W, R10W, R11W, R14W, R15W, R12W, R13W], > [AL, CL, DL, BL, SPL, BPL, SIL, DIL, > - R8B, R9B, R10B, R11B, R12B, R13B, R14B, R15B]>; > + R8B, R9B, R10B, R11B, R14B, R15B, R12B, R13B]>; > > // It's unclear if this subreg set is safe, given that not all > registers > // in the class have an 'H' subreg. > @@ -191,30 +191,30 @@ def : SubRegSet<1, [AX, CX, DX, BX, SP, > // [AH, CH, DH, BH]>; > > def : SubRegSet<1, [EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI, > - R8D, R9D, R10D, R11D, R12D, R13D, R14D, R15D], > + R8D, R9D, R10D, R11D, R14D, R15D, R12D, R13D], > [AL, CL, DL, BL, SPL, BPL, SIL, DIL, > - R8B, R9B, R10B, R11B, R12B, R13B, R14B, R15B]>; > + R8B, R9B, R10B, R11B, R14B, R15B, R12B, R13B]>; > > def : SubRegSet<2, [EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI, > - R8D, R9D, R10D, R11D, R12D, R13D, R14D, R15D], > + R8D, R9D, R10D, R11D, R14D, R15D, R12D, R13D], > [AX, CX, DX, BX, SP, BP, SI, DI, > - R8W, R9W, R10W, R11W, R12W, R13W, R14W, R15W]>; > + R8W, R9W, R10W, R11W, R14W, R15W, R12W, R13W]>; > > > def : SubRegSet<1, [RAX, RCX, RDX, RBX, RSP, RBP, RSI, RDI, > - R8, R9, R10, R11, R12, R13, R14, R15], > + R8, R9, R10, R11, R14, R15, R12, R13], > [AL, CL, DL, BL, SPL, BPL, SIL, DIL, > - R8B, R9B, R10B, R11B, R12B, R13B, R14B, R15B]>; > + R8B, R9B, R10B, R11B, R14B, R15B, R12B, R13B]>; > > def : SubRegSet<2, [RAX, RCX, RDX, RBX, RSP, RBP, RSI, RDI, > - R8, R9, R10, R11, R12, R13, R14, R15], > + R8, R9, R10, R11, R14, R15, R12, R13], > [AX, CX, DX, BX, SP, BP, SI, DI, > - R8W, R9W, R10W, R11W, R12W, R13W, R14W, R15W]>; > + R8W, R9W, R10W, R11W, R14W, R15W, R12W, R13W]>; > > def : SubRegSet<3, [RAX, RCX, RDX, RBX, RSP, RBP, RSI, RDI, > - R8, R9, R10, R11, R12, R13, R14, R15], > + R8, R9, R10, R11, R14, R15, R12, R13], > [EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI, > - R8D, R9D, R10D, R11D, R12D, R13D, R14D, R15D]>; > + R8D, R9D, R10D, R11D, R14D, R15D, R12D, R13D]>; > > // > = > = > = > ---------------------------------------------------------------------- > ===// > // Register Class Definitions... now that we have all of the pieces, > define the > @@ -229,7 +229,7 @@ def : SubRegSet<3, [RAX, RCX, RDX, RBX, > // FIXME: Allow AH, CH, DH, BH in 64-mode for non-REX instructions, > def GR8 : RegisterClass<"X86", [i8], 8, > [AL, CL, DL, BL, AH, CH, DH, BH, SIL, DIL, > BPL, SPL, > - R8B, R9B, R10B, R11B, R12B, R13B, R14B, > R15B]> { > + R8B, R9B, R10B, R11B, R14B, R15B, R12B, > R13B]> { > let MethodProtos = [{ > iterator allocation_order_begin(const MachineFunction &MF) const; > iterator allocation_order_end(const MachineFunction &MF) const; > @@ -240,12 +240,12 @@ def GR8 : RegisterClass<"X86", [i8], 8, > static const unsigned X86_GR8_AO_64_fp[] = > {X86::AL, X86::CL, X86::DL, X86::SIL, X86::DIL, > X86::R8B, X86::R9B, X86::R10B, X86::R11B, > - X86::BL, X86::R12B, X86::R13B, X86::R14B, X86::R15B}; > + X86::BL, X86::R14B, X86::R15B, X86::R12B, X86::R13B}; > // If not, just don't allocate SPL. > static const unsigned X86_GR8_AO_64[] = > {X86::AL, X86::CL, X86::DL, X86::SIL, X86::DIL, > X86::R8B, X86::R9B, X86::R10B, X86::R11B, > - X86::BL, X86::R12B, X86::R13B, X86::R14B, X86::R15B, > X86::BPL}; > + X86::BL, X86::R14B, X86::R15B, X86::R12B, X86::R13B, > X86::BPL}; > // In 32-mode, none of the 8-bit registers aliases EBP or ESP. > static const unsigned X86_GR8_AO_32[] = > {X86::AL, X86::CL, X86::DL, X86::AH, X86::CH, X86::DH, > X86::BL, X86::BH}; > @@ -281,7 +281,7 @@ def GR8 : RegisterClass<"X86", [i8], 8, > > def GR16 : RegisterClass<"X86", [i16], 16, > [AX, CX, DX, SI, DI, BX, BP, SP, > - R8W, R9W, R10W, R11W, R12W, R13W, R14W, > R15W]> { > + R8W, R9W, R10W, R11W, R14W, R15W, R12W, > R13W]> { > let SubRegClassList = [GR8]; > let MethodProtos = [{ > iterator allocation_order_begin(const MachineFunction &MF) const; > @@ -293,14 +293,14 @@ def GR16 : RegisterClass<"X86", [i16], 1 > static const unsigned X86_GR16_AO_64_fp[] = > {X86::AX, X86::CX, X86::DX, X86::SI, X86::DI, > X86::R8W, X86::R9W, X86::R10W, X86::R11W, > - X86::BX, X86::R12W, X86::R13W, X86::R14W, X86::R15W}; > + X86::BX, X86::R14W, X86::R15W, X86::R12W, X86::R13W}; > static const unsigned X86_GR16_AO_32_fp[] = > {X86::AX, X86::CX, X86::DX, X86::SI, X86::DI, X86::BX}; > // If not, just don't allocate SPL. > static const unsigned X86_GR16_AO_64[] = > {X86::AX, X86::CX, X86::DX, X86::SI, X86::DI, > X86::R8W, X86::R9W, X86::R10W, X86::R11W, > - X86::BX, X86::R12W, X86::R13W, X86::R14W, X86::R15W, > X86::BP}; > + X86::BX, X86::R14W, X86::R15W, X86::R12W, X86::R13W, > X86::BP}; > static const unsigned X86_GR16_AO_32[] = > {X86::AX, X86::CX, X86::DX, X86::SI, X86::DI, X86::BX, > X86::BP}; > > @@ -345,7 +345,7 @@ def GR16 : RegisterClass<"X86", [i16], 1 > > def GR32 : RegisterClass<"X86", [i32], 32, > [EAX, ECX, EDX, ESI, EDI, EBX, EBP, ESP, > - R8D, R9D, R10D, R11D, R12D, R13D, R14D, > R15D]> { > + R8D, R9D, R10D, R11D, R14D, R15D, R12D, > R13D]> { > let SubRegClassList = [GR8, GR16]; > let MethodProtos = [{ > iterator allocation_order_begin(const MachineFunction &MF) const; > @@ -357,14 +357,14 @@ def GR32 : RegisterClass<"X86", [i32], 3 > static const unsigned X86_GR32_AO_64_fp[] = > {X86::EAX, X86::ECX, X86::EDX, X86::ESI, X86::EDI, > X86::R8D, X86::R9D, X86::R10D, X86::R11D, > - X86::EBX, X86::R12D, X86::R13D, X86::R14D, X86::R15D}; > + X86::EBX, X86::R14D, X86::R15D, X86::R12D, X86::R13D}; > static const unsigned X86_GR32_AO_32_fp[] = > {X86::EAX, X86::ECX, X86::EDX, X86::ESI, X86::EDI, X86::EBX}; > // If not, just don't allocate SPL. > static const unsigned X86_GR32_AO_64[] = > {X86::EAX, X86::ECX, X86::EDX, X86::ESI, X86::EDI, > X86::R8D, X86::R9D, X86::R10D, X86::R11D, > - X86::EBX, X86::R12D, X86::R13D, X86::R14D, X86::R15D, > X86::EBP}; > + X86::EBX, X86::R14D, X86::R15D, X86::R12D, X86::R13D, > X86::EBP}; > static const unsigned X86_GR32_AO_32[] = > {X86::EAX, X86::ECX, X86::EDX, X86::ESI, X86::EDI, X86::EBX, > X86::EBP}; > > @@ -409,7 +409,7 @@ def GR32 : RegisterClass<"X86", [i32], 3 > > def GR64 : RegisterClass<"X86", [i64], 64, > [RAX, RCX, RDX, RSI, RDI, R8, R9, R10, R11, > - RBX, R12, R13, R14, R15, RBP, RSP]> { > + RBX, R14, R15, R12, R13, RBP, RSP]> { > let SubRegClassList = [GR8, GR16, GR32]; > let MethodProtos = [{ > iterator allocation_order_end(const MachineFunction &MF) const; > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From gohman at apple.com Mon Nov 17 20:50:01 2008 From: gohman at apple.com (Dan Gohman) Date: Tue, 18 Nov 2008 02:50:01 -0000 Subject: [llvm-commits] [llvm] r59489 - /llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Message-ID: <200811180250.mAI2o11D030694@zion.cs.uiuc.edu> Author: djg Date: Mon Nov 17 20:50:01 2008 New Revision: 59489 URL: http://llvm.org/viewvc/llvm-project?rev=59489&view=rev Log: Fix a typo in a comment. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp?rev=59489&r1=59488&r2=59489&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Mon Nov 17 20:50:01 2008 @@ -54,7 +54,7 @@ /// PendingQueue - This contains all of the instructions whose operands have /// been issued, but their results are not ready yet (due to the latency of - /// the operation). Once the operands becomes available, the instruction is + /// the operation). Once the operands become available, the instruction is /// added to the AvailableQueue. std::vector PendingQueue; From isanbard at gmail.com Mon Nov 17 23:32:12 2008 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 18 Nov 2008 05:32:12 -0000 Subject: [llvm-commits] [llvm] r59496 - /llvm/trunk/lib/CodeGen/StackProtector.cpp Message-ID: <200811180532.mAI5WCrh003859@zion.cs.uiuc.edu> Author: void Date: Mon Nov 17 23:32:11 2008 New Revision: 59496 URL: http://llvm.org/viewvc/llvm-project?rev=59496&view=rev Log: - Use "moveAfter" instead of "remove/insert" of a basic block. - Use less indentation in coding. - Shorten description. - Update comments. - Move code around Modified: llvm/trunk/lib/CodeGen/StackProtector.cpp Modified: llvm/trunk/lib/CodeGen/StackProtector.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StackProtector.cpp?rev=59496&r1=59495&r2=59496&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/StackProtector.cpp (original) +++ llvm/trunk/lib/CodeGen/StackProtector.cpp Mon Nov 17 23:32:11 2008 @@ -33,8 +33,8 @@ // smashing protection. static cl::opt SSPBufferSize("stack-protector-buffer-size", cl::init(8), - cl::desc("The lower bound for a buffer to be considered for " - "stack smashing protection.")); + cl::desc("Lower bound for a buffer to be considered for " + "stack protection")); namespace { class VISIBILITY_HIDDEN StackProtector : public FunctionPass { @@ -87,6 +87,41 @@ return InsertStackProtectors(); } +/// RequiresStackProtector - Check whether or not this function needs a stack +/// protector based upon the stack protector level. The heuristic we use is to +/// add a guard variable to functions that call alloca, and functions with +/// buffers larger than SSPBufferSize bytes. +bool StackProtector::RequiresStackProtector() const { + if (F->hasFnAttr(Attribute::StackProtectReq)) + return true; + + if (!F->hasFnAttr(Attribute::StackProtect)) + return false; + + const TargetData *TD = TLI->getTargetData(); + + for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) { + BasicBlock *BB = I; + + for (BasicBlock::iterator + II = BB->begin(), IE = BB->end(); II != IE; ++II) + if (AllocaInst *AI = dyn_cast(II)) { + if (AI->isArrayAllocation()) + // This is a call to alloca with a variable size. Emit stack + // protectors. + return true; + + if (const ArrayType *AT = dyn_cast(AI->getAllocatedType())) + // If an array has more than SSPBufferSize bytes of allocated space, + // then we emit stack protectors. + if (SSPBufferSize <= TD->getABITypeSize(AT)) + return true; + } + } + + return false; +} + /// InsertStackProtectors - Insert code into the prologue and epilogue of the /// function. /// @@ -94,77 +129,79 @@ /// - The epilogue checks the value stored in the prologue against the original /// value. It calls __stack_chk_fail if they differ. bool StackProtector::InsertStackProtectors() { - // Loop through the basic blocks that have return instructions. Convert this: - // - // return: - // ... - // ret ... - // - // into this: - // - // return: - // ... - // %1 = load __stack_chk_guard - // %2 = load - // %3 = cmp i1 %1, %2 - // br i1 %3, label %SP_return, label %CallStackCheckFailBlk - // - // SP_return: - // ret ... - // - // CallStackCheckFailBlk: - // call void @__stack_chk_fail() - // unreachable - // BasicBlock *FailBB = 0; // The basic block to jump to if check fails. AllocaInst *AI = 0; // Place on stack that stores the stack guard. Constant *StackGuardVar = 0; // The stack guard variable. for (Function::iterator I = F->begin(), E = F->end(); I != E; ) { - BasicBlock *BB = I; + BasicBlock *BB = I++; - if (ReturnInst *RI = dyn_cast(BB->getTerminator())) { - if (!FailBB) { - // Insert code into the entry block that stores the __stack_chk_guard - // variable onto the stack. - PointerType *PtrTy = PointerType::getUnqual(Type::Int8Ty); - StackGuardVar = M->getOrInsertGlobal("__stack_chk_guard", PtrTy); - - BasicBlock &Entry = F->getEntryBlock(); - Instruction *InsPt = &Entry.front(); - - AI = new AllocaInst(PtrTy, "StackGuardSlot", InsPt); - LoadInst *LI = new LoadInst(StackGuardVar, "StackGuard", false, InsPt); - - Value *Args[] = { LI, AI }; - CallInst:: - Create(Intrinsic::getDeclaration(M, Intrinsic::stackprotector_create), - &Args[0], array_endof(Args), "", InsPt); - - // Create the basic block to jump to when the guard check fails. - FailBB = CreateFailBB(); - } + ReturnInst *RI = dyn_cast(BB->getTerminator()); + if (!RI) continue; - ++I; // Skip to the next block so that we don't resplit the return block. + if (!FailBB) { + // Insert code into the entry block that stores the __stack_chk_guard + // variable onto the stack: + // + // entry: + // StackGuardSlot = alloca i8* + // StackGuard = load __stack_chk_guard + // call void @llvm.stackprotect.create(StackGuard, StackGuardSlot) + // + PointerType *PtrTy = PointerType::getUnqual(Type::Int8Ty); + StackGuardVar = M->getOrInsertGlobal("__stack_chk_guard", PtrTy); + + BasicBlock &Entry = F->getEntryBlock(); + Instruction *InsPt = &Entry.front(); + + AI = new AllocaInst(PtrTy, "StackGuardSlot", InsPt); + LoadInst *LI = new LoadInst(StackGuardVar, "StackGuard", false, InsPt); + + Value *Args[] = { LI, AI }; + CallInst:: + Create(Intrinsic::getDeclaration(M, Intrinsic::stackprotector_create), + &Args[0], array_endof(Args), "", InsPt); - // Split the basic block before the return instruction. - BasicBlock *NewBB = BB->splitBasicBlock(RI, "SP_return"); - - // Move the newly created basic block to the point right after the old - // basic block so that it's in the "fall through" position. - NewBB->removeFromParent(); - F->getBasicBlockList().insert(I, NewBB); - - // Generate the stack protector instructions in the old basic block. - LoadInst *LI1 = new LoadInst(StackGuardVar, "", false, BB); - CallInst *CI = CallInst:: - Create(Intrinsic::getDeclaration(M, Intrinsic::stackprotector_check), - AI, "", BB); - ICmpInst *Cmp = new ICmpInst(CmpInst::ICMP_EQ, CI, LI1, "", BB); - BranchInst::Create(NewBB, FailBB, Cmp, BB); - } else { - ++I; + // Create the basic block to jump to when the guard check fails. + FailBB = CreateFailBB(); } + + // For each block with a return instruction, convert this: + // + // return: + // ... + // ret ... + // + // into this: + // + // return: + // ... + // %1 = load __stack_chk_guard + // %2 = call i8* @llvm.stackprotect.check(StackGuardSlot) + // %3 = cmp i1 %1, %2 + // br i1 %3, label %SP_return, label %CallStackCheckFailBlk + // + // SP_return: + // ret ... + // + // CallStackCheckFailBlk: + // call void @__stack_chk_fail() + // unreachable + + // Split the basic block before the return instruction. + BasicBlock *NewBB = BB->splitBasicBlock(RI, "SP_return"); + + // Move the newly created basic block to the point right after the old basic + // block so that it's in the "fall through" position. + NewBB->moveAfter(BB); + + // Generate the stack protector instructions in the old basic block. + LoadInst *LI = new LoadInst(StackGuardVar, "", false, BB); + CallInst *CI = CallInst:: + Create(Intrinsic::getDeclaration(M, Intrinsic::stackprotector_check), + AI, "", BB); + ICmpInst *Cmp = new ICmpInst(CmpInst::ICMP_EQ, CI, LI, "", BB); + BranchInst::Create(NewBB, FailBB, Cmp, BB); } // Return if we didn't modify any basic blocks. I.e., there are no return @@ -184,39 +221,3 @@ new UnreachableInst(FailBB); return FailBB; } - -/// RequiresStackProtector - Check whether or not this function needs a stack -/// protector based upon the stack protector level. The heuristic we use is to -/// add a guard variable to functions that call alloca, and functions with -/// buffers larger than 8 bytes. -bool StackProtector::RequiresStackProtector() const { - if (F->hasFnAttr(Attribute::StackProtectReq)) - return true; - - if (F->hasFnAttr(Attribute::StackProtect)) { - const TargetData *TD = TLI->getTargetData(); - - for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) { - BasicBlock *BB = I; - - for (BasicBlock::iterator - II = BB->begin(), IE = BB->end(); II != IE; ++II) - if (AllocaInst *AI = dyn_cast(II)) { - if (AI->isArrayAllocation()) - // This is a call to alloca with a variable size. Emit stack - // protectors. - return true; - - if (const ArrayType *AT = dyn_cast(AI->getAllocatedType())) - // If an array has more than 8 bytes of allocated space, then we - // emit stack protectors. - if (SSPBufferSize <= TD->getABITypeSize(AT)) - return true; - } - } - - return false; - } - - return false; -} From wendling at apple.com Mon Nov 17 23:33:03 2008 From: wendling at apple.com (Bill Wendling) Date: Mon, 17 Nov 2008 21:33:03 -0800 Subject: [llvm-commits] [llvm] r58673 - in /llvm/trunk: include/llvm/CodeGen/Passes.h lib/CodeGen/LLVMTargetMachine.cpp lib/CodeGen/StackProtector.cpp In-Reply-To: <5A6368E7-8FA1-40AF-8D90-67F6EDDEC600@apple.com> References: <200811040210.mA42ANXh009663@zion.cs.uiuc.edu> <16e5fdf90811041559n79df52cej45d726133f7d2521@mail.gmail.com> <5A6368E7-8FA1-40AF-8D90-67F6EDDEC600@apple.com> Message-ID: <3DBDD5AE-84D2-4CF6-99FB-E6699F267FE2@apple.com> On Nov 15, 2008, at 10:13 PM, Chris Lattner wrote: > On Nov 4, 2008, at 3:59 PM, Bill Wendling wrote: > >> On Tue, Nov 4, 2008 at 5:28 AM, Chris Lattner >> wrote: >>>> + PM.add(createStackProtectorPass(EnableStackProtector)); >>> >>> Why do you add the pass even when it is not enabled? Have you >>> looked >>> at whether adding this pass ends up breaking analysis chains, and >>> requiring them to be run multiple times? For example, does >>> dominators >>> end up being run more frequently with this? If so, the pass should >>> update dominators instead of invalidating it. >>> >> I looked at --debug-pass=Details with stack protectors and without. >> There doesn't seem to be a difference in the two analyses. I'll test >> more on other programs to make sure. I'm trying to do this late in >> the >> game -- right before DAG conversion -- so that LLVM IR passes won't >> be >> affected too much. > > Ok, thanks. > > Some other comments: > > 1) are there any .ll testcases for the new intrinsics? It seems > that there should be something in test/CodeGen/X86. Is there any > target-specific code for the lowering? If not, putting a test in > test/CodeGen/generic would be even better. > There's no target-specific code for lowering. (YAY!) As far as testcases, the only ones we have are in the llvm-gcc testsuite. But I can craft together some kind of .ll files for our local tests. > 2) does stackprotector_check need to be an intrinsic? Can't it just > be written in LLVM IR directly? > Hmm, perhaps. If the load is marked "volatile", will the optimizer passes refrain from moving it around? That's the only question. Right now the intrinsic is marked as "IntrReadMem", so I'm hoping that passes will leave it alone. >>> Two things: first, use I->getTerminator. Second, why do you make a >>> vector of returns and iterate over the vector? You should be able >>> to >>> handle all of these with one pass over the function without the >>> intermediate vector. Also, F->size() is linear time, so that itself >>> does a pass over the function. >>> >> I simplified the code. But it still looks like modifying the function >> while iterating over it is doing badness (it went into an infinite >> loop on me when I tried it out). What did you have in mind? > > Since you've made many changes to the pass, I'll just review the > whole thing again. I really like the approach and where it > converged to, thanks for working on this! > Sure! :-) > static cl::opt > SSPBufferSize("stack-protector-buffer-size", cl::init(8), > cl::desc("The lower bound for a buffer to be considered > for " > "stack smashing protection.")); > > This is the longest option description in llc --help, please shorten > it a bit. > Okay. > /// RequiresStackProtector - Check whether or not this function > needs a stack > /// protector based upon the stack protector level. The heuristic we > use is to > /// add a guard variable to functions that call alloca, and > functions with > /// buffers larger than 8 bytes. > bool StackProtector::RequiresStackProtector() const { > > It's a minor thing, but I'd prefer this method to be lexically right > after runOnFunction to aid in reading the file from top to bottom. Heh. I prefer it the opposite way (auxiliary methods are placed out of the way), but no big deal. I'll move it. > I don't see "8 bytes" hard coded here, please update the comment. Done. > > // If an array has more than 8 bytes of allocated space, > then we > // emit stack protectors. > if (SSPBufferSize <= TD->getABITypeSize(AT)) > return true; > > Same out of date comment. > Okay. > if (F->hasFnAttr(Attribute::StackProtectReq)) > return true; > > funky indentation. > Okay. > if (F->hasFnAttr(Attribute::StackProtect)) { > ... > } > > return false; > > Please use: > > if (!F->hasFnAttr(Attribute::StackProtect)) > return false; > > to reduce nesting. > Okay. > bool StackProtector::InsertStackProtectors() { > // Loop through the basic blocks that have return instructions. > Convert this: > > This big comment is out of date, please update it. > Alright. > for (Function::iterator I = F->begin(), E = F->end(); I != E; ) { > BasicBlock *BB = I; > > if (ReturnInst *RI = dyn_cast(BB->getTerminator())) { > ... > ++I; // Skip to the next block so that we don't resplit the > return block. > ... > } else { > ++I; > } > } > > I think this loop would be simpler if you wrote it as: > > for (Function::iterator I = F->begin(), E = F->end(); I != E; ) { > BasicBlock *BB = I++; > > ReturnInst *RI = dyn_cast(BB->getTerminator()); > if (!RI) continue; > ... > } > > It reduces nesting and simplifies manipulation of I. > Yeah. Good call. :-) > > // Move the newly created basic block to the point right after > the old > // basic block so that it's in the "fall through" position. > NewBB->removeFromParent(); > F->getBasicBlockList().insert(I, NewBB); > > This is correct, but less efficient than using BB->moveBefore or BB- > >moveAfter. Unlinking and relinking a block has to remove all the > instructions from the function symbol table then reinsert them. > Oh yeah. That's fairly gross. Done! > > Thanks again for working on this Bill! > No probs. :-) -bw From elder at cs.wisc.edu Mon Nov 17 23:51:40 2008 From: elder at cs.wisc.edu (Matt Elder) Date: Mon, 17 Nov 2008 23:51:40 -0600 Subject: [llvm-commits] Patch to lib/Analysis/ConstantFolding.cpp Message-ID: <492257EC.80205@cs.wisc.edu> Probably a small error in ConstantFoldInstruction(). Patch attached. -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: yanchar.patch Url: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20081117/b76f1d49/attachment.pl From clattner at apple.com Tue Nov 18 00:00:09 2008 From: clattner at apple.com (Chris Lattner) Date: Mon, 17 Nov 2008 22:00:09 -0800 Subject: [llvm-commits] [llvm] r58673 - in /llvm/trunk: include/llvm/CodeGen/Passes.h lib/CodeGen/LLVMTargetMachine.cpp lib/CodeGen/StackProtector.cpp In-Reply-To: <3DBDD5AE-84D2-4CF6-99FB-E6699F267FE2@apple.com> References: <200811040210.mA42ANXh009663@zion.cs.uiuc.edu> <16e5fdf90811041559n79df52cej45d726133f7d2521@mail.gmail.com> <5A6368E7-8FA1-40AF-8D90-67F6EDDEC600@apple.com> <3DBDD5AE-84D2-4CF6-99FB-E6699F267FE2@apple.com> Message-ID: <67BEF733-03FE-4BCC-AC11-0D8A03014031@apple.com> On Nov 17, 2008, at 9:33 PM, Bill Wendling wrote: >> Some other comments: >> >> 1) are there any .ll testcases for the new intrinsics? It seems >> that there should be something in test/CodeGen/X86. Is there any >> target-specific code for the lowering? If not, putting a test in >> test/CodeGen/generic would be even better. >> > There's no target-specific code for lowering. (YAY!) As far as > testcases, the only ones we have are in the llvm-gcc testsuite. But > I can craft together some kind of .ll files for our local tests. Cool, just something simple is sufficient. >> 2) does stackprotector_check need to be an intrinsic? Can't it >> just be written in LLVM IR directly? >> > Hmm, perhaps. If the load is marked "volatile", will the optimizer > passes refrain from moving it around? That's the only question. > Right now the intrinsic is marked as "IntrReadMem", so I'm hoping > that passes will leave it alone. IntrReadMem is the same as a non-volatile load. A volatile load would be better. >> Thanks again for working on this Bill! >> > No probs. :-) Thanks Bil! -Chris From kremenek at apple.com Tue Nov 18 00:54:01 2008 From: kremenek at apple.com (Ted Kremenek) Date: Tue, 18 Nov 2008 06:54:01 -0000 Subject: [llvm-commits] [llvm] r59500 - /llvm/tags/checker/checker-129/ Message-ID: <200811180654.mAI6s1jv006874@zion.cs.uiuc.edu> Author: kremenek Date: Tue Nov 18 00:54:01 2008 New Revision: 59500 URL: http://llvm.org/viewvc/llvm-project?rev=59500&view=rev Log: Tagging checker-129. Added: llvm/tags/checker/checker-129/ - copied from r59499, llvm/trunk/ From isanbard at gmail.com Tue Nov 18 01:30:58 2008 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 18 Nov 2008 07:30:58 -0000 Subject: [llvm-commits] [llvm] r59504 - in /llvm/trunk: include/llvm/Intrinsics.td lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp lib/CodeGen/StackProtector.cpp Message-ID: <200811180730.mAI7Uw1K008163@zion.cs.uiuc.edu> Author: void Date: Tue Nov 18 01:30:57 2008 New Revision: 59504 URL: http://llvm.org/viewvc/llvm-project?rev=59504&view=rev Log: Remove the stackprotector_check intrinsic. Use a volatile load instead. Modified: llvm/trunk/include/llvm/Intrinsics.td llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp llvm/trunk/lib/CodeGen/StackProtector.cpp Modified: llvm/trunk/include/llvm/Intrinsics.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Intrinsics.td?rev=59504&r1=59503&r2=59504&view=diff ============================================================================== --- llvm/trunk/include/llvm/Intrinsics.td (original) +++ llvm/trunk/include/llvm/Intrinsics.td Tue Nov 18 01:30:57 2008 @@ -180,14 +180,11 @@ def int_readcyclecounter : Intrinsic<[llvm_i64_ty]>; -// Stack Protector Intrinsics - The stackprotector_create writes the stack guard -// to the correct place on the stack frame. The stackprotector_check reads back -// the stack guard that the stackprotector_create stored. +// Stack Protector Intrinsic - The stackprotector_create writes the stack guard +// to the correct place on the stack frame. def int_stackprotector_create : Intrinsic<[llvm_void_ty], [llvm_ptr_ty, llvm_ptrptr_ty], [IntrWriteMem]>; -def int_stackprotector_check : Intrinsic<[llvm_ptr_ty], [llvm_ptrptr_ty], - [IntrReadMem]>; //===------------------- Standard C Library Intrinsics --------------------===// // Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp?rev=59504&r1=59503&r2=59504&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Tue Nov 18 01:30:57 2008 @@ -4041,19 +4041,6 @@ DAG.setRoot(Result); return 0; } - case Intrinsic::stackprotector_check: { - // Emit code into the DAG to retrieve the stack guard off of the stack. - MachineFunction &MF = DAG.getMachineFunction(); - MachineFrameInfo *MFI = MF.getFrameInfo(); - MVT PtrTy = TLI.getPointerTy(); - - // Load the value stored on the stack. - int FI = MFI->getStackProtectorIndex(); - SDValue FIN = DAG.getFrameIndex(MFI->getStackProtectorIndex(), PtrTy); - setValue(&I, DAG.getLoad(PtrTy, getRoot(), FIN, - PseudoSourceValue::getFixedStack(FI), 0, true)); - return 0; - } case Intrinsic::var_annotation: // Discard annotate attributes return 0; Modified: llvm/trunk/lib/CodeGen/StackProtector.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StackProtector.cpp?rev=59504&r1=59503&r2=59504&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/StackProtector.cpp (original) +++ llvm/trunk/lib/CodeGen/StackProtector.cpp Tue Nov 18 01:30:57 2008 @@ -177,7 +177,7 @@ // return: // ... // %1 = load __stack_chk_guard - // %2 = call i8* @llvm.stackprotect.check(StackGuardSlot) + // %2 = load StackGuardSlot // %3 = cmp i1 %1, %2 // br i1 %3, label %SP_return, label %CallStackCheckFailBlk // @@ -196,11 +196,9 @@ NewBB->moveAfter(BB); // Generate the stack protector instructions in the old basic block. - LoadInst *LI = new LoadInst(StackGuardVar, "", false, BB); - CallInst *CI = CallInst:: - Create(Intrinsic::getDeclaration(M, Intrinsic::stackprotector_check), - AI, "", BB); - ICmpInst *Cmp = new ICmpInst(CmpInst::ICMP_EQ, CI, LI, "", BB); + LoadInst *LI1 = new LoadInst(StackGuardVar, "", false, BB); + LoadInst *LI2 = new LoadInst(AI, "", true, BB); + ICmpInst *Cmp = new ICmpInst(CmpInst::ICMP_EQ, LI1, LI2, "", BB); BranchInst::Create(NewBB, FailBB, Cmp, BB); } From wendling at apple.com Tue Nov 18 01:31:22 2008 From: wendling at apple.com (Bill Wendling) Date: Mon, 17 Nov 2008 23:31:22 -0800 Subject: [llvm-commits] [llvm] r58673 - in /llvm/trunk: include/llvm/CodeGen/Passes.h lib/CodeGen/LLVMTargetMachine.cpp lib/CodeGen/StackProtector.cpp In-Reply-To: <67BEF733-03FE-4BCC-AC11-0D8A03014031@apple.com> References: <200811040210.mA42ANXh009663@zion.cs.uiuc.edu> <16e5fdf90811041559n79df52cej45d726133f7d2521@mail.gmail.com> <5A6368E7-8FA1-40AF-8D90-67F6EDDEC600@apple.com> <3DBDD5AE-84D2-4CF6-99FB-E6699F267FE2@apple.com> <67BEF733-03FE-4BCC-AC11-0D8A03014031@apple.com> Message-ID: <5BD9CD2A-10E0-4A31-BCDE-2A1692080EAC@apple.com> On Nov 17, 2008, at 10:00 PM, Chris Lattner wrote: >> Hmm, perhaps. If the load is marked "volatile", will the optimizer >> passes refrain from moving it around? That's the only question. >> Right now the intrinsic is marked as "IntrReadMem", so I'm hoping >> that passes will leave it alone. > > IntrReadMem is the same as a non-volatile load. A volatile load would > be better. > >> Sounds good! Thanks for catching that. :-) -bw From isanbard at gmail.com Tue Nov 18 01:34:50 2008 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 18 Nov 2008 07:34:50 -0000 Subject: [llvm-commits] [llvm] r59505 - /llvm/trunk/test/CodeGen/Generic/stack-protector.ll Message-ID: <200811180734.mAI7YoP5008300@zion.cs.uiuc.edu> Author: void Date: Tue Nov 18 01:34:50 2008 New Revision: 59505 URL: http://llvm.org/viewvc/llvm-project?rev=59505&view=rev Log: A simple test for stack protectors. This should be valid on all platforms. Added: llvm/trunk/test/CodeGen/Generic/stack-protector.ll Added: llvm/trunk/test/CodeGen/Generic/stack-protector.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Generic/stack-protector.ll?rev=59505&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/Generic/stack-protector.ll (added) +++ llvm/trunk/test/CodeGen/Generic/stack-protector.ll Tue Nov 18 01:34:50 2008 @@ -0,0 +1,25 @@ +; RUN: llvm-as < %s | llc -o - | grep {__stack_chk_guard} +; RUN: llvm-as < %s | llc -o - | grep {__stack_chk_fail} + +@"\01LC" = internal constant [11 x i8] c"buf == %s\0A\00" ; <[11 x i8]*> [#uses=1] + +define void @test(i8* %a) nounwind ssp { +entry: + %a_addr = alloca i8* ; [#uses=2] + %buf = alloca [8 x i8] ; <[8 x i8]*> [#uses=2] + %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] + store i8* %a, i8** %a_addr + %buf1 = bitcast [8 x i8]* %buf to i8* ; [#uses=1] + %0 = load i8** %a_addr, align 4 ; [#uses=1] + %1 = call i8* @strcpy(i8* %buf1, i8* %0) nounwind ; [#uses=0] + %buf2 = bitcast [8 x i8]* %buf to i8* ; [#uses=1] + %2 = call i32 (i8*, ...)* @printf(i8* getelementptr ([11 x i8]* @"\01LC", i32 0, i32 0), i8* %buf2) nounwind ; [#uses=0] + br label %return + +return: ; preds = %entry + ret void +} + +declare i8* @strcpy(i8*, i8*) nounwind + +declare i32 @printf(i8*, ...) nounwind From baldrick at free.fr Tue Nov 18 03:15:07 2008 From: baldrick at free.fr (Duncan Sands) Date: Tue, 18 Nov 2008 09:15:07 -0000 Subject: [llvm-commits] [llvm] r59513 - in /llvm/trunk: lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp lib/CodeGen/SelectionDAG/LegalizeTypes.h test/CodeGen/XCore/cos.ll test/CodeGen/XCore/exp.ll test/CodeGen/XCore/exp2.ll test/CodeGen/XCore/fneg.ll test/CodeGen/XCore/log.ll test/CodeGen/XCore/log10.ll test/CodeGen/XCore/log2.ll test/CodeGen/XCore/sin.ll test/CodeGen/XCore/sqrt.ll Message-ID: <200811180915.mAI9F8vf021413@zion.cs.uiuc.edu> Author: baldrick Date: Tue Nov 18 03:15:03 2008 New Revision: 59513 URL: http://llvm.org/viewvc/llvm-project?rev=59513&view=rev Log: Reapply r59464, this time using the correct type when softening FNEG. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h llvm/trunk/test/CodeGen/XCore/cos.ll llvm/trunk/test/CodeGen/XCore/exp.ll llvm/trunk/test/CodeGen/XCore/exp2.ll llvm/trunk/test/CodeGen/XCore/fneg.ll llvm/trunk/test/CodeGen/XCore/log.ll llvm/trunk/test/CodeGen/XCore/log10.ll llvm/trunk/test/CodeGen/XCore/log2.ll llvm/trunk/test/CodeGen/XCore/sin.ll llvm/trunk/test/CodeGen/XCore/sqrt.ll Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp?rev=59513&r1=59512&r2=59513&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp Tue Nov 18 03:15:03 2008 @@ -61,14 +61,28 @@ break; case ISD::FABS: R = SoftenFloatRes_FABS(N); break; case ISD::FADD: R = SoftenFloatRes_FADD(N); break; + case ISD::FCEIL: R = SoftenFloatRes_FCEIL(N); break; case ISD::FCOPYSIGN: R = SoftenFloatRes_FCOPYSIGN(N); break; + case ISD::FCOS: R = SoftenFloatRes_FCOS(N); break; case ISD::FDIV: R = SoftenFloatRes_FDIV(N); break; + case ISD::FEXP: R = SoftenFloatRes_FEXP(N); break; + case ISD::FEXP2: R = SoftenFloatRes_FEXP2(N); break; + case ISD::FFLOOR: R = SoftenFloatRes_FFLOOR(N); break; + case ISD::FLOG: R = SoftenFloatRes_FLOG(N); break; + case ISD::FLOG2: R = SoftenFloatRes_FLOG2(N); break; + case ISD::FLOG10: R = SoftenFloatRes_FLOG10(N); break; case ISD::FMUL: R = SoftenFloatRes_FMUL(N); break; + case ISD::FNEARBYINT: R = SoftenFloatRes_FNEARBYINT(N); break; + case ISD::FNEG: R = SoftenFloatRes_FNEG(N); break; case ISD::FP_EXTEND: R = SoftenFloatRes_FP_EXTEND(N); break; case ISD::FP_ROUND: R = SoftenFloatRes_FP_ROUND(N); break; case ISD::FPOW: R = SoftenFloatRes_FPOW(N); break; case ISD::FPOWI: R = SoftenFloatRes_FPOWI(N); break; + case ISD::FRINT: R = SoftenFloatRes_FRINT(N); break; + case ISD::FSIN: R = SoftenFloatRes_FSIN(N); break; + case ISD::FSQRT: R = SoftenFloatRes_FSQRT(N); break; case ISD::FSUB: R = SoftenFloatRes_FSUB(N); break; + case ISD::FTRUNC: R = SoftenFloatRes_FTRUNC(N); break; case ISD::LOAD: R = SoftenFloatRes_LOAD(N); break; case ISD::SELECT: R = SoftenFloatRes_SELECT(N); break; case ISD::SELECT_CC: R = SoftenFloatRes_SELECT_CC(N); break; @@ -103,7 +117,7 @@ unsigned Size = NVT.getSizeInBits(); // Mask = ~(1 << (Size-1)) - SDValue Mask = DAG.getConstant(APInt::getAllOnesValue(Size).clear(Size-1), + SDValue Mask = DAG.getConstant(APInt::getAllOnesValue(Size).clear(Size-1), NVT); SDValue Op = GetSoftenedFloat(N->getOperand(0)); return DAG.getNode(ISD::AND, NVT, Op, Mask); @@ -121,6 +135,17 @@ NVT, Ops, 2, false); } +SDValue DAGTypeLegalizer::SoftenFloatRes_FCEIL(SDNode *N) { + MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); + SDValue Op = GetSoftenedFloat(N->getOperand(0)); + return MakeLibCall(GetFPLibCall(N->getValueType(0), + RTLIB::CEIL_F32, + RTLIB::CEIL_F64, + RTLIB::CEIL_F80, + RTLIB::CEIL_PPCF128), + NVT, &Op, 1, false); +} + SDValue DAGTypeLegalizer::SoftenFloatRes_FCOPYSIGN(SDNode *N) { SDValue LHS = GetSoftenedFloat(N->getOperand(0)); SDValue RHS = BitConvertToInteger(N->getOperand(1)); @@ -160,6 +185,17 @@ return DAG.getNode(ISD::OR, LVT, LHS, SignBit); } +SDValue DAGTypeLegalizer::SoftenFloatRes_FCOS(SDNode *N) { + MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); + SDValue Op = GetSoftenedFloat(N->getOperand(0)); + return MakeLibCall(GetFPLibCall(N->getValueType(0), + RTLIB::COS_F32, + RTLIB::COS_F64, + RTLIB::COS_F80, + RTLIB::COS_PPCF128), + NVT, &Op, 1, false); +} + SDValue DAGTypeLegalizer::SoftenFloatRes_FDIV(SDNode *N) { MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)), @@ -172,6 +208,72 @@ NVT, Ops, 2, false); } +SDValue DAGTypeLegalizer::SoftenFloatRes_FEXP(SDNode *N) { + MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); + SDValue Op = GetSoftenedFloat(N->getOperand(0)); + return MakeLibCall(GetFPLibCall(N->getValueType(0), + RTLIB::EXP_F32, + RTLIB::EXP_F64, + RTLIB::EXP_F80, + RTLIB::EXP_PPCF128), + NVT, &Op, 1, false); +} + +SDValue DAGTypeLegalizer::SoftenFloatRes_FEXP2(SDNode *N) { + MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); + SDValue Op = GetSoftenedFloat(N->getOperand(0)); + return MakeLibCall(GetFPLibCall(N->getValueType(0), + RTLIB::EXP2_F32, + RTLIB::EXP2_F64, + RTLIB::EXP2_F80, + RTLIB::EXP2_PPCF128), + NVT, &Op, 1, false); +} + +SDValue DAGTypeLegalizer::SoftenFloatRes_FFLOOR(SDNode *N) { + MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); + SDValue Op = GetSoftenedFloat(N->getOperand(0)); + return MakeLibCall(GetFPLibCall(N->getValueType(0), + RTLIB::FLOOR_F32, + RTLIB::FLOOR_F64, + RTLIB::FLOOR_F80, + RTLIB::FLOOR_PPCF128), + NVT, &Op, 1, false); +} + +SDValue DAGTypeLegalizer::SoftenFloatRes_FLOG(SDNode *N) { + MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); + SDValue Op = GetSoftenedFloat(N->getOperand(0)); + return MakeLibCall(GetFPLibCall(N->getValueType(0), + RTLIB::LOG_F32, + RTLIB::LOG_F64, + RTLIB::LOG_F80, + RTLIB::LOG_PPCF128), + NVT, &Op, 1, false); +} + +SDValue DAGTypeLegalizer::SoftenFloatRes_FLOG2(SDNode *N) { + MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); + SDValue Op = GetSoftenedFloat(N->getOperand(0)); + return MakeLibCall(GetFPLibCall(N->getValueType(0), + RTLIB::LOG2_F32, + RTLIB::LOG2_F64, + RTLIB::LOG2_F80, + RTLIB::LOG2_PPCF128), + NVT, &Op, 1, false); +} + +SDValue DAGTypeLegalizer::SoftenFloatRes_FLOG10(SDNode *N) { + MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); + SDValue Op = GetSoftenedFloat(N->getOperand(0)); + return MakeLibCall(GetFPLibCall(N->getValueType(0), + RTLIB::LOG10_F32, + RTLIB::LOG10_F64, + RTLIB::LOG10_F80, + RTLIB::LOG10_PPCF128), + NVT, &Op, 1, false); +} + SDValue DAGTypeLegalizer::SoftenFloatRes_FMUL(SDNode *N) { MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)), @@ -184,6 +286,30 @@ NVT, Ops, 2, false); } +SDValue DAGTypeLegalizer::SoftenFloatRes_FNEARBYINT(SDNode *N) { + MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); + SDValue Op = GetSoftenedFloat(N->getOperand(0)); + return MakeLibCall(GetFPLibCall(N->getValueType(0), + RTLIB::NEARBYINT_F32, + RTLIB::NEARBYINT_F64, + RTLIB::NEARBYINT_F80, + RTLIB::NEARBYINT_PPCF128), + NVT, &Op, 1, false); +} + +SDValue DAGTypeLegalizer::SoftenFloatRes_FNEG(SDNode *N) { + MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); + // Expand Y = FNEG(X) -> Y = SUB -0.0, X + SDValue Ops[2] = { DAG.getConstantFP(-0.0, N->getValueType(0)), + GetSoftenedFloat(N->getOperand(0)) }; + return MakeLibCall(GetFPLibCall(N->getValueType(0), + RTLIB::SUB_F32, + RTLIB::SUB_F64, + RTLIB::SUB_F80, + RTLIB::SUB_PPCF128), + NVT, Ops, 2, false); +} + SDValue DAGTypeLegalizer::SoftenFloatRes_FP_EXTEND(SDNode *N) { MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); SDValue Op = N->getOperand(0); @@ -225,6 +351,39 @@ NVT, Ops, 2, false); } +SDValue DAGTypeLegalizer::SoftenFloatRes_FRINT(SDNode *N) { + MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); + SDValue Op = GetSoftenedFloat(N->getOperand(0)); + return MakeLibCall(GetFPLibCall(N->getValueType(0), + RTLIB::RINT_F32, + RTLIB::RINT_F64, + RTLIB::RINT_F80, + RTLIB::RINT_PPCF128), + NVT, &Op, 1, false); +} + +SDValue DAGTypeLegalizer::SoftenFloatRes_FSIN(SDNode *N) { + MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); + SDValue Op = GetSoftenedFloat(N->getOperand(0)); + return MakeLibCall(GetFPLibCall(N->getValueType(0), + RTLIB::SIN_F32, + RTLIB::SIN_F64, + RTLIB::SIN_F80, + RTLIB::SIN_PPCF128), + NVT, &Op, 1, false); +} + +SDValue DAGTypeLegalizer::SoftenFloatRes_FSQRT(SDNode *N) { + MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); + SDValue Op = GetSoftenedFloat(N->getOperand(0)); + return MakeLibCall(GetFPLibCall(N->getValueType(0), + RTLIB::SQRT_F32, + RTLIB::SQRT_F64, + RTLIB::SQRT_F80, + RTLIB::SQRT_PPCF128), + NVT, &Op, 1, false); +} + SDValue DAGTypeLegalizer::SoftenFloatRes_FSUB(SDNode *N) { MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)), @@ -237,6 +396,17 @@ NVT, Ops, 2, false); } +SDValue DAGTypeLegalizer::SoftenFloatRes_FTRUNC(SDNode *N) { + MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); + SDValue Op = GetSoftenedFloat(N->getOperand(0)); + return MakeLibCall(GetFPLibCall(N->getValueType(0), + RTLIB::TRUNC_F32, + RTLIB::TRUNC_F64, + RTLIB::TRUNC_F80, + RTLIB::TRUNC_PPCF128), + NVT, &Op, 1, false); +} + SDValue DAGTypeLegalizer::SoftenFloatRes_LOAD(SDNode *N) { LoadSDNode *L = cast(N); MVT VT = N->getValueType(0); @@ -607,7 +777,7 @@ case ISD::FPOW: ExpandFloatRes_FPOW(N, Lo, Hi); break; case ISD::FPOWI: ExpandFloatRes_FPOWI(N, Lo, Hi); break; case ISD::FRINT: ExpandFloatRes_FRINT(N, Lo, Hi); break; - case ISD::FSIN: ExpandFloatRes_FABS(N, Lo, Hi); break; + case ISD::FSIN: ExpandFloatRes_FSIN(N, Lo, Hi); break; case ISD::FSQRT: ExpandFloatRes_FSQRT(N, Lo, Hi); break; case ISD::FSUB: ExpandFloatRes_FSUB(N, Lo, Hi); break; case ISD::FTRUNC: ExpandFloatRes_FTRUNC(N, Lo, Hi); break; @@ -926,14 +1096,14 @@ // though. if (SrcVT.bitsLE(MVT::i32)) { // The integer can be represented exactly in an f64. - Src = DAG.getNode(isSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, + Src = DAG.getNode(isSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, MVT::i32, Src); Lo = DAG.getConstantFP(APFloat(APInt(NVT.getSizeInBits(), 0)), NVT); Hi = DAG.getNode(ISD::SINT_TO_FP, NVT, Src); } else { RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; if (SrcVT.bitsLE(MVT::i64)) { - Src = DAG.getNode(isSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, + Src = DAG.getNode(isSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, MVT::i64, Src); LC = RTLIB::SINTTOFP_I64_PPCF128; } else if (SrcVT.bitsLE(MVT::i128)) { Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h?rev=59513&r1=59512&r2=59513&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h Tue Nov 18 03:15:03 2008 @@ -351,14 +351,28 @@ SDValue SoftenFloatRes_ConstantFP(ConstantFPSDNode *N); SDValue SoftenFloatRes_FABS(SDNode *N); SDValue SoftenFloatRes_FADD(SDNode *N); + SDValue SoftenFloatRes_FCEIL(SDNode *N); SDValue SoftenFloatRes_FCOPYSIGN(SDNode *N); + SDValue SoftenFloatRes_FCOS(SDNode *N); SDValue SoftenFloatRes_FDIV(SDNode *N); + SDValue SoftenFloatRes_FEXP(SDNode *N); + SDValue SoftenFloatRes_FEXP2(SDNode *N); + SDValue SoftenFloatRes_FFLOOR(SDNode *N); + SDValue SoftenFloatRes_FLOG(SDNode *N); + SDValue SoftenFloatRes_FLOG2(SDNode *N); + SDValue SoftenFloatRes_FLOG10(SDNode *N); SDValue SoftenFloatRes_FMUL(SDNode *N); + SDValue SoftenFloatRes_FNEARBYINT(SDNode *N); + SDValue SoftenFloatRes_FNEG(SDNode *N); SDValue SoftenFloatRes_FP_EXTEND(SDNode *N); SDValue SoftenFloatRes_FP_ROUND(SDNode *N); SDValue SoftenFloatRes_FPOW(SDNode *N); SDValue SoftenFloatRes_FPOWI(SDNode *N); + SDValue SoftenFloatRes_FRINT(SDNode *N); + SDValue SoftenFloatRes_FSIN(SDNode *N); + SDValue SoftenFloatRes_FSQRT(SDNode *N); SDValue SoftenFloatRes_FSUB(SDNode *N); + SDValue SoftenFloatRes_FTRUNC(SDNode *N); SDValue SoftenFloatRes_LOAD(SDNode *N); SDValue SoftenFloatRes_SELECT(SDNode *N); SDValue SoftenFloatRes_SELECT_CC(SDNode *N); Modified: llvm/trunk/test/CodeGen/XCore/cos.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/XCore/cos.ll?rev=59513&r1=59512&r2=59513&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/XCore/cos.ll (original) +++ llvm/trunk/test/CodeGen/XCore/cos.ll Tue Nov 18 03:15:03 2008 @@ -1,7 +1,6 @@ ; RUN: llvm-as < %s | llc -march=xcore > %t1.s ; RUN: grep "bl cosf" %t1.s | count 1 ; RUN: grep "bl cos" %t1.s | count 2 -; XFAIL: * declare double @llvm.cos.f64(double) define double @test(double %F) { Modified: llvm/trunk/test/CodeGen/XCore/exp.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/XCore/exp.ll?rev=59513&r1=59512&r2=59513&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/XCore/exp.ll (original) +++ llvm/trunk/test/CodeGen/XCore/exp.ll Tue Nov 18 03:15:03 2008 @@ -1,7 +1,6 @@ ; RUN: llvm-as < %s | llc -march=xcore > %t1.s ; RUN: grep "bl expf" %t1.s | count 1 ; RUN: grep "bl exp" %t1.s | count 2 -; XFAIL: * declare double @llvm.exp.f64(double) define double @test(double %F) { Modified: llvm/trunk/test/CodeGen/XCore/exp2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/XCore/exp2.ll?rev=59513&r1=59512&r2=59513&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/XCore/exp2.ll (original) +++ llvm/trunk/test/CodeGen/XCore/exp2.ll Tue Nov 18 03:15:03 2008 @@ -1,7 +1,6 @@ ; RUN: llvm-as < %s | llc -march=xcore > %t1.s ; RUN: grep "bl exp2f" %t1.s | count 1 ; RUN: grep "bl exp2" %t1.s | count 2 -; XFAIL: * declare double @llvm.exp2.f64(double) define double @test(double %F) { Modified: llvm/trunk/test/CodeGen/XCore/fneg.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/XCore/fneg.ll?rev=59513&r1=59512&r2=59513&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/XCore/fneg.ll (original) +++ llvm/trunk/test/CodeGen/XCore/fneg.ll Tue Nov 18 03:15:03 2008 @@ -1,6 +1,5 @@ ; RUN: llvm-as < %s | llc -march=xcore > %t1.s ; RUN: grep "bl __subdf3" %t1.s | count 1 -; XFAIL: * define i1 @test(double %F) nounwind { entry: %0 = sub double -0.000000e+00, %F Modified: llvm/trunk/test/CodeGen/XCore/log.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/XCore/log.ll?rev=59513&r1=59512&r2=59513&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/XCore/log.ll (original) +++ llvm/trunk/test/CodeGen/XCore/log.ll Tue Nov 18 03:15:03 2008 @@ -1,7 +1,6 @@ ; RUN: llvm-as < %s | llc -march=xcore > %t1.s ; RUN: grep "bl logf" %t1.s | count 1 ; RUN: grep "bl log" %t1.s | count 2 -; XFAIL: * declare double @llvm.log.f64(double) define double @test(double %F) { Modified: llvm/trunk/test/CodeGen/XCore/log10.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/XCore/log10.ll?rev=59513&r1=59512&r2=59513&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/XCore/log10.ll (original) +++ llvm/trunk/test/CodeGen/XCore/log10.ll Tue Nov 18 03:15:03 2008 @@ -1,7 +1,6 @@ ; RUN: llvm-as < %s | llc -march=xcore > %t1.s ; RUN: grep "bl log10f" %t1.s | count 1 ; RUN: grep "bl log10" %t1.s | count 2 -; XFAIL: * declare double @llvm.log10.f64(double) define double @test(double %F) { Modified: llvm/trunk/test/CodeGen/XCore/log2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/XCore/log2.ll?rev=59513&r1=59512&r2=59513&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/XCore/log2.ll (original) +++ llvm/trunk/test/CodeGen/XCore/log2.ll Tue Nov 18 03:15:03 2008 @@ -1,7 +1,6 @@ ; RUN: llvm-as < %s | llc -march=xcore > %t1.s ; RUN: grep "bl log2f" %t1.s | count 1 ; RUN: grep "bl log2" %t1.s | count 2 -; XFAIL: * declare double @llvm.log2.f64(double) define double @test(double %F) { Modified: llvm/trunk/test/CodeGen/XCore/sin.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/XCore/sin.ll?rev=59513&r1=59512&r2=59513&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/XCore/sin.ll (original) +++ llvm/trunk/test/CodeGen/XCore/sin.ll Tue Nov 18 03:15:03 2008 @@ -1,7 +1,6 @@ ; RUN: llvm-as < %s | llc -march=xcore > %t1.s ; RUN: grep "bl sinf" %t1.s | count 1 ; RUN: grep "bl sin" %t1.s | count 2 -; XFAIL: * declare double @llvm.sin.f64(double) define double @test(double %F) { Modified: llvm/trunk/test/CodeGen/XCore/sqrt.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/XCore/sqrt.ll?rev=59513&r1=59512&r2=59513&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/XCore/sqrt.ll (original) +++ llvm/trunk/test/CodeGen/XCore/sqrt.ll Tue Nov 18 03:15:03 2008 @@ -1,7 +1,6 @@ ; RUN: llvm-as < %s | llc -march=xcore > %t1.s ; RUN: grep "bl sqrtf" %t1.s | count 1 ; RUN: grep "bl sqrt" %t1.s | count 2 -; XFAIL: * declare double @llvm.sqrt.f64(double) define double @test(double %F) { From baldrick at free.fr Tue Nov 18 03:16:20 2008 From: baldrick at free.fr (Duncan Sands) Date: Tue, 18 Nov 2008 10:16:20 +0100 Subject: [llvm-commits] [llvm] r59464 - in /llvm/trunk: lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp lib/CodeGen/SelectionDAG/LegalizeTypes.h test/CodeGen/XCore/cos.ll test/CodeGen/XCore/exp.ll test/CodeGen/XCore/exp2.ll test/CodeGen/XCore/fneg.ll test/CodeGen/XCore/log.ll test/CodeGen/XCore/log10.ll test/CodeGen/XCore/log2.ll test/CodeGen/XCore/pow.ll test/CodeGen/XCore/powi.ll test/CodeGen/XCore/sin.ll test/CodeGen/XCore/sqrt.ll In-Reply-To: References: <200811172052.mAHKqd5M018376@zion.cs.uiuc.edu> Message-ID: <200811181016.21269.baldrick@free.fr> Hi Bill, > This is causing a segfault in one of the XCore tests. Please > investigate. thanks for reverting this. I've reapplied it, with a fix. Not sure how I missed this in my (quick) testing. Ciao, Duncan. From baldrick at free.fr Tue Nov 18 04:39:05 2008 From: baldrick at free.fr (Duncan Sands) Date: Tue, 18 Nov 2008 10:39:05 -0000 Subject: [llvm-commits] [llvm] r59515 - /llvm/trunk/lib/Analysis/ScalarEvolution.cpp Message-ID: <200811181039.mAIAd5tT025105@zion.cs.uiuc.edu> Author: baldrick Date: Tue Nov 18 04:39:04 2008 New Revision: 59515 URL: http://llvm.org/viewvc/llvm-project?rev=59515&view=rev Log: Remove unused variable. Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=59515&r1=59514&r2=59515&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original) +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Tue Nov 18 04:39:04 2008 @@ -83,9 +83,6 @@ #include using namespace llvm; -STATISTIC(NumBruteForceEvaluations, - "Number of brute force evaluations needed to " - "calculate high-order polynomial exit values"); STATISTIC(NumArrayLenItCounts, "Number of trip counts computed with array length"); STATISTIC(NumTripCountsComputed, From nicolas.geoffray at lip6.fr Tue Nov 18 04:44:46 2008 From: nicolas.geoffray at lip6.fr (Nicolas Geoffray) Date: Tue, 18 Nov 2008 10:44:46 -0000 Subject: [llvm-commits] [llvm] r59516 - in /llvm/trunk: include/llvm/CodeGen/MachineCodeEmitter.h lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp Message-ID: <200811181044.mAIAilFF025334@zion.cs.uiuc.edu> Author: geoffray Date: Tue Nov 18 04:44:46 2008 New Revision: 59516 URL: http://llvm.org/viewvc/llvm-project?rev=59516&view=rev Log: Implement support for JIT exceptions on X86_64. Relative offsets are encoded on 32 bytes, and the personality function is not encoded as relative. Modified: llvm/trunk/include/llvm/CodeGen/MachineCodeEmitter.h llvm/trunk/lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp Modified: llvm/trunk/include/llvm/CodeGen/MachineCodeEmitter.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineCodeEmitter.h?rev=59516&r1=59515&r2=59516&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/MachineCodeEmitter.h (original) +++ llvm/trunk/include/llvm/CodeGen/MachineCodeEmitter.h Tue Nov 18 04:44:46 2008 @@ -228,12 +228,19 @@ } } - /// emitAt - Emit Value in Addr - void emitAt(uintptr_t *Addr, uintptr_t Value) { + /// emitInt32At - Emit the Int32 Value in Addr. + void emitInt32At(uintptr_t *Addr, uintptr_t Value) { if (Addr >= (uintptr_t*)BufferBegin && Addr < (uintptr_t*)BufferEnd) - (*Addr) = Value; + (*(uint32_t*)Addr) = (uint32_t)Value; } + /// emitInt64At - Emit the Int64 Value in Addr. + void emitInt64At(uintptr_t *Addr, uintptr_t Value) { + if (Addr >= (uintptr_t*)BufferBegin && Addr < (uintptr_t*)BufferEnd) + (*(uint64_t*)Addr) = (uint64_t)Value; + } + + /// emitLabel - Emits a label virtual void emitLabel(uint64_t LabelID) = 0; Modified: llvm/trunk/lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp?rev=59516&r1=59515&r2=59516&view=diff ============================================================================== --- llvm/trunk/lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp (original) +++ llvm/trunk/lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp Tue Nov 18 04:44:46 2008 @@ -89,11 +89,7 @@ // Advance row if new location. if (BaseLabelPtr && LabelID && (BaseLabelID != LabelID || !IsLocal)) { MCE->emitByte(dwarf::DW_CFA_advance_loc4); - if (PointerSize == 8) { - MCE->emitInt64(LabelPtr - BaseLabelPtr); - } else { - MCE->emitInt32(LabelPtr - BaseLabelPtr); - } + MCE->emitInt32(LabelPtr - BaseLabelPtr); BaseLabelID = LabelID; BaseLabelPtr = LabelPtr; @@ -435,46 +431,28 @@ if (!S.BeginLabel) { BeginLabelPtr = (intptr_t)StartFunction; - if (TD->getPointerSize() == sizeof(int32_t)) - MCE->emitInt32(0); - else - MCE->emitInt64(0); + MCE->emitInt32(0); } else { BeginLabelPtr = MCE->getLabelAddress(S.BeginLabel); - if (TD->getPointerSize() == sizeof(int32_t)) - MCE->emitInt32(BeginLabelPtr - (intptr_t)StartFunction); - else - MCE->emitInt64(BeginLabelPtr - (intptr_t)StartFunction); + MCE->emitInt32(BeginLabelPtr - (intptr_t)StartFunction); } // Asm->EOL("Region start"); if (!S.EndLabel) { EndLabelPtr = (intptr_t)EndFunction; - if (TD->getPointerSize() == sizeof(int32_t)) - MCE->emitInt32((intptr_t)EndFunction - BeginLabelPtr); - else - MCE->emitInt64((intptr_t)EndFunction - BeginLabelPtr); + MCE->emitInt32((intptr_t)EndFunction - BeginLabelPtr); } else { EndLabelPtr = MCE->getLabelAddress(S.EndLabel); - if (TD->getPointerSize() == sizeof(int32_t)) - MCE->emitInt32(EndLabelPtr - BeginLabelPtr); - else - MCE->emitInt64(EndLabelPtr - BeginLabelPtr); + MCE->emitInt32(EndLabelPtr - BeginLabelPtr); } //Asm->EOL("Region length"); if (!S.PadLabel) { - if (TD->getPointerSize() == sizeof(int32_t)) - MCE->emitInt32(0); - else - MCE->emitInt64(0); + MCE->emitInt32(0); } else { unsigned PadLabelPtr = MCE->getLabelAddress(S.PadLabel); - if (TD->getPointerSize() == sizeof(int32_t)) - MCE->emitInt32(PadLabelPtr - (intptr_t)StartFunction); - else - MCE->emitInt64(PadLabelPtr - (intptr_t)StartFunction); + MCE->emitInt32(PadLabelPtr - (intptr_t)StartFunction); } // Asm->EOL("Landing pad"); @@ -531,7 +509,7 @@ unsigned char* StartCommonPtr = (unsigned char*)MCE->getCurrentPCValue(); // EH Common Frame header - MCE->allocateSpace(PointerSize, 0); + MCE->allocateSpace(4, 0); unsigned char* FrameCommonBeginPtr = (unsigned char*)MCE->getCurrentPCValue(); MCE->emitInt32((int)0); MCE->emitByte(dwarf::DW_CIE_VERSION); @@ -543,15 +521,12 @@ if (Personality) { MCE->emitULEB128Bytes(7); - // Direct encoding, because we use the function pointer. - MCE->emitByte(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4); - - if (PointerSize == 8) - MCE->emitInt64((intptr_t)Jit.getPointerToGlobal(Personality) - - MCE->getCurrentPCValue()); - else - MCE->emitInt32((intptr_t)Jit.getPointerToGlobal(Personality) - - MCE->getCurrentPCValue()); + // Direct encoding, because we use the function pointer. Not relative, + // because the current PC value may be bigger than the personality + // function pointer. + MCE->emitByte(dwarf::DW_EH_PE_sdata4); + + MCE->emitInt32(((intptr_t)Jit.getPointerToGlobal(Personality))); MCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4); MCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4); @@ -564,9 +539,9 @@ std::vector Moves; RI->getInitialFrameState(Moves); EmitFrameMoves(0, Moves); - MCE->emitAlignment(4); + MCE->emitAlignment(PointerSize); - MCE->emitAt((uintptr_t*)StartCommonPtr, + MCE->emitInt32At((uintptr_t*)StartCommonPtr, (uintptr_t)((unsigned char*)MCE->getCurrentPCValue() - FrameCommonBeginPtr)); @@ -584,18 +559,12 @@ // EH frame header. unsigned char* StartEHPtr = (unsigned char*)MCE->getCurrentPCValue(); - MCE->allocateSpace(PointerSize, 0); + MCE->allocateSpace(4, 0); unsigned char* FrameBeginPtr = (unsigned char*)MCE->getCurrentPCValue(); // FDE CIE Offset - if (PointerSize == 8) { - MCE->emitInt64(FrameBeginPtr - StartCommonPtr); - MCE->emitInt64(StartFunction - (unsigned char*)MCE->getCurrentPCValue()); - MCE->emitInt64(EndFunction - StartFunction); - } else { - MCE->emitInt32(FrameBeginPtr - StartCommonPtr); - MCE->emitInt32(StartFunction - (unsigned char*)MCE->getCurrentPCValue()); - MCE->emitInt32(EndFunction - StartFunction); - } + MCE->emitInt32(FrameBeginPtr - StartCommonPtr); + MCE->emitInt32(StartFunction - (unsigned char*)MCE->getCurrentPCValue()); + MCE->emitInt32(EndFunction - StartFunction); // If there is a personality and landing pads then point to the language // specific data area in the exception table. @@ -603,12 +572,7 @@ MCE->emitULEB128Bytes(4); if (!MMI->getLandingPads().empty()) { - if (PointerSize == 8) - MCE->emitInt64(ExceptionTable - (unsigned char*)MCE->getCurrentPCValue()); - else - MCE->emitInt32(ExceptionTable - (unsigned char*)MCE->getCurrentPCValue()); - } else if (PointerSize == 8) { - MCE->emitInt64((int)0); + MCE->emitInt32(ExceptionTable - (unsigned char*)MCE->getCurrentPCValue()); } else { MCE->emitInt32((int)0); } @@ -620,10 +584,10 @@ // frame. EmitFrameMoves((intptr_t)StartFunction, MMI->getFrameMoves()); - MCE->emitAlignment(4); + MCE->emitAlignment(PointerSize); // Indicate the size of the table - MCE->emitAt((uintptr_t*)StartEHPtr, + MCE->emitInt32At((uintptr_t*)StartEHPtr, (uintptr_t)((unsigned char*)MCE->getCurrentPCValue() - StartEHPtr)); @@ -655,9 +619,11 @@ FinalSize += GetExceptionTableSizeInBytes(&F); const std::vector Personalities = MMI->getPersonalities(); - FinalSize += GetCommonEHFrameSizeInBytes(Personalities[MMI->getPersonalityIndex()]); + FinalSize += + GetCommonEHFrameSizeInBytes(Personalities[MMI->getPersonalityIndex()]); - FinalSize += GetEHFrameSizeInBytes(Personalities[MMI->getPersonalityIndex()], StartFunction); + FinalSize += GetEHFrameSizeInBytes(Personalities[MMI->getPersonalityIndex()], + StartFunction); return FinalSize; } From isanbard at gmail.com Tue Nov 18 04:57:27 2008 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 18 Nov 2008 10:57:27 -0000 Subject: [llvm-commits] [llvm] r59518 - /llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp Message-ID: <200811181057.mAIAvSps025741@zion.cs.uiuc.edu> Author: void Date: Tue Nov 18 04:57:27 2008 New Revision: 59518 URL: http://llvm.org/viewvc/llvm-project?rev=59518&view=rev Log: Cast to remove warning about comparing signed and unsigned. Modified: llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp Modified: llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp?rev=59518&r1=59517&r2=59518&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp Tue Nov 18 04:57:27 2008 @@ -732,7 +732,7 @@ // If the iteration range can be handled by SIToFPInst then use it. APInt Max = APInt::getSignedMaxValue(32); - if (Max.getZExtValue() > abs(intEV - intIV)) + if (Max.getZExtValue() > static_cast(abs(intEV - intIV))) return true; return false; From isanbard at gmail.com Tue Nov 18 05:00:31 2008 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 18 Nov 2008 03:00:31 -0800 Subject: [llvm-commits] [llvm] r59513 - in /llvm/trunk: lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp lib/CodeGen/SelectionDAG/LegalizeTypes.h test/CodeGen/XCore/cos.ll test/CodeGen/XCore/exp.ll test/CodeGen/XCore/exp2.ll test/CodeGen/XCore/fneg.ll test/CodeGen/XCore/log.ll test/CodeGen/XCore/log10.ll test/CodeGen/XCore/log2.ll test/CodeGen/XCore/sin.ll test/CodeGen/XCore/sqrt.ll In-Reply-To: <200811180915.mAI9F8vf021413@zion.cs.uiuc.edu> References: <200811180915.mAI9F8vf021413@zion.cs.uiuc.edu> Message-ID: On Nov 18, 2008, at 1:15 AM, Duncan Sands wrote: > Author: baldrick > Date: Tue Nov 18 03:15:03 2008 > New Revision: 59513 > > URL: http://llvm.org/viewvc/llvm-project?rev=59513&view=rev > Log: > Reapply r59464, this time using the correct type > when softening FNEG. > Thanks, Duncan! -bw From isanbard at gmail.com Tue Nov 18 05:01:34 2008 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 18 Nov 2008 11:01:34 -0000 Subject: [llvm-commits] [llvm] r59519 - in /llvm/trunk: include/llvm/Intrinsics.td lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp lib/CodeGen/StackProtector.cpp Message-ID: <200811181101.mAIB1YQb025875@zion.cs.uiuc.edu> Author: void Date: Tue Nov 18 05:01:33 2008 New Revision: 59519 URL: http://llvm.org/viewvc/llvm-project?rev=59519&view=rev Log: Rename stackprotector_create intrinsic to stackprotector. Modified: llvm/trunk/include/llvm/Intrinsics.td llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp llvm/trunk/lib/CodeGen/StackProtector.cpp Modified: llvm/trunk/include/llvm/Intrinsics.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Intrinsics.td?rev=59519&r1=59518&r2=59519&view=diff ============================================================================== --- llvm/trunk/include/llvm/Intrinsics.td (original) +++ llvm/trunk/include/llvm/Intrinsics.td Tue Nov 18 05:01:33 2008 @@ -180,11 +180,11 @@ def int_readcyclecounter : Intrinsic<[llvm_i64_ty]>; -// Stack Protector Intrinsic - The stackprotector_create writes the stack guard -// to the correct place on the stack frame. -def int_stackprotector_create : Intrinsic<[llvm_void_ty], - [llvm_ptr_ty, llvm_ptrptr_ty], - [IntrWriteMem]>; +// Stack Protector Intrinsic - The stackprotector intrinsic writes the stack +// guard to the correct place on the stack frame. +def int_stackprotector : Intrinsic<[llvm_void_ty], + [llvm_ptr_ty, llvm_ptrptr_ty], + [IntrWriteMem]>; //===------------------- Standard C Library Intrinsics --------------------===// // Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp?rev=59519&r1=59518&r2=59519&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Tue Nov 18 05:01:33 2008 @@ -4019,7 +4019,7 @@ DAG.setRoot(DAG.getNode(ISD::STACKRESTORE, MVT::Other, getRoot(), Tmp)); return 0; } - case Intrinsic::stackprotector_create: { + case Intrinsic::stackprotector: { // Emit code into the DAG to store the stack guard onto the stack. MachineFunction &MF = DAG.getMachineFunction(); MachineFrameInfo *MFI = MF.getFrameInfo(); Modified: llvm/trunk/lib/CodeGen/StackProtector.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StackProtector.cpp?rev=59519&r1=59518&r2=59519&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/StackProtector.cpp (original) +++ llvm/trunk/lib/CodeGen/StackProtector.cpp Tue Nov 18 05:01:33 2008 @@ -159,7 +159,7 @@ Value *Args[] = { LI, AI }; CallInst:: - Create(Intrinsic::getDeclaration(M, Intrinsic::stackprotector_create), + Create(Intrinsic::getDeclaration(M, Intrinsic::stackprotector), &Args[0], array_endof(Args), "", InsPt); // Create the basic block to jump to when the guard check fails. From nicholas at mxc.ca Tue Nov 18 09:10:54 2008 From: nicholas at mxc.ca (Nick Lewycky) Date: Tue, 18 Nov 2008 15:10:54 -0000 Subject: [llvm-commits] [llvm] r59528 - in /llvm/trunk: lib/Analysis/ScalarEvolution.cpp test/Analysis/ScalarEvolution/2008-11-18-LessThanOrEqual.ll test/Analysis/ScalarEvolution/2008-11-18-Stride1.ll test/Analysis/ScalarEvolution/2008-11-18-Stride2.ll Message-ID: <200811181510.mAIFAtVS001882@zion.cs.uiuc.edu> Author: nicholas Date: Tue Nov 18 09:10:54 2008 New Revision: 59528 URL: http://llvm.org/viewvc/llvm-project?rev=59528&view=rev Log: Add a utility function that detects whether a loop is guaranteed to be finite. Use it to safely handle less-than-or-equals-to exit conditions in loops. These also occur when the loop exit branch is exit on true because SCEV inverses the icmp predicate. Use it again to handle non-zero strides, but only with an unsigned comparison in the exit condition. Added: llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-LessThanOrEqual.ll llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride1.ll llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride2.ll Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=59528&r1=59527&r2=59528&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original) +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Tue Nov 18 09:10:54 2008 @@ -1477,7 +1477,7 @@ /// specified less-than comparison will execute. If not computable, return /// UnknownValue. isSigned specifies whether the less-than is signed. SCEVHandle HowManyLessThans(SCEV *LHS, SCEV *RHS, const Loop *L, - bool isSigned); + bool isSigned, bool trueWhenEqual); /// getPredecessorWithUniqueSuccessorForBB - Return a predecessor of BB /// (which may not be an immediate predecessor) which has exactly one @@ -1487,7 +1487,13 @@ /// executesAtLeastOnce - Test whether entry to the loop is protected by /// a conditional between LHS and RHS. - bool executesAtLeastOnce(const Loop *L, bool isSigned, SCEV *LHS, SCEV *RHS); + bool executesAtLeastOnce(const Loop *L, bool isSigned, bool trueWhenEqual, + SCEV *LHS, SCEV *RHS); + + /// potentialInfiniteLoop - Test whether the loop might jump over the exit value + /// due to wrapping. + bool potentialInfiniteLoop(SCEV *Stride, SCEV *RHS, bool isSigned, + bool trueWhenEqual); /// getConstantEvolutionLoopExitValue - If we know that the specified Phi is /// in the header of its containing loop, we know the loop executes a @@ -2025,24 +2031,46 @@ break; } case ICmpInst::ICMP_SLT: { - SCEVHandle TC = HowManyLessThans(LHS, RHS, L, true); + SCEVHandle TC = HowManyLessThans(LHS, RHS, L, true, false); if (!isa(TC)) return TC; break; } case ICmpInst::ICMP_SGT: { SCEVHandle TC = HowManyLessThans(SE.getNotSCEV(LHS), - SE.getNotSCEV(RHS), L, true); + SE.getNotSCEV(RHS), L, true, false); if (!isa(TC)) return TC; break; } case ICmpInst::ICMP_ULT: { - SCEVHandle TC = HowManyLessThans(LHS, RHS, L, false); + SCEVHandle TC = HowManyLessThans(LHS, RHS, L, false, false); if (!isa(TC)) return TC; break; } case ICmpInst::ICMP_UGT: { SCEVHandle TC = HowManyLessThans(SE.getNotSCEV(LHS), - SE.getNotSCEV(RHS), L, false); + SE.getNotSCEV(RHS), L, false, false); + if (!isa(TC)) return TC; + break; + } + case ICmpInst::ICMP_SLE: { + SCEVHandle TC = HowManyLessThans(LHS, RHS, L, true, true); + if (!isa(TC)) return TC; + break; + } + case ICmpInst::ICMP_SGE: { + SCEVHandle TC = HowManyLessThans(SE.getNotSCEV(LHS), + SE.getNotSCEV(RHS), L, true, true); + if (!isa(TC)) return TC; + break; + } + case ICmpInst::ICMP_ULE: { + SCEVHandle TC = HowManyLessThans(LHS, RHS, L, false, true); + if (!isa(TC)) return TC; + break; + } + case ICmpInst::ICMP_UGE: { + SCEVHandle TC = HowManyLessThans(SE.getNotSCEV(LHS), + SE.getNotSCEV(RHS), L, false, true); if (!isa(TC)) return TC; break; } @@ -2738,6 +2766,7 @@ /// executesAtLeastOnce - Test whether entry to the loop is protected by /// a conditional between LHS and RHS. bool ScalarEvolutionsImpl::executesAtLeastOnce(const Loop *L, bool isSigned, + bool trueWhenEqual, SCEV *LHS, SCEV *RHS) { BasicBlock *Preheader = L->getLoopPreheader(); BasicBlock *PreheaderDest = L->getHeader(); @@ -2770,20 +2799,36 @@ switch (Cond) { case ICmpInst::ICMP_UGT: - if (isSigned) continue; + if (isSigned || trueWhenEqual) continue; std::swap(PreCondLHS, PreCondRHS); Cond = ICmpInst::ICMP_ULT; break; case ICmpInst::ICMP_SGT: - if (!isSigned) continue; + if (!isSigned || trueWhenEqual) continue; std::swap(PreCondLHS, PreCondRHS); Cond = ICmpInst::ICMP_SLT; break; case ICmpInst::ICMP_ULT: - if (isSigned) continue; + if (isSigned || trueWhenEqual) continue; break; case ICmpInst::ICMP_SLT: - if (!isSigned) continue; + if (!isSigned || trueWhenEqual) continue; + break; + case ICmpInst::ICMP_UGE: + if (isSigned || !trueWhenEqual) continue; + std::swap(PreCondLHS, PreCondRHS); + Cond = ICmpInst::ICMP_ULE; + break; + case ICmpInst::ICMP_SGE: + if (!isSigned || !trueWhenEqual) continue; + std::swap(PreCondLHS, PreCondRHS); + Cond = ICmpInst::ICMP_SLE; + break; + case ICmpInst::ICMP_ULE: + if (isSigned || !trueWhenEqual) continue; + break; + case ICmpInst::ICMP_SLE: + if (!isSigned || !trueWhenEqual) continue; break; default: continue; @@ -2802,11 +2847,46 @@ return false; } +/// potentialInfiniteLoop - Test whether the loop might jump over the exit value +/// due to wrapping around 2^n. +bool ScalarEvolutionsImpl::potentialInfiniteLoop(SCEV *Stride, SCEV *RHS, + bool isSigned, bool trueWhenEqual) { + // Return true when the distance from RHS to maxint > Stride. + + if (!isa(Stride)) + return true; + SCEVConstant *SC = cast(Stride); + + if (SC->getValue()->isZero()) + return true; + if (!trueWhenEqual && SC->getValue()->isOne()) + return false; + + if (!isa(RHS)) + return true; + SCEVConstant *R = cast(RHS); + + if (isSigned) + return true; // XXX: because we don't have an sdiv scev. + + // If negative, it wraps around every iteration, but we don't care about that. + APInt S = SC->getValue()->getValue().abs(); + + APInt Dist = APInt::getMaxValue(R->getValue()->getBitWidth()) - + R->getValue()->getValue(); + + if (trueWhenEqual) + return !S.ult(Dist); + else + return !S.ule(Dist); +} + /// HowManyLessThans - Return the number of times a backedge containing the /// specified less-than comparison will execute. If not computable, return /// UnknownValue. SCEVHandle ScalarEvolutionsImpl:: -HowManyLessThans(SCEV *LHS, SCEV *RHS, const Loop *L, bool isSigned) { +HowManyLessThans(SCEV *LHS, SCEV *RHS, const Loop *L, + bool isSigned, bool trueWhenEqual) { // Only handle: "ADDREC < LoopInvariant". if (!RHS->isLoopInvariant(L)) return UnknownValue; @@ -2815,34 +2895,50 @@ return UnknownValue; if (AddRec->isAffine()) { - // FORNOW: We only support unit strides. - SCEVHandle One = SE.getIntegerSCEV(1, RHS->getType()); - if (AddRec->getOperand(1) != One) + SCEVHandle Stride = AddRec->getOperand(1); + if (potentialInfiniteLoop(Stride, RHS, isSigned, trueWhenEqual)) return UnknownValue; - // We know the LHS is of the form {n,+,1} and the RHS is some loop-invariant - // m. So, we count the number of iterations in which {n,+,1} < m is true. - // Note that we cannot simply return max(m-n,0) because it's not safe to + // We know the LHS is of the form {n,+,s} and the RHS is some loop-invariant + // m. So, we count the number of iterations in which {n,+,s} < m is true. + // Note that we cannot simply return max(m-n,0)/s because it's not safe to // treat m-n as signed nor unsigned due to overflow possibility. // First, we get the value of the LHS in the first iteration: n SCEVHandle Start = AddRec->getOperand(0); - if (executesAtLeastOnce(L, isSigned, - SE.getMinusSCEV(AddRec->getOperand(0), One), RHS)) { - // Since we know that the condition is true in order to enter the loop, - // we know that it will run exactly m-n times. - return SE.getMinusSCEV(RHS, Start); - } else { - // Then, we get the value of the LHS in the first iteration in which the - // above condition doesn't hold. This equals to max(m,n). - SCEVHandle End = isSigned ? SE.getSMaxExpr(RHS, Start) - : SE.getUMaxExpr(RHS, Start); - - // Finally, we subtract these two values to get the number of times the - // backedge is executed: max(m,n)-n. - return SE.getMinusSCEV(End, Start); + SCEVHandle One = SE.getIntegerSCEV(1, RHS->getType()); + + // Assuming that the loop will run at least once, we know that it will + // run (m-n)/s times. + SCEVHandle End = RHS; + + if (!executesAtLeastOnce(L, isSigned, trueWhenEqual, + SE.getMinusSCEV(Start, One), RHS)) { + // If not, we get the value of the LHS in the first iteration in which + // the above condition doesn't hold. This equals to max(m,n). + End = isSigned ? SE.getSMaxExpr(RHS, Start) + : SE.getUMaxExpr(RHS, Start); } + + // If the expression is less-than-or-equal to, we need to extend the + // loop by one iteration. + // + // The loop won't actually run (m-n)/s times because the loop iterations + // won't divide evenly. For example, if you have {2,+,5} u< 10 the + // division would equal one, but the loop runs twice putting the + // induction variable at 12. + + if (!trueWhenEqual) + // (Stride - 1) is correct only because we know it's unsigned. + // What we really want is to decrease the magnitude of Stride by one. + Start = SE.getMinusSCEV(Start, SE.getMinusSCEV(Stride, One)); + else + Start = SE.getMinusSCEV(Start, Stride); + + // Finally, we subtract these two values to get the number of times the + // backedge is executed: max(m,n)-n. + return SE.getUDivExpr(SE.getMinusSCEV(End, Start), Stride); } return UnknownValue; Added: llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-LessThanOrEqual.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-LessThanOrEqual.ll?rev=59528&view=auto ============================================================================== --- llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-LessThanOrEqual.ll (added) +++ llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-LessThanOrEqual.ll Tue Nov 18 09:10:54 2008 @@ -0,0 +1,31 @@ +; RUN: llvm-as < %s | opt -analyze -scalar-evolution |& \ +; RUN: grep {Loop bb: (7 + (-1 \\* %argc)) iterations!} + +define i32 @main(i32 %argc, i8** %argv) nounwind { +entry: + %0 = icmp ugt i32 %argc, 7 ; [#uses=1] + br i1 %0, label %bb2, label %bb.nph + +bb.nph: ; preds = %entry + br label %bb + +bb: ; preds = %bb.nph, %bb1 + %indvar = phi i32 [ 0, %bb.nph ], [ %indvar.next, %bb1 ] ; [#uses=2] + %argc_addr.04 = add i32 %indvar, %argc ; [#uses=1] + tail call void (...)* @Test() nounwind + %1 = add i32 %argc_addr.04, 1 ; [#uses=1] + br label %bb1 + +bb1: ; preds = %bb + %phitmp = icmp ugt i32 %1, 7 ; [#uses=1] + %indvar.next = add i32 %indvar, 1 ; [#uses=1] + br i1 %phitmp, label %bb1.bb2_crit_edge, label %bb + +bb1.bb2_crit_edge: ; preds = %bb1 + br label %bb2 + +bb2: ; preds = %bb1.bb2_crit_edge, %entry + ret i32 0 +} + +declare void @Test(...) Added: llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride1.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride1.ll?rev=59528&view=auto ============================================================================== --- llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride1.ll (added) +++ llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride1.ll Tue Nov 18 09:10:54 2008 @@ -0,0 +1,30 @@ +; RUN: llvm-as < %s | opt -analyze -scalar-evolution |& grep {/u 3} + +define i32 @f(i32 %x) nounwind readnone { +entry: + %0 = icmp ugt i32 %x, 4 ; [#uses=1] + br i1 %0, label %bb.nph, label %bb2 + +bb.nph: ; preds = %entry + br label %bb + +bb: ; preds = %bb.nph, %bb1 + %indvar = phi i32 [ 0, %bb.nph ], [ %indvar.next, %bb1 ] ; [#uses=2] + %tmp = mul i32 %indvar, -3 ; [#uses=1] + %x_addr.04 = add i32 %tmp, %x ; [#uses=1] + %1 = add i32 %x_addr.04, -3 ; [#uses=2] + br label %bb1 + +bb1: ; preds = %bb + %2 = icmp ugt i32 %1, 4 ; [#uses=1] + %indvar.next = add i32 %indvar, 1 ; [#uses=1] + br i1 %2, label %bb, label %bb1.bb2_crit_edge + +bb1.bb2_crit_edge: ; preds = %bb1 + %.lcssa = phi i32 [ %1, %bb1 ] ; [#uses=1] + br label %bb2 + +bb2: ; preds = %bb1.bb2_crit_edge, %entry + %x_addr.0.lcssa = phi i32 [ %.lcssa, %bb1.bb2_crit_edge ], [ %x, %entry ] ; [#uses=1] + ret i32 %x_addr.0.lcssa +} Added: llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride2.ll?rev=59528&view=auto ============================================================================== --- llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride2.ll (added) +++ llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride2.ll Tue Nov 18 09:10:54 2008 @@ -0,0 +1,30 @@ +; RUN: llvm-as < %s | opt -analyze -scalar-evolution |& grep {/u 3} + +define i32 @f(i32 %x) nounwind readnone { +entry: + %0 = icmp ugt i32 %x, 999 ; [#uses=1] + br i1 %0, label %bb2, label %bb.nph + +bb.nph: ; preds = %entry + br label %bb + +bb: ; preds = %bb.nph, %bb1 + %indvar = phi i32 [ 0, %bb.nph ], [ %indvar.next, %bb1 ] ; [#uses=2] + %tmp = mul i32 %indvar, 3 ; [#uses=1] + %x_addr.04 = add i32 %tmp, %x ; [#uses=1] + %1 = add i32 %x_addr.04, 3 ; [#uses=2] + br label %bb1 + +bb1: ; preds = %bb + %2 = icmp ugt i32 %1, 999 ; [#uses=1] + %indvar.next = add i32 %indvar, 1 ; [#uses=1] + br i1 %2, label %bb1.bb2_crit_edge, label %bb + +bb1.bb2_crit_edge: ; preds = %bb1 + %.lcssa = phi i32 [ %1, %bb1 ] ; [#uses=1] + br label %bb2 + +bb2: ; preds = %bb1.bb2_crit_edge, %entry + %x_addr.0.lcssa = phi i32 [ %.lcssa, %bb1.bb2_crit_edge ], [ %x, %entry ] ; [#uses=1] + ret i32 %x_addr.0.lcssa +} From baldrick at free.fr Tue Nov 18 10:40:51 2008 From: baldrick at free.fr (Duncan Sands) Date: Tue, 18 Nov 2008 16:40:51 -0000 Subject: [llvm-commits] [llvm] r59530 - in /llvm/trunk/lib/CodeGen/SelectionDAG: LegalizeTypes.h LegalizeVectorTypes.cpp Message-ID: <200811181640.mAIGepXe005336@zion.cs.uiuc.edu> Author: baldrick Date: Tue Nov 18 10:40:48 2008 New Revision: 59530 URL: http://llvm.org/viewvc/llvm-project?rev=59530&view=rev Log: LegalizeTypes support for splitting and scalarizing SCALAR_TO_VECTOR. I didn't add the testcase, because once llc gets past scalar-to-vector it hits a SPU target lowering bug and explodes. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h?rev=59530&r1=59529&r2=59530&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h Tue Nov 18 10:40:48 2008 @@ -463,6 +463,7 @@ SDValue ScalarizeVecRes_FPOWI(SDNode *N); SDValue ScalarizeVecRes_INSERT_VECTOR_ELT(SDNode *N); SDValue ScalarizeVecRes_LOAD(LoadSDNode *N); + SDValue ScalarizeVecRes_SCALAR_TO_VECTOR(SDNode *N); SDValue ScalarizeVecRes_SELECT(SDNode *N); SDValue ScalarizeVecRes_SELECT_CC(SDNode *N); SDValue ScalarizeVecRes_UNDEF(SDNode *N); @@ -497,6 +498,7 @@ void SplitVecRes_FPOWI(SDNode *N, SDValue &Lo, SDValue &Hi); void SplitVecRes_INSERT_VECTOR_ELT(SDNode *N, SDValue &Lo, SDValue &Hi); void SplitVecRes_LOAD(LoadSDNode *N, SDValue &Lo, SDValue &Hi); + void SplitVecRes_SCALAR_TO_VECTOR(SDNode *N, SDValue &Lo, SDValue &Hi); void SplitVecRes_UNDEF(SDNode *N, SDValue &Lo, SDValue &Hi); void SplitVecRes_VECTOR_SHUFFLE(SDNode *N, SDValue &Lo, SDValue &Hi); void SplitVecRes_VSETCC(SDNode *N, SDValue &Lo, SDValue &Hi); Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp?rev=59530&r1=59529&r2=59530&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp Tue Nov 18 10:40:48 2008 @@ -41,18 +41,19 @@ assert(0 && "Do not know how to scalarize the result of this operator!"); abort(); - case ISD::BIT_CONVERT: R = ScalarizeVecRes_BIT_CONVERT(N); break; - case ISD::BUILD_VECTOR: R = N->getOperand(0); break; - case ISD::CONVERT_RNDSAT: R = ScalarizeVecRes_CONVERT_RNDSAT(N); break; + case ISD::BIT_CONVERT: R = ScalarizeVecRes_BIT_CONVERT(N); break; + case ISD::BUILD_VECTOR: R = N->getOperand(0); break; + case ISD::CONVERT_RNDSAT: R = ScalarizeVecRes_CONVERT_RNDSAT(N); break; case ISD::EXTRACT_SUBVECTOR: R = ScalarizeVecRes_EXTRACT_SUBVECTOR(N); break; - case ISD::FPOWI: R = ScalarizeVecRes_FPOWI(N); break; + case ISD::FPOWI: R = ScalarizeVecRes_FPOWI(N); break; case ISD::INSERT_VECTOR_ELT: R = ScalarizeVecRes_INSERT_VECTOR_ELT(N); break; case ISD::LOAD: R = ScalarizeVecRes_LOAD(cast(N));break; - case ISD::SELECT: R = ScalarizeVecRes_SELECT(N); break; - case ISD::SELECT_CC: R = ScalarizeVecRes_SELECT_CC(N); break; - case ISD::UNDEF: R = ScalarizeVecRes_UNDEF(N); break; - case ISD::VECTOR_SHUFFLE: R = ScalarizeVecRes_VECTOR_SHUFFLE(N); break; - case ISD::VSETCC: R = ScalarizeVecRes_VSETCC(N); break; + case ISD::SCALAR_TO_VECTOR: R = ScalarizeVecRes_SCALAR_TO_VECTOR(N); break; + case ISD::SELECT: R = ScalarizeVecRes_SELECT(N); break; + case ISD::SELECT_CC: R = ScalarizeVecRes_SELECT_CC(N); break; + case ISD::UNDEF: R = ScalarizeVecRes_UNDEF(N); break; + case ISD::VECTOR_SHUFFLE: R = ScalarizeVecRes_VECTOR_SHUFFLE(N); break; + case ISD::VSETCC: R = ScalarizeVecRes_VSETCC(N); break; case ISD::CTLZ: case ISD::CTPOP: @@ -164,8 +165,8 @@ return DAG.getNode(N->getOpcode(), DestVT, Op); } -SDValue DAGTypeLegalizer::ScalarizeVecRes_UNDEF(SDNode *N) { - return DAG.getNode(ISD::UNDEF, N->getValueType(0).getVectorElementType()); +SDValue DAGTypeLegalizer::ScalarizeVecRes_SCALAR_TO_VECTOR(SDNode *N) { + return N->getOperand(0); } SDValue DAGTypeLegalizer::ScalarizeVecRes_SELECT(SDNode *N) { @@ -182,6 +183,10 @@ N->getOperand(4)); } +SDValue DAGTypeLegalizer::ScalarizeVecRes_UNDEF(SDNode *N) { + return DAG.getNode(ISD::UNDEF, N->getValueType(0).getVectorElementType()); +} + SDValue DAGTypeLegalizer::ScalarizeVecRes_VECTOR_SHUFFLE(SDNode *N) { // Figure out if the scalar is the LHS or RHS and return it. SDValue Arg = N->getOperand(2).getOperand(0); @@ -354,6 +359,7 @@ case ISD::EXTRACT_SUBVECTOR: SplitVecRes_EXTRACT_SUBVECTOR(N, Lo, Hi); break; case ISD::FPOWI: SplitVecRes_FPOWI(N, Lo, Hi); break; case ISD::INSERT_VECTOR_ELT: SplitVecRes_INSERT_VECTOR_ELT(N, Lo, Hi); break; + case ISD::SCALAR_TO_VECTOR: SplitVecRes_SCALAR_TO_VECTOR(N, Lo, Hi); break; case ISD::LOAD: SplitVecRes_LOAD(cast(N), Lo, Hi);break; case ISD::VECTOR_SHUFFLE: SplitVecRes_VECTOR_SHUFFLE(N, Lo, Hi); break; case ISD::VSETCC: SplitVecRes_VSETCC(N, Lo, Hi); break; @@ -579,6 +585,14 @@ SplitVecRes_LOAD(cast(Load.getNode()), Lo, Hi); } +void DAGTypeLegalizer::SplitVecRes_SCALAR_TO_VECTOR(SDNode *N, SDValue &Lo, + SDValue &Hi) { + MVT LoVT, HiVT; + GetSplitDestVTs(N->getValueType(0), LoVT, HiVT); + Lo = DAG.getNode(ISD::SCALAR_TO_VECTOR, LoVT, N->getOperand(0)); + Hi = DAG.getNode(ISD::UNDEF, HiVT); +} + void DAGTypeLegalizer::SplitVecRes_LOAD(LoadSDNode *LD, SDValue &Lo, SDValue &Hi) { assert(ISD::isUNINDEXEDLoad(LD) && "Indexed load during type legalization!"); From gohman at apple.com Tue Nov 18 11:03:15 2008 From: gohman at apple.com (Dan Gohman) Date: Tue, 18 Nov 2008 17:03:15 -0000 Subject: [llvm-commits] [llvm] r59531 - in /llvm/trunk/lib/Target: Alpha/AsmPrinter/ Sparc/AsmPrinter/ Message-ID: <200811181703.mAIH3GVo006127@zion.cs.uiuc.edu> Author: djg Date: Tue Nov 18 11:03:06 2008 New Revision: 59531 URL: http://llvm.org/viewvc/llvm-project?rev=59531&view=rev Log: Add svn:ignore for build directories. Modified: llvm/trunk/lib/Target/Alpha/AsmPrinter/ (props changed) llvm/trunk/lib/Target/Sparc/AsmPrinter/ (props changed) Propchange: llvm/trunk/lib/Target/Alpha/AsmPrinter/ ------------------------------------------------------------------------------ --- svn:ignore (added) +++ svn:ignore Tue Nov 18 11:03:06 2008 @@ -0,0 +1,3 @@ +Debug +Release +Release-Asserts Propchange: llvm/trunk/lib/Target/Sparc/AsmPrinter/ ------------------------------------------------------------------------------ --- svn:ignore (added) +++ svn:ignore Tue Nov 18 11:03:06 2008 @@ -0,0 +1,3 @@ +Debug +Release +Release-Asserts From gohman at apple.com Tue Nov 18 11:05:42 2008 From: gohman at apple.com (Dan Gohman) Date: Tue, 18 Nov 2008 17:05:42 -0000 Subject: [llvm-commits] [llvm] r59532 - in /llvm/trunk: include/llvm/CodeGen/SelectionDAGNodes.h lib/CodeGen/SelectionDAG/LatencyPriorityQueue.h Message-ID: <200811181705.mAIH5gix006236@zion.cs.uiuc.edu> Author: djg Date: Tue Nov 18 11:05:42 2008 New Revision: 59532 URL: http://llvm.org/viewvc/llvm-project?rev=59532&view=rev Log: Whitespace cleanups. Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h llvm/trunk/lib/CodeGen/SelectionDAG/LatencyPriorityQueue.h Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h?rev=59532&r1=59531&r2=59532&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h (original) +++ llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h Tue Nov 18 11:05:42 2008 @@ -1766,7 +1766,7 @@ virtual void ANCHOR(); // Out-of-line virtual method to give class a home. bool ReadMem; // Intrinsic reads memory bool WriteMem; // Intrinsic writes memory - public: +public: MemIntrinsicSDNode(unsigned Opc, SDVTList VTs, const SDValue *Ops, unsigned NumOps, MVT MemoryVT, const Value *srcValue, int SVO, Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LatencyPriorityQueue.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LatencyPriorityQueue.h?rev=59532&r1=59531&r2=59532&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LatencyPriorityQueue.h (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LatencyPriorityQueue.h Tue Nov 18 11:05:42 2008 @@ -45,7 +45,7 @@ std::vector NumNodesSolelyBlocking; PriorityQueue, latency_sort> Queue; -public: + public: LatencyPriorityQueue() : Queue(latency_sort(this)) { } @@ -113,7 +113,7 @@ // the node available. void ScheduledNode(SUnit *Node); -private: + private: void CalculatePriorities(); int CalcLatency(const SUnit &SU); void AdjustPriorityOfUnscheduledPreds(SUnit *SU); From dpatel at apple.com Tue Nov 18 11:59:38 2008 From: dpatel at apple.com (Devang Patel) Date: Tue, 18 Nov 2008 09:59:38 -0800 Subject: [llvm-commits] [llvm] r59518 - /llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp In-Reply-To: <200811181057.mAIAvSps025741@zion.cs.uiuc.edu> References: <200811181057.mAIAvSps025741@zion.cs.uiuc.edu> Message-ID: <1AE52F02-7E96-4FE8-9264-2D2A87C45B6B@apple.com> On Nov 18, 2008, at 2:57 AM, Bill Wendling wrote: > Author: void > Date: Tue Nov 18 04:57:27 2008 > New Revision: 59518 > > URL: http://llvm.org/viewvc/llvm-project?rev=59518&view=rev > Log: > Cast to remove warning about comparing signed and unsigned. Thanks! > > > Modified: > llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp > > Modified: llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp?rev=59518&r1=59517&r2=59518&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp (original) > +++ llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp Tue Nov 18 > 04:57:27 2008 > @@ -732,7 +732,7 @@ > > // If the iteration range can be handled by SIToFPInst then use it. > APInt Max = APInt::getSignedMaxValue(32); > - if (Max.getZExtValue() > abs(intEV - intIV)) > + if (Max.getZExtValue() > static_cast(abs(intEV - intIV))) > return true; > > return false; > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits - Devang From evan.cheng at apple.com Tue Nov 18 12:00:13 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 18 Nov 2008 10:00:13 -0800 Subject: [llvm-commits] [llvm] r59399 - in /llvm/trunk: lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp test/CodeGen/X86/vec_shuffle-25.ll test/CodeGen/X86/vec_shuffle-26.ll test/CodeGen/X86/vec_shuffle-27.ll In-Reply-To: <200811160506.mAG56SV9023318@zion.cs.uiuc.edu> References: <200811160506.mAG56SV9023318@zion.cs.uiuc.edu> Message-ID: Hi Mon Ping, Thanks. Some nitpicks below. Evan On Nov 15, 2008, at 9:06 PM, Mon P Wang wrote: > Author: wangmp > Date: Sat Nov 15 23:06:27 2008 > New Revision: 59399 > > URL: http://llvm.org/viewvc/llvm-project?rev=59399&view=rev > Log: > Improved shuffle normalization to avoid using extract/build when we > can extract using different indexes for two vectors. Added a few tests > for vector shuffles. > > Added: > llvm/trunk/test/CodeGen/X86/vec_shuffle-25.ll > llvm/trunk/test/CodeGen/X86/vec_shuffle-26.ll > llvm/trunk/test/CodeGen/X86/vec_shuffle-27.ll > Modified: > llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp > > Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp?rev=59399&r1=59398&r2=59399&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp > (original) > +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Sat > Nov 15 23:06:27 2008 > @@ -2292,8 +2292,8 @@ > // Utility for visitShuffleVector - Returns true if the mask is mask > starting > // from SIndx and increasing to the element length (undefs are > allowed). > static bool SequentialMask(SDValue Mask, unsigned SIndx) { > - unsigned NumElems = Mask.getNumOperands(); > - for (unsigned i = 0; i != NumElems; ++i) { > + unsigned MaskNumElts = Mask.getNumOperands(); > + for (unsigned i = 0; i != MaskNumElts; ++i) { > if (Mask.getOperand(i).getOpcode() != ISD::UNDEF) { > unsigned Idx = cast(Mask.getOperand(i))- > >getZExtValue(); > if (Idx != i + SIndx) > @@ -2304,161 +2304,187 @@ > } > > void SelectionDAGLowering::visitShuffleVector(User &I) { > - SDValue V1 = getValue(I.getOperand(0)); > - SDValue V2 = getValue(I.getOperand(1)); > + SDValue Srcs[2]; > + Srcs[0] = getValue(I.getOperand(0)); > + Srcs[1] = getValue(I.getOperand(1)); A common idiom used is: SDValue Srcs[] = { getValue(I.getOperand(0), getValue(I.getOperand(1)) }; Is an array preferrable to V1 and V2? > > SDValue Mask = getValue(I.getOperand(2)); > > MVT VT = TLI.getValueType(I.getType()); > - MVT VT1 = V1.getValueType(); > - unsigned MaskNumElts = Mask.getNumOperands(); > - unsigned Src1NumElts = VT1.getVectorNumElements(); > + MVT SrcVT = Srcs[0].getValueType(); > + int MaskNumElts = Mask.getNumOperands(); > + int SrcNumElts = SrcVT.getVectorNumElements(); Why int instead of unsigned? > > > - if (Src1NumElts == MaskNumElts) { > - setValue(&I, DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V1, V2, Mask)); > + if (SrcNumElts == MaskNumElts) { > + setValue(&I, DAG.getNode(ISD::VECTOR_SHUFFLE, VT, Srcs[0], > Srcs[1], Mask)); > return; > } > > // Normalize the shuffle vector since mask and vector length don't > match. > - if (Src1NumElts < MaskNumElts && MaskNumElts % Src1NumElts == 0) { > - // We can concat vectors to make the mask and input vector match. > - if (Src1NumElts*2 == MaskNumElts && SequentialMask(Mask, 0)) { > - // The shuffle is concatenating two vectors. > - setValue(&I, DAG.getNode(ISD::CONCAT_VECTORS, VT, V1, V2)); > + MVT MaskEltVT = Mask.getValueType().getVectorElementType(); > + > + if (SrcNumElts < MaskNumElts && MaskNumElts % SrcNumElts == 0) { > + // Mask is longer than the source vectors and is a multiple of > the source > + // vectors. We can use concatenate vector to make the mask and > vectors > + // length match. lengthes. > > + if (SrcNumElts*2 == MaskNumElts && SequentialMask(Mask, 0)) { > + // The shuffle is concatenating two vectors together. > + setValue(&I, DAG.getNode(ISD::CONCAT_VECTORS, VT, Srcs[0], > Srcs[1])); > return; > } > > - // Pad both vectors with undefs to the same size as the mask. > - unsigned NumConcat = MaskNumElts / Src1NumElts; > - std::vector UnOps(Src1NumElts, > - DAG.getNode(ISD::UNDEF, > - > VT1.getVectorElementType())); > - SDValue UndefVal = DAG.getNode(ISD::BUILD_VECTOR, VT1, > - &UnOps[0], UnOps.size()); > + // Pad both vectors with undefs to make them the same length as > the mask. > + unsigned NumConcat = MaskNumElts / SrcNumElts; > + SDValue UndefVal = DAG.getNode(ISD::UNDEF, SrcVT); > > SmallVector MOps1, MOps2; > - MOps1.push_back(V1); > - MOps2.push_back(V2); > + MOps1.push_back(Srcs[0]); > + MOps2.push_back(Srcs[1]); > for (unsigned i = 1; i != NumConcat; ++i) { > MOps1.push_back(UndefVal); > MOps2.push_back(UndefVal); > } It seems silly to use vectors instead of arrays here. > > - V1 = DAG.getNode(ISD::CONCAT_VECTORS, VT, &MOps1[0], > MOps1.size()); > - V2 = DAG.getNode(ISD::CONCAT_VECTORS, VT, &MOps2[0], > MOps2.size()); > + Srcs[0] = DAG.getNode(ISD::CONCAT_VECTORS, VT, &MOps1[0], > MOps1.size()); > + Srcs[1] = DAG.getNode(ISD::CONCAT_VECTORS, VT, &MOps2[0], > MOps2.size()); > > // Readjust mask for new input vector length. > SmallVector MappedOps; > - for (unsigned i = 0; i != MaskNumElts; ++i) { > + for (int i = 0; i != MaskNumElts; ++i) { > if (Mask.getOperand(i).getOpcode() == ISD::UNDEF) { > MappedOps.push_back(Mask.getOperand(i)); > } else { > - unsigned Idx = cast(Mask.getOperand(i))- > >getZExtValue(); > - if (Idx < Src1NumElts) { > - MappedOps.push_back(DAG.getConstant(Idx, > - > Mask.getOperand(i).getValueType())); > - } else { > - MappedOps.push_back(DAG.getConstant(Idx + MaskNumElts - > Src1NumElts, > - > Mask.getOperand(i).getValueType())); > - } > + int Idx = cast(Mask.getOperand(i))- > >getZExtValue(); > + if (Idx < SrcNumElts) > + MappedOps.push_back(DAG.getConstant(Idx, MaskEltVT)); > + else > + MappedOps.push_back(DAG.getConstant(Idx + MaskNumElts - > SrcNumElts, > + MaskEltVT)); > } > } > Mask = DAG.getNode(ISD::BUILD_VECTOR, Mask.getValueType(), > &MappedOps[0], MappedOps.size()); > > - setValue(&I, DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V1, V2, Mask)); > + setValue(&I, DAG.getNode(ISD::VECTOR_SHUFFLE, VT, Srcs[0], > Srcs[1], Mask)); > return; > } > > - if (Src1NumElts > MaskNumElts) { > + if (SrcNumElts > MaskNumElts) { > // Resulting vector is shorter than the incoming vector. > - if (Src1NumElts == MaskNumElts && SequentialMask(Mask,0)) { > + if (SrcNumElts == MaskNumElts && SequentialMask(Mask,0)) { > // Shuffle extracts 1st vector. > - setValue(&I, V1); > + setValue(&I, Srcs[0]); > return; > } > > - if (Src1NumElts == MaskNumElts && > SequentialMask(Mask,MaskNumElts)) { > + if (SrcNumElts == MaskNumElts && > SequentialMask(Mask,MaskNumElts)) { > // Shuffle extracts 2nd vector. > - setValue(&I, V2); > + setValue(&I, Srcs[1]); > return; > } > > - // Analyze the access pattern of the vector to see if we can > extract each > - // subvector and then do the shuffle. The analysis is done by > calculating > - // the range of elements the mask access on both vectors. If it > is useful, > - // we could do better by considering separate what elements are > accessed > - // in each vector (i.e., have min/max for each vector). > - int MinRange = Src1NumElts+1; > - int MaxRange = -1; > - for (unsigned i = 0; i != MaskNumElts; ++i) { > + // Analyze the access pattern of the vector to see if we can > extract > + // two subvectors and do the shuffle. The analysis is done by > calculating > + // the range of elements the mask access on both vectors. > + int MinRange[2] = { SrcNumElts+1, SrcNumElts+1}; > + int MaxRange[2] = {-1, -1}; > + > + for (int i = 0; i != MaskNumElts; ++i) { > SDValue Arg = Mask.getOperand(i); > if (Arg.getOpcode() != ISD::UNDEF) { > assert(isa(Arg) && "Invalid VECTOR_SHUFFLE > mask!"); > - int Idx = cast(Mask.getOperand(i))- > >getZExtValue(); > - if (Idx > (int) Src1NumElts) > - Idx -= Src1NumElts; > - if (Idx > MaxRange) > - MaxRange = Idx; > - if (Idx < MinRange) > - MinRange = Idx; > - } > - } > - // Adjust MinRange to start at an even boundary since this give > us > - // better quality splits later. > - if ((unsigned) MinRange < Src1NumElts && MinRange%2 != 0) > - MinRange = MinRange - 1; > - if (MaxRange - MinRange < (int) MaskNumElts) { > - // Extract subvector because the range is less than the new > vector length > - unsigned StartIdx = (MinRange/MaskNumElts)*MaskNumElts; > - if (MaxRange - StartIdx < MaskNumElts) { > - V1 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, VT, V1, > - DAG.getIntPtrConstant(MinRange)); > - V2 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, VT, V2, > - DAG.getIntPtrConstant(MinRange)); > - // Readjust mask for new input vector length. > - SmallVector MappedOps; > - for (unsigned i = 0; i != MaskNumElts; ++i) { > - if (Mask.getOperand(i).getOpcode() == ISD::UNDEF) { > - MappedOps.push_back(Mask.getOperand(i)); > - } else { > - unsigned Idx = > - cast(Mask.getOperand(i))- > >getZExtValue(); > - if (Idx < Src1NumElts) { > - MappedOps.push_back(DAG.getConstant(Idx - StartIdx, > - > Mask.getOperand(i).getValueType())); > - } else { > - Idx = Idx - Src1NumElts - StartIdx + MaskNumElts; > - MappedOps.push_back(DAG.getConstant(Idx, > - > Mask.getOperand(i).getValueType())); > - } > - } > + int Idx = cast(Arg)->getZExtValue(); > + int Input = 0; > + if (Idx >= SrcNumElts) { > + Input = 1; > + Idx -= SrcNumElts; > } > - Mask = DAG.getNode(ISD::BUILD_VECTOR, Mask.getValueType(), > - &MappedOps[0], MappedOps.size()); > + if (Idx > MaxRange[Input]) > + MaxRange[Input] = Idx; > + if (Idx < MinRange[Input]) > + MinRange[Input] = Idx; > + } > + } > > - setValue(&I, DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V1, V2, > Mask)); > - return; > + // Check if the access is smaller than the vector size and can > we find > + // a reasonable extract index. > + int RangeUse[2]; // 0 = Unused, 1 = Extract, 2 = Can not > Extract. Perhaps initialize RangeUse with 2's to eliminate some nesting below? > > + int StartIdx[2]; // StartIdx to extract from > + for (int Input=0; Input < 2; ++Input) { int -> unsigned? > > + if (MinRange[Input] == SrcNumElts+1 && MaxRange[Input] == -1) { > + RangeUse[Input] = 0; // Unused > + StartIdx[Input] = 0; > + } else if (MaxRange[Input] - MinRange[Input] < MaskNumElts) { > + // Fits within range but we should see if we can find a good > + // start index that a multiple of the mask length. > + if (MaxRange[Input] < MaskNumElts) { > + RangeUse[Input] = 1; // Extract from beginning of the > vector > + StartIdx[Input] = 0; > + } else { > + StartIdx[Input] = (MinRange[Input]/ > MaskNumElts)*MaskNumElts; > + if (MaxRange[Input] - StartIdx[Input] < MaskNumElts) > + RangeUse[Input] = 1; // Extract from a multiple of the > mask length. > + else > + RangeUse[Input] = 2; // Can not extract > + } > + } else > + RangeUse[Input] = 2; // Access doesn't fit within range > + } > + > + if (RangeUse[0] == 0 && RangeUse[0] == 0) { > + setValue(&I, DAG.getNode(ISD::UNDEF, VT)); // Vectors are > not used. > + return; > + } > + else if (RangeUse[0] < 2 && RangeUse[1] < 2) { > + // Extract appropriate subvector and generate a vector shuffle > + for (int Input=0; Input < 2; ++Input) { > + if (RangeUse[Input] == 0) { > + Srcs[Input] = DAG.getNode(ISD::UNDEF, VT); > + } else { > + Srcs[Input] = DAG.getNode(ISD::EXTRACT_SUBVECTOR, VT, > Srcs[Input], > + > DAG.getIntPtrConstant(StartIdx[Input])); > + } > + } > + // Calculate new mask. > + SmallVector MappedOps; > + for (int i = 0; i != MaskNumElts; ++i) { int -> unsigned? > > + SDValue Arg = Mask.getOperand(i); > + if (Arg.getOpcode() == ISD::UNDEF) { > + MappedOps.push_back(Arg); > + } else { > + int Idx = cast(Arg)->getZExtValue(); > + if (Idx < SrcNumElts) > + MappedOps.push_back(DAG.getConstant(Idx - StartIdx[0], > MaskEltVT)); > + else { > + Idx = Idx - SrcNumElts - StartIdx[1] + MaskNumElts; > + MappedOps.push_back(DAG.getConstant(Idx, MaskEltVT)); > + } > + } > } > + Mask = DAG.getNode(ISD::BUILD_VECTOR, Mask.getValueType(), > + &MappedOps[0], MappedOps.size()); > + setValue(&I, DAG.getNode(ISD::VECTOR_SHUFFLE, VT, Srcs[0], > Srcs[1], Mask)); > + return; > } > } > > - // We can't use either concat vectors or extract subvectors so we > fall back > - // to insert and extracts. > + // We can't use either concat vectors or extract subvectors so > fall back to > + // replacing the shuffle with extract and build vector. > + // to insert and build vector. > MVT EltVT = VT.getVectorElementType(); > MVT PtrVT = TLI.getPointerTy(); > SmallVector Ops; > - for (unsigned i = 0; i != MaskNumElts; ++i) { > + for (int i = 0; i != MaskNumElts; ++i) { > SDValue Arg = Mask.getOperand(i); > if (Arg.getOpcode() == ISD::UNDEF) { > Ops.push_back(DAG.getNode(ISD::UNDEF, EltVT)); > } else { > assert(isa(Arg) && "Invalid VECTOR_SHUFFLE > mask!"); > - unsigned Idx = cast(Arg)->getZExtValue(); > - if (Idx < Src1NumElts) > - Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EltVT, V1, > + int Idx = cast(Arg)->getZExtValue(); > + if (Idx < SrcNumElts) > + Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EltVT, > Srcs[0], > DAG.getConstant(Idx, PtrVT))); > else > - Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EltVT, V2, > - DAG.getConstant(Idx - > Src1NumElts, PtrVT))); > + Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EltVT, > Srcs[1], > + DAG.getConstant(Idx - SrcNumElts, > PtrVT))); > } > } > setValue(&I, DAG.getNode(ISD::BUILD_VECTOR, VT, &Ops[0], > Ops.size())); > > Added: llvm/trunk/test/CodeGen/X86/vec_shuffle-25.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/vec_shuffle-25.ll?rev=59399&view=auto > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/test/CodeGen/X86/vec_shuffle-25.ll (added) > +++ llvm/trunk/test/CodeGen/X86/vec_shuffle-25.ll Sat Nov 15 > 23:06:27 2008 > @@ -0,0 +1,34 @@ > +; RUN: llvm-as < %s | llc -march=x86 -mattr=sse41 -o %t -f > +; RUN: grep unpcklps %t | count 3 > +; RUN: grep unpckhps %t | count 1 > + > +; Transpose example using the more generic vector shuffle. We return > +; float8 instead of float16 since x86 can return that in register. > +; ModuleID = 'transpose2_opt.bc' > +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32- > i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64- > f80:32:32" > +target triple = "i386-apple-cl.1.0" > + at r0 = common global <4 x float> zeroinitializer, align 16 ; <<4 x > float>*> [#uses=1] > + at r1 = common global <4 x float> zeroinitializer, align 16 ; <<4 x > float>*> [#uses=1] > + at r2 = common global <4 x float> zeroinitializer, align 16 ; <<4 x > float>*> [#uses=1] > + at r3 = common global <4 x float> zeroinitializer, align 16 ; <<4 x > float>*> [#uses=1] > + > +define <8 x float> @__transpose2(<4 x float> %p0, <4 x float> %p1, > <4 x float> %p2, <4 x float> %p3) nounwind { > +entry: > + %unpcklps = shufflevector <4 x float> %p0, <4 x float> %p2, <4 x > i32> < i32 0, i32 4, i32 1, i32 5 > ; <<4 x float>> [#uses=2] > + %unpckhps = shufflevector <4 x float> %p0, <4 x float> %p2, <4 x > i32> < i32 2, i32 6, i32 3, i32 7 > ; <<4 x float>> [#uses=2] > + %unpcklps8 = shufflevector <4 x float> %p1, <4 x float> %p3, <4 x > i32> < i32 0, i32 4, i32 1, i32 5 > ; <<4 x float>> [#uses=2] > + %unpckhps11 = shufflevector <4 x float> %p1, <4 x float> %p3, <4 x > i32> < i32 2, i32 6, i32 3, i32 7 > ; <<4 x float>> [#uses=2] > + %unpcklps14 = shufflevector <4 x float> %unpcklps, <4 x float> > %unpcklps8, <4 x i32> < i32 0, i32 4, i32 1, i32 5 > ; <<4 x > float>> [#uses=1] > + %unpcklps14a = shufflevector <4 x float> %unpcklps14, <4 x float> > undef, <16 x i32> < i32 0, i32 1, i32 2, i32 3, i32 undef, i32 > undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 > undef, i32 undef, i32 undef, i32 undef, i32 undef>; > + %unpckhps17 = shufflevector <4 x float> %unpcklps, <4 x float> > %unpcklps8, <4 x i32> < i32 2, i32 6, i32 3, i32 7 > ; <<4 x > float>> [#uses=1] > + %unpckhps17a = shufflevector <4 x float> %unpckhps17, <4 x float> > undef, <16 x i32> < i32 0, i32 1, i32 2, i32 3, i32 undef, i32 > undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 > undef, i32 undef, i32 undef, i32 undef, i32 undef>; > + %r1 = shufflevector <16 x float> %unpcklps14a, <16 x float> > %unpckhps17a, <16 x i32> < i32 0, i32 1, i32 2, i32 3, i32 16, i32 > 17, i32 18, i32 19, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, > i32 14, i32 15>; > + %unpcklps20 = shufflevector <4 x float> %unpckhps, <4 x float> > %unpckhps11, <4 x i32> < i32 0, i32 4, i32 1, i32 5 > ; <<4 x > float>> [#uses=1] > + %unpcklps20a = shufflevector <4 x float> %unpcklps20, <4 x float> > undef, <16 x i32> < i32 0, i32 1, i32 2, i32 3, i32 undef, i32 > undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 > undef, i32 undef, i32 undef, i32 undef, i32 undef>; > + %r2 = shufflevector <16 x float> %r1, <16 x float> %unpcklps20a, > <16 x i32> < i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, > i32 16, i32 17, i32 18, i32 19, i32 12, i32 13, i32 14, i32 15>; > + %unpckhps23 = shufflevector <4 x float> %unpckhps, <4 x float> > %unpckhps11, <4 x i32> < i32 2, i32 6, i32 3, i32 7 > ; <<4 x > float>> [#uses=1] > + %unpckhps23a = shufflevector <4 x float> %unpckhps23, <4 x float> > undef, <16 x i32> < i32 0, i32 1, i32 2, i32 3, i32 undef, i32 > undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 > undef, i32 undef, i32 undef, i32 undef, i32 undef>; > + %r3 = shufflevector <16 x float> %r2, <16 x float> %unpckhps23a, > <16 x i32> < i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, > i32 8, i32 9, i32 10, i32 11, i32 16, i32 17, i32 18, i32 19>; > + %r4 = shufflevector <16 x float> %r3, <16 x float> undef, <8 x > i32> < i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>; > + ret <8 x float> %r4; > +} > > Added: llvm/trunk/test/CodeGen/X86/vec_shuffle-26.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/vec_shuffle-26.ll?rev=59399&view=auto > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/test/CodeGen/X86/vec_shuffle-26.ll (added) > +++ llvm/trunk/test/CodeGen/X86/vec_shuffle-26.ll Sat Nov 15 > 23:06:27 2008 > @@ -0,0 +1,29 @@ > +; RUN: llvm-as < %s | llc -march=x86 -mattr=sse41 -o %t -f > +; RUN: grep unpcklps %t | count 1 > +; RUN: grep unpckhps %t | count 3 > + > +; Transpose example using the more generic vector shuffle. Return > float8 > +; instead of float16 > +; ModuleID = 'transpose2_opt.bc' > +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32- > i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64- > f80:32:32" > +target triple = "i386-apple-cl.1.0" > + at r0 = common global <4 x float> zeroinitializer, align 16 ; <<4 x > float>*> [#uses=1] > + at r1 = common global <4 x float> zeroinitializer, align 16 ; <<4 x > float>*> [#uses=1] > + at r2 = common global <4 x float> zeroinitializer, align 16 ; <<4 x > float>*> [#uses=1] > + at r3 = common global <4 x float> zeroinitializer, align 16 ; <<4 x > float>*> [#uses=1] > + > +define <8 x float> @__transpose2(<4 x float> %p0, <4 x float> %p1, > <4 x float> %p2, <4 x float> %p3) nounwind { > +entry: > + %unpcklps = shufflevector <4 x float> %p0, <4 x float> %p2, <4 x > i32> < i32 0, i32 4, i32 1, i32 5 > ; <<4 x float>> [#uses=2] > + %unpckhps = shufflevector <4 x float> %p0, <4 x float> %p2, <4 x > i32> < i32 2, i32 6, i32 3, i32 7 > ; <<4 x float>> [#uses=2] > + %unpcklps8 = shufflevector <4 x float> %p1, <4 x float> %p3, <4 x > i32> < i32 0, i32 4, i32 1, i32 5 > ; <<4 x float>> [#uses=2] > + %unpckhps11 = shufflevector <4 x float> %p1, <4 x float> %p3, <4 x > i32> < i32 2, i32 6, i32 3, i32 7 > ; <<4 x float>> [#uses=2] > + %unpcklps14 = shufflevector <4 x float> %unpcklps, <4 x float> > %unpcklps8, <4 x i32> < i32 0, i32 4, i32 1, i32 5 > ; <<4 x > float>> [#uses=1] > + %unpckhps17 = shufflevector <4 x float> %unpcklps, <4 x float> > %unpcklps8, <4 x i32> < i32 2, i32 6, i32 3, i32 7 > ; <<4 x > float>> [#uses=1] > + %r1 = shufflevector <4 x float> %unpcklps14, <4 x float> > %unpckhps17, <8 x i32> < i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, > i32 6, i32 7 >; > + %unpcklps20 = shufflevector <4 x float> %unpckhps, <4 x float> > %unpckhps11, <4 x i32> < i32 0, i32 4, i32 1, i32 5 > ; <<4 x > float>> [#uses=1] > + %unpckhps23 = shufflevector <4 x float> %unpckhps, <4 x float> > %unpckhps11, <4 x i32> < i32 2, i32 6, i32 3, i32 7 > ; <<4 x > float>> [#uses=1] > + %r2 = shufflevector <4 x float> %unpcklps20, <4 x float> > %unpckhps23, <8 x i32> < i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, > i32 6, i32 7 >; > +; %r3 = shufflevector <8 x float> %r1, <8 x float> %r2, <16 > x i32> < i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 > 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15 >; > + ret <8 x float> %r2; > +} > > Added: llvm/trunk/test/CodeGen/X86/vec_shuffle-27.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/vec_shuffle-27.ll?rev=59399&view=auto > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/test/CodeGen/X86/vec_shuffle-27.ll (added) > +++ llvm/trunk/test/CodeGen/X86/vec_shuffle-27.ll Sat Nov 15 > 23:06:27 2008 > @@ -0,0 +1,17 @@ > +; RUN: llvm-as < %s | llc -march=x86 -mattr=sse41 -o %t -f > +; RUN: grep addps %t | count 2 > +; RUN: grep mulps %t | count 2 > +; RUN: grep subps %t | count 2 > + > +; ModuleID = 'vec_shuffle-27.bc' > +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32- > i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64- > f80:32:32" > +target triple = "i686-apple-cl.1.0" > + > +define <8 x float> @my2filter4_1d(<4 x float> %a, <8 x float> %T0, > <8 x float> %T1) nounwind readnone { > +entry: > + %tmp7 = shufflevector <4 x float> %a, <4 x float> undef, <8 x i32> > < i32 0, i32 1, i32 2, i32 3, i32 0, i32 1, i32 2, i32 3 > ; <<8 x > float>> [#uses=1] > + %sub = sub <8 x float> %T1, %T0 ; <<8 x float>> [#uses=1] > + %mul = mul <8 x float> %sub, %tmp7 ; <<8 x float>> [#uses=1] > + %add = add <8 x float> %mul, %T0 ; <<8 x float>> [#uses=1] > + ret <8 x float> %add > +} > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From evan.cheng at apple.com Tue Nov 18 12:22:52 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 18 Nov 2008 10:22:52 -0800 Subject: [llvm-commits] [llvm] r59528 - in /llvm/trunk: lib/Analysis/ScalarEvolution.cpp test/Analysis/ScalarEvolution/2008-11-18-LessThanOrEqual.ll test/Analysis/ScalarEvolution/2008-11-18-Stride1.ll test/Analysis/ScalarEvolution/2008-11-18-Stride2.ll In-Reply-To: <200811181510.mAIFAtVS001882@zion.cs.uiuc.edu> References: <200811181510.mAIFAtVS001882@zion.cs.uiuc.edu> Message-ID: <4C90C36A-77D6-4006-9F3F-19002F2E561A@apple.com> Hi Nicholas, What does "trueWhenEqual" mean? Should it default to true / false? Thanks, Evan On Nov 18, 2008, at 7:10 AM, Nick Lewycky wrote: > Author: nicholas > Date: Tue Nov 18 09:10:54 2008 > New Revision: 59528 > > URL: http://llvm.org/viewvc/llvm-project?rev=59528&view=rev > Log: > Add a utility function that detects whether a loop is guaranteed to > be finite. > > Use it to safely handle less-than-or-equals-to exit conditions in > loops. These > also occur when the loop exit branch is exit on true because SCEV > inverses the > icmp predicate. > > Use it again to handle non-zero strides, but only with an unsigned > comparison > in the exit condition. > > Added: > llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18- > LessThanOrEqual.ll > llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride1.ll > llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride2.ll > Modified: > llvm/trunk/lib/Analysis/ScalarEvolution.cpp > > Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=59528&r1=59527&r2=59528&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original) > +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Tue Nov 18 09:10:54 > 2008 > @@ -1477,7 +1477,7 @@ > /// specified less-than comparison will execute. If not > computable, return > /// UnknownValue. isSigned specifies whether the less-than is > signed. > SCEVHandle HowManyLessThans(SCEV *LHS, SCEV *RHS, const Loop *L, > - bool isSigned); > + bool isSigned, bool trueWhenEqual); > > /// getPredecessorWithUniqueSuccessorForBB - Return a > predecessor of BB > /// (which may not be an immediate predecessor) which has > exactly one > @@ -1487,7 +1487,13 @@ > > /// executesAtLeastOnce - Test whether entry to the loop is > protected by > /// a conditional between LHS and RHS. > - bool executesAtLeastOnce(const Loop *L, bool isSigned, SCEV > *LHS, SCEV *RHS); > + bool executesAtLeastOnce(const Loop *L, bool isSigned, bool > trueWhenEqual, > + SCEV *LHS, SCEV *RHS); > + > + /// potentialInfiniteLoop - Test whether the loop might jump > over the exit value > + /// due to wrapping. > + bool potentialInfiniteLoop(SCEV *Stride, SCEV *RHS, bool > isSigned, > + bool trueWhenEqual); > > /// getConstantEvolutionLoopExitValue - If we know that the > specified Phi is > /// in the header of its containing loop, we know the loop > executes a > @@ -2025,24 +2031,46 @@ > break; > } > case ICmpInst::ICMP_SLT: { > - SCEVHandle TC = HowManyLessThans(LHS, RHS, L, true); > + SCEVHandle TC = HowManyLessThans(LHS, RHS, L, true, false); > if (!isa(TC)) return TC; > break; > } > case ICmpInst::ICMP_SGT: { > SCEVHandle TC = HowManyLessThans(SE.getNotSCEV(LHS), > - SE.getNotSCEV(RHS), L, true); > + SE.getNotSCEV(RHS), L, true, > false); > if (!isa(TC)) return TC; > break; > } > case ICmpInst::ICMP_ULT: { > - SCEVHandle TC = HowManyLessThans(LHS, RHS, L, false); > + SCEVHandle TC = HowManyLessThans(LHS, RHS, L, false, false); > if (!isa(TC)) return TC; > break; > } > case ICmpInst::ICMP_UGT: { > SCEVHandle TC = HowManyLessThans(SE.getNotSCEV(LHS), > - SE.getNotSCEV(RHS), L, false); > + SE.getNotSCEV(RHS), L, false, > false); > + if (!isa(TC)) return TC; > + break; > + } > + case ICmpInst::ICMP_SLE: { > + SCEVHandle TC = HowManyLessThans(LHS, RHS, L, true, true); > + if (!isa(TC)) return TC; > + break; > + } > + case ICmpInst::ICMP_SGE: { > + SCEVHandle TC = HowManyLessThans(SE.getNotSCEV(LHS), > + SE.getNotSCEV(RHS), L, true, > true); > + if (!isa(TC)) return TC; > + break; > + } > + case ICmpInst::ICMP_ULE: { > + SCEVHandle TC = HowManyLessThans(LHS, RHS, L, false, true); > + if (!isa(TC)) return TC; > + break; > + } > + case ICmpInst::ICMP_UGE: { > + SCEVHandle TC = HowManyLessThans(SE.getNotSCEV(LHS), > + SE.getNotSCEV(RHS), L, false, > true); > if (!isa(TC)) return TC; > break; > } > @@ -2738,6 +2766,7 @@ > /// executesAtLeastOnce - Test whether entry to the loop is > protected by > /// a conditional between LHS and RHS. > bool ScalarEvolutionsImpl::executesAtLeastOnce(const Loop *L, bool > isSigned, > + bool trueWhenEqual, > SCEV *LHS, SCEV *RHS) { > BasicBlock *Preheader = L->getLoopPreheader(); > BasicBlock *PreheaderDest = L->getHeader(); > @@ -2770,20 +2799,36 @@ > > switch (Cond) { > case ICmpInst::ICMP_UGT: > - if (isSigned) continue; > + if (isSigned || trueWhenEqual) continue; > std::swap(PreCondLHS, PreCondRHS); > Cond = ICmpInst::ICMP_ULT; > break; > case ICmpInst::ICMP_SGT: > - if (!isSigned) continue; > + if (!isSigned || trueWhenEqual) continue; > std::swap(PreCondLHS, PreCondRHS); > Cond = ICmpInst::ICMP_SLT; > break; > case ICmpInst::ICMP_ULT: > - if (isSigned) continue; > + if (isSigned || trueWhenEqual) continue; > break; > case ICmpInst::ICMP_SLT: > - if (!isSigned) continue; > + if (!isSigned || trueWhenEqual) continue; > + break; > + case ICmpInst::ICMP_UGE: > + if (isSigned || !trueWhenEqual) continue; > + std::swap(PreCondLHS, PreCondRHS); > + Cond = ICmpInst::ICMP_ULE; > + break; > + case ICmpInst::ICMP_SGE: > + if (!isSigned || !trueWhenEqual) continue; > + std::swap(PreCondLHS, PreCondRHS); > + Cond = ICmpInst::ICMP_SLE; > + break; > + case ICmpInst::ICMP_ULE: > + if (isSigned || !trueWhenEqual) continue; > + break; > + case ICmpInst::ICMP_SLE: > + if (!isSigned || !trueWhenEqual) continue; > break; > default: > continue; > @@ -2802,11 +2847,46 @@ > return false; > } > > +/// potentialInfiniteLoop - Test whether the loop might jump over > the exit value > +/// due to wrapping around 2^n. > +bool ScalarEvolutionsImpl::potentialInfiniteLoop(SCEV *Stride, SCEV > *RHS, > + bool isSigned, > bool trueWhenEqual) { > + // Return true when the distance from RHS to maxint > Stride. > + > + if (!isa(Stride)) > + return true; > + SCEVConstant *SC = cast(Stride); > + > + if (SC->getValue()->isZero()) > + return true; > + if (!trueWhenEqual && SC->getValue()->isOne()) > + return false; > + > + if (!isa(RHS)) > + return true; > + SCEVConstant *R = cast(RHS); > + > + if (isSigned) > + return true; // XXX: because we don't have an sdiv scev. > + > + // If negative, it wraps around every iteration, but we don't > care about that. > + APInt S = SC->getValue()->getValue().abs(); > + > + APInt Dist = APInt::getMaxValue(R->getValue()->getBitWidth()) - > + R->getValue()->getValue(); > + > + if (trueWhenEqual) > + return !S.ult(Dist); > + else > + return !S.ule(Dist); > +} > + > /// HowManyLessThans - Return the number of times a backedge > containing the > /// specified less-than comparison will execute. If not computable, > return > /// UnknownValue. > SCEVHandle ScalarEvolutionsImpl:: > -HowManyLessThans(SCEV *LHS, SCEV *RHS, const Loop *L, bool > isSigned) { > +HowManyLessThans(SCEV *LHS, SCEV *RHS, const Loop *L, > + bool isSigned, bool trueWhenEqual) { > // Only handle: "ADDREC < LoopInvariant". > if (!RHS->isLoopInvariant(L)) return UnknownValue; > > @@ -2815,34 +2895,50 @@ > return UnknownValue; > > if (AddRec->isAffine()) { > - // FORNOW: We only support unit strides. > - SCEVHandle One = SE.getIntegerSCEV(1, RHS->getType()); > - if (AddRec->getOperand(1) != One) > + SCEVHandle Stride = AddRec->getOperand(1); > + if (potentialInfiniteLoop(Stride, RHS, isSigned, trueWhenEqual)) > return UnknownValue; > > - // We know the LHS is of the form {n,+,1} and the RHS is some > loop-invariant > - // m. So, we count the number of iterations in which {n,+,1} < > m is true. > - // Note that we cannot simply return max(m-n,0) because it's > not safe to > + // We know the LHS is of the form {n,+,s} and the RHS is some > loop-invariant > + // m. So, we count the number of iterations in which {n,+,s} < > m is true. > + // Note that we cannot simply return max(m-n,0)/s because it's > not safe to > // treat m-n as signed nor unsigned due to overflow possibility. > > // First, we get the value of the LHS in the first iteration: n > SCEVHandle Start = AddRec->getOperand(0); > > - if (executesAtLeastOnce(L, isSigned, > - SE.getMinusSCEV(AddRec->getOperand(0), > One), RHS)) { > - // Since we know that the condition is true in order to enter > the loop, > - // we know that it will run exactly m-n times. > - return SE.getMinusSCEV(RHS, Start); > - } else { > - // Then, we get the value of the LHS in the first iteration > in which the > - // above condition doesn't hold. This equals to max(m,n). > - SCEVHandle End = isSigned ? SE.getSMaxExpr(RHS, Start) > - : SE.getUMaxExpr(RHS, Start); > - > - // Finally, we subtract these two values to get the number of > times the > - // backedge is executed: max(m,n)-n. > - return SE.getMinusSCEV(End, Start); > + SCEVHandle One = SE.getIntegerSCEV(1, RHS->getType()); > + > + // Assuming that the loop will run at least once, we know that > it will > + // run (m-n)/s times. > + SCEVHandle End = RHS; > + > + if (!executesAtLeastOnce(L, isSigned, trueWhenEqual, > + SE.getMinusSCEV(Start, One), RHS)) { > + // If not, we get the value of the LHS in the first iteration > in which > + // the above condition doesn't hold. This equals to max(m,n). > + End = isSigned ? SE.getSMaxExpr(RHS, Start) > + : SE.getUMaxExpr(RHS, Start); > } > + > + // If the expression is less-than-or-equal to, we need to > extend the > + // loop by one iteration. > + // > + // The loop won't actually run (m-n)/s times because the loop > iterations > + // won't divide evenly. For example, if you have {2,+,5} u< 10 > the > + // division would equal one, but the loop runs twice putting the > + // induction variable at 12. > + > + if (!trueWhenEqual) > + // (Stride - 1) is correct only because we know it's unsigned. > + // What we really want is to decrease the magnitude of Stride > by one. > + Start = SE.getMinusSCEV(Start, SE.getMinusSCEV(Stride, One)); > + else > + Start = SE.getMinusSCEV(Start, Stride); > + > + // Finally, we subtract these two values to get the number of > times the > + // backedge is executed: max(m,n)-n. > + return SE.getUDivExpr(SE.getMinusSCEV(End, Start), Stride); > } > > return UnknownValue; > > Added: llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18- > LessThanOrEqual.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-LessThanOrEqual.ll?rev=59528&view=auto > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18- > LessThanOrEqual.ll (added) > +++ llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18- > LessThanOrEqual.ll Tue Nov 18 09:10:54 2008 > @@ -0,0 +1,31 @@ > +; RUN: llvm-as < %s | opt -analyze -scalar-evolution |& \ > +; RUN: grep {Loop bb: (7 + (-1 \\* %argc)) iterations!} > + > +define i32 @main(i32 %argc, i8** %argv) nounwind { > +entry: > + %0 = icmp ugt i32 %argc, 7 ; [#uses=1] > + br i1 %0, label %bb2, label %bb.nph > + > +bb.nph: ; preds = %entry > + br label %bb > + > +bb: ; preds = %bb.nph, %bb1 > + %indvar = phi i32 [ 0, %bb.nph ], [ %indvar.next, %bb1 ] ; > [#uses=2] > + %argc_addr.04 = add i32 %indvar, %argc ; [#uses=1] > + tail call void (...)* @Test() nounwind > + %1 = add i32 %argc_addr.04, 1 ; [#uses=1] > + br label %bb1 > + > +bb1: ; preds = %bb > + %phitmp = icmp ugt i32 %1, 7 ; [#uses=1] > + %indvar.next = add i32 %indvar, 1 ; [#uses=1] > + br i1 %phitmp, label %bb1.bb2_crit_edge, label %bb > + > +bb1.bb2_crit_edge: ; preds = %bb1 > + br label %bb2 > + > +bb2: ; preds = %bb1.bb2_crit_edge, %entry > + ret i32 0 > +} > + > +declare void @Test(...) > > Added: llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride1.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride1.ll?rev=59528&view=auto > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride1.ll > (added) > +++ llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride1.ll > Tue Nov 18 09:10:54 2008 > @@ -0,0 +1,30 @@ > +; RUN: llvm-as < %s | opt -analyze -scalar-evolution |& grep {/u 3} > + > +define i32 @f(i32 %x) nounwind readnone { > +entry: > + %0 = icmp ugt i32 %x, 4 ; [#uses=1] > + br i1 %0, label %bb.nph, label %bb2 > + > +bb.nph: ; preds = %entry > + br label %bb > + > +bb: ; preds = %bb.nph, %bb1 > + %indvar = phi i32 [ 0, %bb.nph ], [ %indvar.next, %bb1 ] ; > [#uses=2] > + %tmp = mul i32 %indvar, -3 ; [#uses=1] > + %x_addr.04 = add i32 %tmp, %x ; [#uses=1] > + %1 = add i32 %x_addr.04, -3 ; [#uses=2] > + br label %bb1 > + > +bb1: ; preds = %bb > + %2 = icmp ugt i32 %1, 4 ; [#uses=1] > + %indvar.next = add i32 %indvar, 1 ; [#uses=1] > + br i1 %2, label %bb, label %bb1.bb2_crit_edge > + > +bb1.bb2_crit_edge: ; preds = %bb1 > + %.lcssa = phi i32 [ %1, %bb1 ] ; [#uses=1] > + br label %bb2 > + > +bb2: ; preds = %bb1.bb2_crit_edge, %entry > + %x_addr.0.lcssa = phi i32 [ %.lcssa, %bb1.bb2_crit_edge ], [ %x, > %entry ] ; [#uses=1] > + ret i32 %x_addr.0.lcssa > +} > > Added: llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride2.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride2.ll?rev=59528&view=auto > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride2.ll > (added) > +++ llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride2.ll > Tue Nov 18 09:10:54 2008 > @@ -0,0 +1,30 @@ > +; RUN: llvm-as < %s | opt -analyze -scalar-evolution |& grep {/u 3} > + > +define i32 @f(i32 %x) nounwind readnone { > +entry: > + %0 = icmp ugt i32 %x, 999 ; [#uses=1] > + br i1 %0, label %bb2, label %bb.nph > + > +bb.nph: ; preds = %entry > + br label %bb > + > +bb: ; preds = %bb.nph, %bb1 > + %indvar = phi i32 [ 0, %bb.nph ], [ %indvar.next, %bb1 ] ; > [#uses=2] > + %tmp = mul i32 %indvar, 3 ; [#uses=1] > + %x_addr.04 = add i32 %tmp, %x ; [#uses=1] > + %1 = add i32 %x_addr.04, 3 ; [#uses=2] > + br label %bb1 > + > +bb1: ; preds = %bb > + %2 = icmp ugt i32 %1, 999 ; [#uses=1] > + %indvar.next = add i32 %indvar, 1 ; [#uses=1] > + br i1 %2, label %bb1.bb2_crit_edge, label %bb > + > +bb1.bb2_crit_edge: ; preds = %bb1 > + %.lcssa = phi i32 [ %1, %bb1 ] ; [#uses=1] > + br label %bb2 > + > +bb2: ; preds = %bb1.bb2_crit_edge, %entry > + %x_addr.0.lcssa = phi i32 [ %.lcssa, %bb1.bb2_crit_edge ], [ %x, > %entry ] ; [#uses=1] > + ret i32 %x_addr.0.lcssa > +} > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From clattner at apple.com Tue Nov 18 12:26:45 2008 From: clattner at apple.com (Chris Lattner) Date: Tue, 18 Nov 2008 10:26:45 -0800 Subject: [llvm-commits] [llvm] r59519 - in /llvm/trunk: include/llvm/Intrinsics.td lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp lib/CodeGen/StackProtector.cpp In-Reply-To: <200811181101.mAIB1YQb025875@zion.cs.uiuc.edu> References: <200811181101.mAIB1YQb025875@zion.cs.uiuc.edu> Message-ID: <499BA954-77D6-4B1D-8B05-C91C4F3AB68D@apple.com> On Nov 18, 2008, at 3:01 AM, Bill Wendling wrote: > Author: void > Date: Tue Nov 18 05:01:33 2008 > New Revision: 59519 > > URL: http://llvm.org/viewvc/llvm-project?rev=59519&view=rev > Log: > Rename stackprotector_create intrinsic to stackprotector. Very cool. Can you please add this to LangRef.html also? -Chris From dpatel at apple.com Tue Nov 18 12:43:10 2008 From: dpatel at apple.com (Devang Patel) Date: Tue, 18 Nov 2008 18:43:10 -0000 Subject: [llvm-commits] [llvm] r59538 - /llvm/trunk/lib/Transforms/Utils/LowerAllocations.cpp Message-ID: <200811181843.mAIIhA1s010154@zion.cs.uiuc.edu> Author: dpatel Date: Tue Nov 18 12:43:07 2008 New Revision: 59538 URL: http://llvm.org/viewvc/llvm-project?rev=59538&view=rev Log: Initialize MallocFunc and FreeFunc properly. Modified: llvm/trunk/lib/Transforms/Utils/LowerAllocations.cpp Modified: llvm/trunk/lib/Transforms/Utils/LowerAllocations.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/LowerAllocations.cpp?rev=59538&r1=59537&r2=59538&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/LowerAllocations.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/LowerAllocations.cpp Tue Nov 18 12:43:07 2008 @@ -58,7 +58,7 @@ bool doInitialization(Module &M); virtual bool doInitialization(Function &F) { - return BasicBlockPass::doInitialization(F); + return doInitialization(*F.getParent()); } /// runOnBasicBlock - This method does the actual work of converting From gohman at apple.com Tue Nov 18 13:04:29 2008 From: gohman at apple.com (Dan Gohman) Date: Tue, 18 Nov 2008 19:04:29 -0000 Subject: [llvm-commits] [llvm] r59540 - in /llvm/trunk: include/llvm/CodeGen/MachineInstr.h lib/CodeGen/MachineInstr.cpp Message-ID: <200811181904.mAIJ4UsO010989@zion.cs.uiuc.edu> Author: djg Date: Tue Nov 18 13:04:29 2008 New Revision: 59540 URL: http://llvm.org/viewvc/llvm-project?rev=59540&view=rev Log: Make some methods const. Modified: llvm/trunk/include/llvm/CodeGen/MachineInstr.h llvm/trunk/lib/CodeGen/MachineInstr.cpp Modified: llvm/trunk/include/llvm/CodeGen/MachineInstr.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineInstr.h?rev=59540&r1=59539&r2=59540&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/MachineInstr.h (original) +++ llvm/trunk/include/llvm/CodeGen/MachineInstr.h Tue Nov 18 13:04:29 2008 @@ -248,11 +248,11 @@ /// isSafeToMove - Return true if it is safe to move this instruction. If /// SawStore is set to true, it means that there is a store (or call) between /// the instruction's location and its intended destination. - bool isSafeToMove(const TargetInstrInfo *TII, bool &SawStore); + bool isSafeToMove(const TargetInstrInfo *TII, bool &SawStore) const; /// isSafeToReMat - Return true if it's safe to rematerialize the specified /// instruction which defined the specified register instead of copying it. - bool isSafeToReMat(const TargetInstrInfo *TII, unsigned DstReg); + bool isSafeToReMat(const TargetInstrInfo *TII, unsigned DstReg) const; /// hasVolatileMemoryRef - Return true if this instruction may have a /// volatile memory reference, or if the information describing the Modified: llvm/trunk/lib/CodeGen/MachineInstr.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineInstr.cpp?rev=59540&r1=59539&r2=59540&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineInstr.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineInstr.cpp Tue Nov 18 13:04:29 2008 @@ -695,7 +695,8 @@ /// isSafeToMove - Return true if it is safe to move this instruction. If /// SawStore is set to true, it means that there is a store (or call) between /// the instruction's location and its intended destination. -bool MachineInstr::isSafeToMove(const TargetInstrInfo *TII, bool &SawStore) { +bool MachineInstr::isSafeToMove(const TargetInstrInfo *TII, + bool &SawStore) const { // Ignore stuff that we obviously can't move. if (TID->mayStore() || TID->isCall()) { SawStore = true; @@ -719,7 +720,8 @@ /// isSafeToReMat - Return true if it's safe to rematerialize the specified /// instruction which defined the specified register instead of copying it. -bool MachineInstr::isSafeToReMat(const TargetInstrInfo *TII, unsigned DstReg) { +bool MachineInstr::isSafeToReMat(const TargetInstrInfo *TII, + unsigned DstReg) const { bool SawStore = false; if (!getDesc().isRematerializable() || !TII->isTriviallyReMaterializable(this) || From dpatel at apple.com Tue Nov 18 13:12:58 2008 From: dpatel at apple.com (Devang Patel) Date: Tue, 18 Nov 2008 11:12:58 -0800 Subject: [llvm-commits] [llvm] r59208 - /llvm/trunk/lib/Transforms/IPO/StripSymbols.cpp In-Reply-To: <7D48091E-9165-4B3E-9E1E-FEA922D4DC47@apple.com> References: <200811130128.mAD1SfCx025350@zion.cs.uiuc.edu> <0EB49BD7-8E9F-4675-97FD-7583F45A8FAB@apple.com> <7D48091E-9165-4B3E-9E1E-FEA922D4DC47@apple.com> Message-ID: <7E35BAF1-6581-4AAC-987F-92ECE8D89DA4@apple.com> On Nov 17, 2008, at 5:00 PM, Chris Lattner wrote: > On Nov 17, 2008, at 4:45 PM, Devang Patel wrote: >>> I don't think that matching on the names is really a sound way to >>> go. >>> How about just looping over all the globals, removing dead globals >>> in >>> the llvm.metadata section? >> >> >> If it start remove dead globals then it becomes difficult to compare >> "- >> strip-debug -std-compile-opts" output with "-std-compile-opts -strip- >> debug" output. > > What other dead metadata can exist? llvm.used uses llvm.metadata. It is possible that symbols marked as attribute used does not have any use. In such cases we want to preserve them. Until alternative mechanism is available, name matching will be required anyway. - Devang From gohman at apple.com Tue Nov 18 13:49:32 2008 From: gohman at apple.com (Dan Gohman) Date: Tue, 18 Nov 2008 19:49:32 -0000 Subject: [llvm-commits] [llvm] r59542 - in /llvm/trunk: include/llvm/Target/ lib/CodeGen/ lib/Target/ARM/ lib/Target/Alpha/ lib/Target/CellSPU/ lib/Target/Mips/ lib/Target/PIC16/ lib/Target/PowerPC/ lib/Target/Sparc/ lib/Target/X86/ lib/Target/XCore/ Message-ID: <200811181949.mAIJnX9c012756@zion.cs.uiuc.edu> Author: djg Date: Tue Nov 18 13:49:32 2008 New Revision: 59542 URL: http://llvm.org/viewvc/llvm-project?rev=59542&view=rev Log: Add more const qualifiers. This fixes build breakage from r59540. Modified: llvm/trunk/include/llvm/Target/TargetInstrInfo.h llvm/trunk/lib/CodeGen/MachineInstr.cpp llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp llvm/trunk/lib/Target/ARM/ARMInstrInfo.h llvm/trunk/lib/Target/Alpha/AlphaInstrInfo.cpp llvm/trunk/lib/Target/Alpha/AlphaInstrInfo.h llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.cpp llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.h llvm/trunk/lib/Target/Mips/MipsInstrInfo.cpp llvm/trunk/lib/Target/Mips/MipsInstrInfo.h llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.cpp llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.h llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.h llvm/trunk/lib/Target/Sparc/SparcInstrInfo.cpp llvm/trunk/lib/Target/Sparc/SparcInstrInfo.h llvm/trunk/lib/Target/X86/X86InstrInfo.cpp llvm/trunk/lib/Target/X86/X86InstrInfo.h llvm/trunk/lib/Target/XCore/XCoreInstrInfo.cpp llvm/trunk/lib/Target/XCore/XCoreInstrInfo.h Modified: llvm/trunk/include/llvm/Target/TargetInstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetInstrInfo.h?rev=59542&r1=59541&r2=59542&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetInstrInfo.h (original) +++ llvm/trunk/include/llvm/Target/TargetInstrInfo.h Tue Nov 18 13:49:32 2008 @@ -101,7 +101,8 @@ /// the destination along with the FrameIndex of the loaded stack slot. If /// not, return 0. This predicate must return 0 if the instruction has /// any side effects other than loading from the stack slot. - virtual unsigned isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const{ + virtual unsigned isLoadFromStackSlot(const MachineInstr *MI, + int &FrameIndex) const { return 0; } @@ -110,7 +111,8 @@ /// the source reg along with the FrameIndex of the loaded stack slot. If /// not, return 0. This predicate must return 0 if the instruction has /// any side effects other than storing to the stack slot. - virtual unsigned isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const { + virtual unsigned isStoreToStackSlot(const MachineInstr *MI, + int &FrameIndex) const { return 0; } @@ -127,7 +129,7 @@ /// from the argument area of a function if it does not change. This should /// only return true of *all* loads the instruction does are invariant (if it /// does multiple loads). - virtual bool isInvariantLoad(MachineInstr *MI) const { + virtual bool isInvariantLoad(const MachineInstr *MI) const { return false; } Modified: llvm/trunk/lib/CodeGen/MachineInstr.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineInstr.cpp?rev=59542&r1=59541&r2=59542&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineInstr.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineInstr.cpp Tue Nov 18 13:49:32 2008 @@ -728,7 +728,7 @@ !isSafeToMove(TII, SawStore)) return false; for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { - MachineOperand &MO = getOperand(i); + const MachineOperand &MO = getOperand(i); if (!MO.isReg()) continue; // FIXME: For now, do not remat any instruction with register operands. Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp?rev=59542&r1=59541&r2=59542&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp Tue Nov 18 13:49:32 2008 @@ -73,7 +73,8 @@ } } -unsigned ARMInstrInfo::isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const{ +unsigned ARMInstrInfo::isLoadFromStackSlot(const MachineInstr *MI, + int &FrameIndex) const { switch (MI->getOpcode()) { default: break; case ARM::LDR: @@ -107,7 +108,8 @@ return 0; } -unsigned ARMInstrInfo::isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const { +unsigned ARMInstrInfo::isStoreToStackSlot(const MachineInstr *MI, + int &FrameIndex) const { switch (MI->getOpcode()) { default: break; case ARM::STR: Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.h?rev=59542&r1=59541&r2=59542&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.h (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.h Tue Nov 18 13:49:32 2008 @@ -160,8 +160,10 @@ /// virtual bool isMoveInstr(const MachineInstr &MI, unsigned &SrcReg, unsigned &DstReg) const; - virtual unsigned isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const; - virtual unsigned isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const; + virtual unsigned isLoadFromStackSlot(const MachineInstr *MI, + int &FrameIndex) const; + virtual unsigned isStoreToStackSlot(const MachineInstr *MI, + int &FrameIndex) const; void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, const MachineInstr *Orig) const; Modified: llvm/trunk/lib/Target/Alpha/AlphaInstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Alpha/AlphaInstrInfo.cpp?rev=59542&r1=59541&r2=59542&view=diff ============================================================================== --- llvm/trunk/lib/Target/Alpha/AlphaInstrInfo.cpp (original) +++ llvm/trunk/lib/Target/Alpha/AlphaInstrInfo.cpp Tue Nov 18 13:49:32 2008 @@ -49,7 +49,8 @@ } unsigned -AlphaInstrInfo::isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const { +AlphaInstrInfo::isLoadFromStackSlot(const MachineInstr *MI, + int &FrameIndex) const { switch (MI->getOpcode()) { case Alpha::LDL: case Alpha::LDQ: @@ -67,7 +68,8 @@ } unsigned -AlphaInstrInfo::isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const { +AlphaInstrInfo::isStoreToStackSlot(const MachineInstr *MI, + int &FrameIndex) const { switch (MI->getOpcode()) { case Alpha::STL: case Alpha::STQ: Modified: llvm/trunk/lib/Target/Alpha/AlphaInstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Alpha/AlphaInstrInfo.h?rev=59542&r1=59541&r2=59542&view=diff ============================================================================== --- llvm/trunk/lib/Target/Alpha/AlphaInstrInfo.h (original) +++ llvm/trunk/lib/Target/Alpha/AlphaInstrInfo.h Tue Nov 18 13:49:32 2008 @@ -36,8 +36,10 @@ virtual bool isMoveInstr(const MachineInstr &MI, unsigned &SrcReg, unsigned &DstReg) const; - virtual unsigned isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const; - virtual unsigned isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const; + virtual unsigned isLoadFromStackSlot(const MachineInstr *MI, + int &FrameIndex) const; + virtual unsigned isStoreToStackSlot(const MachineInstr *MI, + int &FrameIndex) const; virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, Modified: llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.cpp?rev=59542&r1=59541&r2=59542&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.cpp (original) +++ llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.cpp Tue Nov 18 13:49:32 2008 @@ -119,7 +119,8 @@ } unsigned -SPUInstrInfo::isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const { +SPUInstrInfo::isLoadFromStackSlot(const MachineInstr *MI, + int &FrameIndex) const { switch (MI->getOpcode()) { default: break; case SPU::LQDv16i8: @@ -147,7 +148,8 @@ } unsigned -SPUInstrInfo::isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const { +SPUInstrInfo::isStoreToStackSlot(const MachineInstr *MI, + int &FrameIndex) const { switch (MI->getOpcode()) { default: break; case SPU::STQDv16i8: Modified: llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.h?rev=59542&r1=59541&r2=59542&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.h (original) +++ llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.h Tue Nov 18 13:49:32 2008 @@ -43,8 +43,10 @@ unsigned& sourceReg, unsigned& destReg) const; - unsigned isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const; - unsigned isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const; + unsigned isLoadFromStackSlot(const MachineInstr *MI, + int &FrameIndex) const; + unsigned isStoreToStackSlot(const MachineInstr *MI, + int &FrameIndex) const; virtual bool copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, Modified: llvm/trunk/lib/Target/Mips/MipsInstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsInstrInfo.cpp?rev=59542&r1=59541&r2=59542&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsInstrInfo.cpp (original) +++ llvm/trunk/lib/Target/Mips/MipsInstrInfo.cpp Tue Nov 18 13:49:32 2008 @@ -75,7 +75,7 @@ /// not, return 0. This predicate must return 0 if the instruction has /// any side effects other than loading from the stack slot. unsigned MipsInstrInfo:: -isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const +isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const { if ((MI->getOpcode() == Mips::LW) || (MI->getOpcode() == Mips::LWC1) || (MI->getOpcode() == Mips::LWC1A) || (MI->getOpcode() == Mips::LDC1)) { @@ -96,7 +96,7 @@ /// not, return 0. This predicate must return 0 if the instruction has /// any side effects other than storing to the stack slot. unsigned MipsInstrInfo:: -isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const +isStoreToStackSlot(const MachineInstr *MI, int &FrameIndex) const { if ((MI->getOpcode() == Mips::SW) || (MI->getOpcode() == Mips::SWC1) || (MI->getOpcode() == Mips::SWC1A) || (MI->getOpcode() == Mips::SDC1)) { Modified: llvm/trunk/lib/Target/Mips/MipsInstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsInstrInfo.h?rev=59542&r1=59541&r2=59542&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsInstrInfo.h (original) +++ llvm/trunk/lib/Target/Mips/MipsInstrInfo.h Tue Nov 18 13:49:32 2008 @@ -152,14 +152,16 @@ /// the destination along with the FrameIndex of the loaded stack slot. If /// not, return 0. This predicate must return 0 if the instruction has /// any side effects other than loading from the stack slot. - virtual unsigned isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const; + virtual unsigned isLoadFromStackSlot(const MachineInstr *MI, + int &FrameIndex) const; /// isStoreToStackSlot - If the specified machine instruction is a direct /// store to a stack slot, return the virtual or physical register number of /// the source reg along with the FrameIndex of the loaded stack slot. If /// not, return 0. This predicate must return 0 if the instruction has /// any side effects other than storing to the stack slot. - virtual unsigned isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const; + virtual unsigned isStoreToStackSlot(const MachineInstr *MI, + int &FrameIndex) const; /// Branch Analysis virtual bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, Modified: llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.cpp?rev=59542&r1=59541&r2=59542&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.cpp (original) +++ llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.cpp Tue Nov 18 13:49:32 2008 @@ -38,7 +38,7 @@ /// not, return 0. This predicate must return 0 if the instruction has /// any side effects other than loading from the stack slot. unsigned PIC16InstrInfo:: -isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const +isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const { if (MI->getOpcode() == PIC16::MOVF) { if ((MI->getOperand(2).isFI()) && // is a stack slot @@ -58,7 +58,7 @@ /// not, return 0. This predicate must return 0 if the instruction has /// any side effects other than storing to the stack slot. unsigned PIC16InstrInfo:: -isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const +isStoreToStackSlot(const MachineInstr *MI, int &FrameIndex) const { if (MI->getOpcode() == PIC16::MOVWF) { if ((MI->getOperand(0).isFI()) && // is a stack slot Modified: llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.h?rev=59542&r1=59541&r2=59542&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.h (original) +++ llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.h Tue Nov 18 13:49:32 2008 @@ -40,14 +40,16 @@ /// the destination along with the FrameIndex of the loaded stack slot. If /// not, return 0. This predicate must return 0 if the instruction has /// any side effects other than loading from the stack slot. - virtual unsigned isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const; + virtual unsigned isLoadFromStackSlot(const MachineInstr *MI, + int &FrameIndex) const; /// isStoreToStackSlot - If the specified machine instruction is a direct /// store to a stack slot, return the virtual or physical register number of /// the source reg along with the FrameIndex of the loaded stack slot. If /// not, return 0. This predicate must return 0 if the instruction has /// any side effects other than storing to the stack slot. - virtual unsigned isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const; + virtual unsigned isStoreToStackSlot(const MachineInstr *MI, + int &FrameIndex) const; /// Used for spilling a register void storeRegToStackSlot(MachineBasicBlock &MBB, Modified: llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp?rev=59542&r1=59541&r2=59542&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp Tue Nov 18 13:49:32 2008 @@ -98,7 +98,7 @@ return false; } -unsigned PPCInstrInfo::isLoadFromStackSlot(MachineInstr *MI, +unsigned PPCInstrInfo::isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const { switch (MI->getOpcode()) { default: break; @@ -116,7 +116,7 @@ return 0; } -unsigned PPCInstrInfo::isStoreToStackSlot(MachineInstr *MI, +unsigned PPCInstrInfo::isStoreToStackSlot(const MachineInstr *MI, int &FrameIndex) const { switch (MI->getOpcode()) { default: break; Modified: llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.h?rev=59542&r1=59541&r2=59542&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.h (original) +++ llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.h Tue Nov 18 13:49:32 2008 @@ -93,8 +93,10 @@ unsigned& sourceReg, unsigned& destReg) const; - unsigned isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const; - unsigned isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const; + unsigned isLoadFromStackSlot(const MachineInstr *MI, + int &FrameIndex) const; + unsigned isStoreToStackSlot(const MachineInstr *MI, + int &FrameIndex) const; // commuteInstruction - We can commute rlwimi instructions, but only if the // rotate amt is zero. We also have to munge the immediates a bit. Modified: llvm/trunk/lib/Target/Sparc/SparcInstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcInstrInfo.cpp?rev=59542&r1=59541&r2=59542&view=diff ============================================================================== --- llvm/trunk/lib/Target/Sparc/SparcInstrInfo.cpp (original) +++ llvm/trunk/lib/Target/Sparc/SparcInstrInfo.cpp Tue Nov 18 13:49:32 2008 @@ -66,7 +66,7 @@ /// the destination along with the FrameIndex of the loaded stack slot. If /// not, return 0. This predicate must return 0 if the instruction has /// any side effects other than loading from the stack slot. -unsigned SparcInstrInfo::isLoadFromStackSlot(MachineInstr *MI, +unsigned SparcInstrInfo::isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const { if (MI->getOpcode() == SP::LDri || MI->getOpcode() == SP::LDFri || @@ -85,7 +85,7 @@ /// the source reg along with the FrameIndex of the loaded stack slot. If /// not, return 0. This predicate must return 0 if the instruction has /// any side effects other than storing to the stack slot. -unsigned SparcInstrInfo::isStoreToStackSlot(MachineInstr *MI, +unsigned SparcInstrInfo::isStoreToStackSlot(const MachineInstr *MI, int &FrameIndex) const { if (MI->getOpcode() == SP::STri || MI->getOpcode() == SP::STFri || Modified: llvm/trunk/lib/Target/Sparc/SparcInstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcInstrInfo.h?rev=59542&r1=59541&r2=59542&view=diff ============================================================================== --- llvm/trunk/lib/Target/Sparc/SparcInstrInfo.h (original) +++ llvm/trunk/lib/Target/Sparc/SparcInstrInfo.h Tue Nov 18 13:49:32 2008 @@ -54,14 +54,16 @@ /// the destination along with the FrameIndex of the loaded stack slot. If /// not, return 0. This predicate must return 0 if the instruction has /// any side effects other than loading from the stack slot. - virtual unsigned isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const; + virtual unsigned isLoadFromStackSlot(const MachineInstr *MI, + int &FrameIndex) const; /// isStoreToStackSlot - If the specified machine instruction is a direct /// store to a stack slot, return the virtual or physical register number of /// the source reg along with the FrameIndex of the loaded stack slot. If /// not, return 0. This predicate must return 0 if the instruction has /// any side effects other than storing to the stack slot. - virtual unsigned isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const; + virtual unsigned isStoreToStackSlot(const MachineInstr *MI, + int &FrameIndex) const; virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=59542&r1=59541&r2=59542&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Tue Nov 18 13:49:32 2008 @@ -688,7 +688,7 @@ } } -unsigned X86InstrInfo::isLoadFromStackSlot(MachineInstr *MI, +unsigned X86InstrInfo::isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const { switch (MI->getOpcode()) { default: break; @@ -718,7 +718,7 @@ return 0; } -unsigned X86InstrInfo::isStoreToStackSlot(MachineInstr *MI, +unsigned X86InstrInfo::isStoreToStackSlot(const MachineInstr *MI, int &FrameIndex) const { switch (MI->getOpcode()) { default: break; @@ -936,7 +936,7 @@ /// from the argument area of a function if it does not change. This should /// only return true of *all* loads the instruction does are invariant (if it /// does multiple loads). -bool X86InstrInfo::isInvariantLoad(MachineInstr *MI) const { +bool X86InstrInfo::isInvariantLoad(const MachineInstr *MI) const { // This code cares about loads from three cases: constant pool entries, // invariant argument slots, and global stubs. In order to handle these cases // for all of the myriad of X86 instructions, we just scan for a CP/FI/GV Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.h?rev=59542&r1=59541&r2=59542&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.h (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.h Tue Nov 18 13:49:32 2008 @@ -290,14 +290,14 @@ // bool isMoveInstr(const MachineInstr& MI, unsigned& sourceReg, unsigned& destReg) const; - unsigned isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const; - unsigned isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const; + unsigned isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const; + unsigned isStoreToStackSlot(const MachineInstr *MI, int &FrameIndex) const; bool isReallyTriviallyReMaterializable(const MachineInstr *MI) const; void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, const MachineInstr *Orig) const; - bool isInvariantLoad(MachineInstr *MI) const; + bool isInvariantLoad(const MachineInstr *MI) const; /// convertToThreeAddress - This method must be implemented by targets that /// set the M_CONVERTIBLE_TO_3_ADDR flag. When this flag is set, the target Modified: llvm/trunk/lib/Target/XCore/XCoreInstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/XCore/XCoreInstrInfo.cpp?rev=59542&r1=59541&r2=59542&view=diff ============================================================================== --- llvm/trunk/lib/Target/XCore/XCoreInstrInfo.cpp (original) +++ llvm/trunk/lib/Target/XCore/XCoreInstrInfo.cpp Tue Nov 18 13:49:32 2008 @@ -75,7 +75,7 @@ /// not, return 0. This predicate must return 0 if the instruction has /// any side effects other than loading from the stack slot. unsigned -XCoreInstrInfo::isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const{ +XCoreInstrInfo::isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const{ int Opcode = MI->getOpcode(); if (Opcode == XCore::LDWSP_ru6 || Opcode == XCore::LDWSP_lru6) { @@ -96,7 +96,8 @@ /// not, return 0. This predicate must return 0 if the instruction has /// any side effects other than storing to the stack slot. unsigned -XCoreInstrInfo::isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const { +XCoreInstrInfo::isStoreToStackSlot(const MachineInstr *MI, + int &FrameIndex) const { int Opcode = MI->getOpcode(); if (Opcode == XCore::STWSP_ru6 || Opcode == XCore::STWSP_lru6) { @@ -126,7 +127,7 @@ /// only return true of *all* loads the instruction does are invariant (if it /// does multiple loads). bool -XCoreInstrInfo::isInvariantLoad(MachineInstr *MI) const { +XCoreInstrInfo::isInvariantLoad(const MachineInstr *MI) const { // Loads from constants pools and loads from invariant argument slots are // invariant int Opcode = MI->getOpcode(); Modified: llvm/trunk/lib/Target/XCore/XCoreInstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/XCore/XCoreInstrInfo.h?rev=59542&r1=59541&r2=59542&view=diff ============================================================================== --- llvm/trunk/lib/Target/XCore/XCoreInstrInfo.h (original) +++ llvm/trunk/lib/Target/XCore/XCoreInstrInfo.h Tue Nov 18 13:49:32 2008 @@ -41,16 +41,18 @@ /// the destination along with the FrameIndex of the loaded stack slot. If /// not, return 0. This predicate must return 0 if the instruction has /// any side effects other than loading from the stack slot. - virtual unsigned isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const; + virtual unsigned isLoadFromStackSlot(const MachineInstr *MI, + int &FrameIndex) const; /// isStoreToStackSlot - If the specified machine instruction is a direct /// store to a stack slot, return the virtual or physical register number of /// the source reg along with the FrameIndex of the loaded stack slot. If /// not, return 0. This predicate must return 0 if the instruction has /// any side effects other than storing to the stack slot. - virtual unsigned isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const; + virtual unsigned isStoreToStackSlot(const MachineInstr *MI, + int &FrameIndex) const; - virtual bool isInvariantLoad(MachineInstr *MI) const; + virtual bool isInvariantLoad(const MachineInstr *MI) const; virtual bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, From resistor at mac.com Tue Nov 18 14:53:59 2008 From: resistor at mac.com (Owen Anderson) Date: Tue, 18 Nov 2008 20:53:59 -0000 Subject: [llvm-commits] [llvm] r59544 - /llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp Message-ID: <200811182053.mAIKrxNw015161@zion.cs.uiuc.edu> Author: resistor Date: Tue Nov 18 14:53:59 2008 New Revision: 59544 URL: http://llvm.org/viewvc/llvm-project?rev=59544&view=rev Log: Fix a bug introduced by my previous patch. With this change, SPEC is now clean with prealloc splitting enabled. Modified: llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp Modified: llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp?rev=59544&r1=59543&r2=59544&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp (original) +++ llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp Tue Nov 18 14:53:59 2008 @@ -233,7 +233,7 @@ unsigned &RestoreIndex) { // FIXME: Allow spill to be inserted to the beginning of the mbb. Update mbb // begin index accordingly. - MachineBasicBlock::iterator Pt = MBB->getFirstTerminator(); + MachineBasicBlock::iterator Pt = MBB->end(); unsigned EndIdx = LIs->getMBBEndIdx(MBB); // Go bottom up if RefsInMBB is empty and the end of the mbb isn't beyond From baldrick at free.fr Tue Nov 18 14:56:22 2008 From: baldrick at free.fr (Duncan Sands) Date: Tue, 18 Nov 2008 20:56:22 -0000 Subject: [llvm-commits] [llvm] r59545 - in /llvm/trunk/lib/CodeGen/SelectionDAG: LegalizeIntegerTypes.cpp LegalizeTypes.h Message-ID: <200811182056.mAIKuM5V015242@zion.cs.uiuc.edu> Author: baldrick Date: Tue Nov 18 14:56:22 2008 New Revision: 59545 URL: http://llvm.org/viewvc/llvm-project?rev=59545&view=rev Log: Simplify code using helper routines. There is not supposed to be any functionality change. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp?rev=59545&r1=59544&r2=59545&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp Tue Nov 18 14:56:22 2008 @@ -159,19 +159,14 @@ SDValue DAGTypeLegalizer::PromoteIntRes_AssertSext(SDNode *N) { // Sign-extend the new bits, and continue the assertion. - MVT OldVT = N->getValueType(0); - SDValue Op = GetPromotedInteger(N->getOperand(0)); - return DAG.getNode(ISD::AssertSext, Op.getValueType(), - DAG.getNode(ISD::SIGN_EXTEND_INREG, Op.getValueType(), Op, - DAG.getValueType(OldVT)), N->getOperand(1)); + SDValue Op = SExtPromotedInteger(N->getOperand(0)); + return DAG.getNode(ISD::AssertSext, Op.getValueType(), Op, N->getOperand(1)); } SDValue DAGTypeLegalizer::PromoteIntRes_AssertZext(SDNode *N) { // Zero the new bits, and continue the assertion. - MVT OldVT = N->getValueType(0); - SDValue Op = GetPromotedInteger(N->getOperand(0)); - return DAG.getNode(ISD::AssertZext, Op.getValueType(), - DAG.getZeroExtendInReg(Op, OldVT), N->getOperand(1)); + SDValue Op = ZExtPromotedInteger(N->getOperand(0)); + return DAG.getNode(ISD::AssertZext, Op.getValueType(), Op, N->getOperand(1)); } SDValue DAGTypeLegalizer::PromoteIntRes_Atomic1(AtomicSDNode *N) { @@ -287,11 +282,11 @@ } SDValue DAGTypeLegalizer::PromoteIntRes_CTLZ(SDNode *N) { - SDValue Op = GetPromotedInteger(N->getOperand(0)); + // Zero extend to the promoted type and do the count there. + SDValue Op = ZExtPromotedInteger(N->getOperand(0)); MVT OVT = N->getValueType(0); MVT NVT = Op.getValueType(); - // Zero extend to the promoted type and do the count there. - Op = DAG.getNode(ISD::CTLZ, NVT, DAG.getZeroExtendInReg(Op, OVT)); + Op = DAG.getNode(ISD::CTLZ, NVT, Op); // Subtract off the extra leading bits in the bigger type. return DAG.getNode(ISD::SUB, NVT, Op, DAG.getConstant(NVT.getSizeInBits() - @@ -299,11 +294,9 @@ } SDValue DAGTypeLegalizer::PromoteIntRes_CTPOP(SDNode *N) { - SDValue Op = GetPromotedInteger(N->getOperand(0)); - MVT OVT = N->getValueType(0); - MVT NVT = Op.getValueType(); // Zero extend to the promoted type and do the count there. - return DAG.getNode(ISD::CTPOP, NVT, DAG.getZeroExtendInReg(Op, OVT)); + SDValue Op = ZExtPromotedInteger(N->getOperand(0)); + return DAG.getNode(ISD::CTPOP, Op.getValueType(), Op); } SDValue DAGTypeLegalizer::PromoteIntRes_CTTZ(SDNode *N) { @@ -430,14 +423,8 @@ SDValue DAGTypeLegalizer::PromoteIntRes_SDIV(SDNode *N) { // Sign extend the input. - SDValue LHS = GetPromotedInteger(N->getOperand(0)); - SDValue RHS = GetPromotedInteger(N->getOperand(1)); - MVT VT = N->getValueType(0); - LHS = DAG.getNode(ISD::SIGN_EXTEND_INREG, LHS.getValueType(), LHS, - DAG.getValueType(VT)); - RHS = DAG.getNode(ISD::SIGN_EXTEND_INREG, RHS.getValueType(), RHS, - DAG.getValueType(VT)); - + SDValue LHS = SExtPromotedInteger(N->getOperand(0)); + SDValue RHS = SExtPromotedInteger(N->getOperand(1)); return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, RHS); } @@ -490,11 +477,8 @@ SDValue DAGTypeLegalizer::PromoteIntRes_SRA(SDNode *N) { // The input value must be properly sign extended. - MVT VT = N->getValueType(0); - MVT NVT = TLI.getTypeToTransformTo(VT); - SDValue Res = GetPromotedInteger(N->getOperand(0)); - Res = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Res, DAG.getValueType(VT)); - return DAG.getNode(ISD::SRA, NVT, Res, N->getOperand(1)); + SDValue Res = SExtPromotedInteger(N->getOperand(0)); + return DAG.getNode(ISD::SRA, Res.getValueType(), Res, N->getOperand(1)); } SDValue DAGTypeLegalizer::PromoteIntRes_SRL(SDNode *N) { @@ -526,12 +510,8 @@ SDValue DAGTypeLegalizer::PromoteIntRes_UDIV(SDNode *N) { // Zero extend the input. - SDValue LHS = GetPromotedInteger(N->getOperand(0)); - SDValue RHS = GetPromotedInteger(N->getOperand(1)); - MVT VT = N->getValueType(0); - LHS = DAG.getZeroExtendInReg(LHS, VT); - RHS = DAG.getZeroExtendInReg(RHS, VT); - + SDValue LHS = ZExtPromotedInteger(N->getOperand(0)); + SDValue RHS = ZExtPromotedInteger(N->getOperand(1)); return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, RHS); } @@ -620,13 +600,12 @@ case ISD::SELECT_CC: Res = PromoteIntOp_SELECT_CC(N, OpNo); break; case ISD::SETCC: Res = PromoteIntOp_SETCC(N, OpNo); break; case ISD::SIGN_EXTEND: Res = PromoteIntOp_SIGN_EXTEND(N); break; + case ISD::SINT_TO_FP: Res = PromoteIntOp_SINT_TO_FP(N); break; case ISD::STORE: Res = PromoteIntOp_STORE(cast(N), OpNo); break; case ISD::TRUNCATE: Res = PromoteIntOp_TRUNCATE(N); break; + case ISD::UINT_TO_FP: Res = PromoteIntOp_UINT_TO_FP(N); break; case ISD::ZERO_EXTEND: Res = PromoteIntOp_ZERO_EXTEND(N); break; - - case ISD::SINT_TO_FP: - case ISD::UINT_TO_FP: Res = PromoteIntOp_INT_TO_FP(N); break; } } @@ -652,12 +631,6 @@ /// shared among BR_CC, SELECT_CC, and SETCC handlers. void DAGTypeLegalizer::PromoteSetCCOperands(SDValue &NewLHS,SDValue &NewRHS, ISD::CondCode CCCode) { - MVT VT = NewLHS.getValueType(); - - // Get the promoted values. - NewLHS = GetPromotedInteger(NewLHS); - NewRHS = GetPromotedInteger(NewRHS); - // We have to insert explicit sign or zero extends. Note that we could // insert sign extends for ALL conditions, but zero extend is cheaper on // many machines (an AND instead of two shifts), so prefer it. @@ -672,17 +645,15 @@ // ALL of these operations will work if we either sign or zero extend // the operands (including the unsigned comparisons!). Zero extend is // usually a simpler/cheaper operation, so prefer it. - NewLHS = DAG.getZeroExtendInReg(NewLHS, VT); - NewRHS = DAG.getZeroExtendInReg(NewRHS, VT); + NewLHS = ZExtPromotedInteger(NewLHS); + NewRHS = ZExtPromotedInteger(NewRHS); break; case ISD::SETGE: case ISD::SETGT: case ISD::SETLT: case ISD::SETLE: - NewLHS = DAG.getNode(ISD::SIGN_EXTEND_INREG, NewLHS.getValueType(), NewLHS, - DAG.getValueType(VT)); - NewRHS = DAG.getNode(ISD::SIGN_EXTEND_INREG, NewRHS.getValueType(), NewRHS, - DAG.getValueType(VT)); + NewLHS = SExtPromotedInteger(NewLHS); + NewRHS = SExtPromotedInteger(NewRHS); break; } } @@ -737,11 +708,10 @@ SDValue DAGTypeLegalizer::PromoteIntOp_BUILD_PAIR(SDNode *N) { // Since the result type is legal, the operands must promote to it. MVT OVT = N->getOperand(0).getValueType(); - SDValue Lo = GetPromotedInteger(N->getOperand(0)); + SDValue Lo = ZExtPromotedInteger(N->getOperand(0)); SDValue Hi = GetPromotedInteger(N->getOperand(1)); assert(Lo.getValueType() == N->getValueType(0) && "Operand over promoted?"); - Lo = DAG.getZeroExtendInReg(Lo, OVT); Hi = DAG.getNode(ISD::SHL, N->getValueType(0), Hi, DAG.getConstant(OVT.getSizeInBits(), TLI.getShiftAmountTy())); @@ -823,24 +793,11 @@ assert(OpNo == 2 && "Different operand and result vector types?"); // Promote the index. - SDValue Idx = N->getOperand(2); - Idx = DAG.getZeroExtendInReg(GetPromotedInteger(Idx), Idx.getValueType()); + SDValue Idx = ZExtPromotedInteger(N->getOperand(2)); return DAG.UpdateNodeOperands(SDValue(N, 0), N->getOperand(0), N->getOperand(1), Idx); } -SDValue DAGTypeLegalizer::PromoteIntOp_INT_TO_FP(SDNode *N) { - SDValue In = GetPromotedInteger(N->getOperand(0)); - MVT OpVT = N->getOperand(0).getValueType(); - if (N->getOpcode() == ISD::UINT_TO_FP) - In = DAG.getZeroExtendInReg(In, OpVT); - else - In = DAG.getNode(ISD::SIGN_EXTEND_INREG, In.getValueType(), - In, DAG.getValueType(OpVT)); - - return DAG.UpdateNodeOperands(SDValue(N, 0), In); -} - SDValue DAGTypeLegalizer::PromoteIntOp_MEMBARRIER(SDNode *N) { SDValue NewOps[6]; NewOps[0] = N->getOperand(0); @@ -933,6 +890,11 @@ Op, DAG.getValueType(N->getOperand(0).getValueType())); } +SDValue DAGTypeLegalizer::PromoteIntOp_SINT_TO_FP(SDNode *N) { + return DAG.UpdateNodeOperands(SDValue(N, 0), + SExtPromotedInteger(N->getOperand(0))); +} + SDValue DAGTypeLegalizer::PromoteIntOp_STORE(StoreSDNode *N, unsigned OpNo){ assert(ISD::isUNINDEXEDStore(N) && "Indexed store during type legalization!"); SDValue Ch = N->getChain(), Ptr = N->getBasePtr(); @@ -955,6 +917,11 @@ return DAG.getNode(ISD::TRUNCATE, N->getValueType(0), Op); } +SDValue DAGTypeLegalizer::PromoteIntOp_UINT_TO_FP(SDNode *N) { + return DAG.UpdateNodeOperands(SDValue(N, 0), + ZExtPromotedInteger(N->getOperand(0))); +} + SDValue DAGTypeLegalizer::PromoteIntOp_ZERO_EXTEND(SDNode *N) { SDValue Op = GetPromotedInteger(N->getOperand(0)); Op = DAG.getNode(ISD::ANY_EXTEND, N->getValueType(0), Op); Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h?rev=59545&r1=59544&r2=59545&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h Tue Nov 18 14:56:22 2008 @@ -205,6 +205,15 @@ // Integer Promotion Support: LegalizeIntegerTypes.cpp //===--------------------------------------------------------------------===// + /// GetPromotedInteger - Given a processed operand Op which was promoted to a + /// larger integer type, this returns the promoted value. The bits of the + /// promoted value corresponding to the original type are exactly equal to Op. + /// The extra bits contain rubbish, so the promoted value may need to be zero- + /// or sign-extended from the original type before it is usable (the helpers + /// SExtPromotedInteger and ZExtPromotedInteger can do this for you). + /// For example, if Op is an i16 and was promoted to an i32, then this method + /// returns an i32, the lower 16 bits of which coincide with Op, and the upper + /// 16 bits of which contain rubbish. SDValue GetPromotedInteger(SDValue Op) { SDValue &PromotedOp = PromotedIntegers[Op]; RemapValue(PromotedOp); @@ -213,6 +222,15 @@ } void SetPromotedInteger(SDValue Op, SDValue Result); + /// SExtPromotedInteger - Get a promoted operand and sign extend it to the + /// final size. + SDValue SExtPromotedInteger(SDValue Op) { + MVT OldVT = Op.getValueType(); + Op = GetPromotedInteger(Op); + return DAG.getNode(ISD::SIGN_EXTEND_INREG, Op.getValueType(), Op, + DAG.getValueType(OldVT)); + } + /// ZExtPromotedInteger - Get a promoted operand and zero extend it to the /// final size. SDValue ZExtPromotedInteger(SDValue Op) { @@ -263,15 +281,16 @@ SDValue PromoteIntOp_CONVERT_RNDSAT(SDNode *N); SDValue PromoteIntOp_FP_EXTEND(SDNode *N); SDValue PromoteIntOp_FP_ROUND(SDNode *N); - SDValue PromoteIntOp_INT_TO_FP(SDNode *N); SDValue PromoteIntOp_INSERT_VECTOR_ELT(SDNode *N, unsigned OpNo); SDValue PromoteIntOp_MEMBARRIER(SDNode *N); SDValue PromoteIntOp_SELECT(SDNode *N, unsigned OpNo); SDValue PromoteIntOp_SELECT_CC(SDNode *N, unsigned OpNo); SDValue PromoteIntOp_SETCC(SDNode *N, unsigned OpNo); SDValue PromoteIntOp_SIGN_EXTEND(SDNode *N); + SDValue PromoteIntOp_SINT_TO_FP(SDNode *N); SDValue PromoteIntOp_STORE(StoreSDNode *N, unsigned OpNo); SDValue PromoteIntOp_TRUNCATE(SDNode *N); + SDValue PromoteIntOp_UINT_TO_FP(SDNode *N); SDValue PromoteIntOp_ZERO_EXTEND(SDNode *N); void PromoteSetCCOperands(SDValue &LHS,SDValue &RHS, ISD::CondCode Code); From clattner at apple.com Tue Nov 18 15:01:21 2008 From: clattner at apple.com (Chris Lattner) Date: Tue, 18 Nov 2008 13:01:21 -0800 Subject: [llvm-commits] [llvm] r59208 - /llvm/trunk/lib/Transforms/IPO/StripSymbols.cpp In-Reply-To: <7E35BAF1-6581-4AAC-987F-92ECE8D89DA4@apple.com> References: <200811130128.mAD1SfCx025350@zion.cs.uiuc.edu> <0EB49BD7-8E9F-4675-97FD-7583F45A8FAB@apple.com> <7D48091E-9165-4B3E-9E1E-FEA922D4DC47@apple.com> <7E35BAF1-6581-4AAC-987F-92ECE8D89DA4@apple.com> Message-ID: On Nov 18, 2008, at 11:12 AM, Devang Patel wrote: > > On Nov 17, 2008, at 5:00 PM, Chris Lattner wrote: > >> On Nov 17, 2008, at 4:45 PM, Devang Patel wrote: >>>> I don't think that matching on the names is really a sound way to >>>> go. >>>> How about just looping over all the globals, removing dead globals >>>> in >>>> the llvm.metadata section? >>> >>> >>> If it start remove dead globals then it becomes difficult to compare >>> "- >>> strip-debug -std-compile-opts" output with "-std-compile-opts - >>> strip- >>> debug" output. >> >> What other dead metadata can exist? > > > llvm.used uses llvm.metadata. It is possible that symbols marked as > attribute used does not have any use. In such cases we want to > preserve them. Until alternative mechanism is available, name matching > will be required anyway. Those don't have internal linkage. -Chris From isanbard at gmail.com Tue Nov 18 15:06:23 2008 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 18 Nov 2008 13:06:23 -0800 Subject: [llvm-commits] [llvm] r59519 - in /llvm/trunk: include/llvm/Intrinsics.td lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp lib/CodeGen/StackProtector.cpp In-Reply-To: <499BA954-77D6-4B1D-8B05-C91C4F3AB68D@apple.com> References: <200811181101.mAIB1YQb025875@zion.cs.uiuc.edu> <499BA954-77D6-4B1D-8B05-C91C4F3AB68D@apple.com> Message-ID: <16e5fdf90811181306u6e8542c0yf372ccc1adb5bd54@mail.gmail.com> On Tue, Nov 18, 2008 at 10:26 AM, Chris Lattner wrote: > > On Nov 18, 2008, at 3:01 AM, Bill Wendling wrote: > >> Author: void >> Date: Tue Nov 18 05:01:33 2008 >> New Revision: 59519 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=59519&view=rev >> Log: >> Rename stackprotector_create intrinsic to stackprotector. > > Very cool. Can you please add this to LangRef.html also? > Yup! :-) -bw From ofv at wanadoo.es Tue Nov 18 15:12:02 2008 From: ofv at wanadoo.es (Oscar Fuentes) Date: Tue, 18 Nov 2008 21:12:02 -0000 Subject: [llvm-commits] [llvm] r59546 - /llvm/trunk/include/llvm/Config/config.h.cmake Message-ID: <200811182112.mAILC2kd015836@zion.cs.uiuc.edu> Author: ofv Date: Tue Nov 18 15:12:01 2008 New Revision: 59546 URL: http://llvm.org/viewvc/llvm-project?rev=59546&view=rev Log: CMake: Remove HAVE_LT_DLOPEN from config.h.cmake because it was removed from config.h.in. Modified: llvm/trunk/include/llvm/Config/config.h.cmake Modified: llvm/trunk/include/llvm/Config/config.h.cmake URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Config/config.h.cmake?rev=59546&r1=59545&r2=59546&view=diff ============================================================================== --- llvm/trunk/include/llvm/Config/config.h.cmake (original) +++ llvm/trunk/include/llvm/Config/config.h.cmake Tue Nov 18 15:12:01 2008 @@ -212,9 +212,6 @@ /* Define to 1 if you have the `longjmp' function. */ #undef HAVE_LONGJMP -/* Define if lt_dlopen() is available on this platform */ -#undef HAVE_LT_DLOPEN - /* Define to 1 if you have the header file. */ #undef HAVE_MACH_MACH_H From gohman at apple.com Tue Nov 18 15:12:46 2008 From: gohman at apple.com (Dan Gohman) Date: Tue, 18 Nov 2008 13:12:46 -0800 Subject: [llvm-commits] discouraging use of x86_64 R12 and R13 In-Reply-To: <7D8710B0-A32E-4372-88F9-594568443D5D@apple.com> References: <7D8710B0-A32E-4372-88F9-594568443D5D@apple.com> Message-ID: <00A21D94-9816-4691-80D5-64D75BAB00F0@apple.com> On Nov 17, 2008, at 4:08 PM, Stuart Hastings wrote: > A trivial patch for a mild (and unproven) performance improvement. > (> ) > > The x86_64 R12 and R13 register encodings are related to the RBP and > RSP encodings, and thus require slightly longer instructions than the > other R8..R15 registers. Specifically, just like [RBP], the X86_64 > cannot encode [R12] directly; this is expressed as [R12+0]. In like > manner, [R13] resembles [RSP], and requires an SIB byte. > > Since R14 and R15 don't have these drawbacks, here is a patch for LLVM > to prefer them over R12 & R13. By "prefer," we really mean "allocate > R14 and R15 first." Along with Evan's comments, can you summarize the above two paragraphs in a comment in the source? Thanks, Dan From dpatel at apple.com Tue Nov 18 15:13:42 2008 From: dpatel at apple.com (Devang Patel) Date: Tue, 18 Nov 2008 21:13:42 -0000 Subject: [llvm-commits] [llvm] r59547 - /llvm/trunk/lib/Transforms/IPO/StripSymbols.cpp Message-ID: <200811182113.mAILDgno015893@zion.cs.uiuc.edu> Author: dpatel Date: Tue Nov 18 15:13:41 2008 New Revision: 59547 URL: http://llvm.org/viewvc/llvm-project?rev=59547&view=rev Log: Remove even more llvm.dbg variables. Remove all dead globals from llvm.metadata. Ignore linkonce linkage for selected llvm.dbg values. Modified: llvm/trunk/lib/Transforms/IPO/StripSymbols.cpp Modified: llvm/trunk/lib/Transforms/IPO/StripSymbols.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/StripSymbols.cpp?rev=59547&r1=59546&r2=59547&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/StripSymbols.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/StripSymbols.cpp Tue Nov 18 15:13:41 2008 @@ -114,20 +114,15 @@ return Changed; } - // Strip the symbol table of its names. static void StripTypeSymtab(TypeSymbolTable &ST) { for (TypeSymbolTable::iterator TI = ST.begin(), E = ST.end(); TI != E; ) ST.remove(TI++); } -/// StripSymbolNames - Strip symbol names. -bool StripSymbols::StripSymbolNames(Module &M) { - - if (OnlyDebugInfo) - return false; - - SmallPtrSet llvmUsedValues; +/// Find values that are marked as llvm.used. +void findUsedValues(Module &M, + SmallPtrSet& llvmUsedValues) { if (GlobalVariable *LLVMUsed = M.getGlobalVariable("llvm.used")) { llvmUsedValues.insert(LLVMUsed); // Collect values that are preserved as per explicit request. @@ -145,7 +140,17 @@ } } } - +} + +/// StripSymbolNames - Strip symbol names. +bool StripSymbols::StripSymbolNames(Module &M) { + + if (OnlyDebugInfo) + return false; + + SmallPtrSet llvmUsedValues; + findUsedValues(M, llvmUsedValues); + for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) { if (I->hasInternalLinkage() && llvmUsedValues.count(I) == 0) @@ -175,7 +180,7 @@ Function *RegionEnd = M.getFunction("llvm.dbg.region.end"); Function *Declare = M.getFunction("llvm.dbg.declare"); - std::vector DeadGlobals; + std::vector DeadConstants; // Remove all of the calls to the debugger intrinsics, and remove them from // the module. @@ -186,8 +191,8 @@ assert(CI->use_empty() && "llvm.dbg intrinsic should have void result"); CI->eraseFromParent(); if (Arg->use_empty()) - if (GlobalVariable *GV = dyn_cast(Arg)) - DeadGlobals.push_back(GV); + if (Constant *C = dyn_cast(Arg)) + DeadConstants.push_back(C); } FuncStart->eraseFromParent(); } @@ -198,8 +203,8 @@ assert(CI->use_empty() && "llvm.dbg intrinsic should have void result"); CI->eraseFromParent(); if (Arg->use_empty()) - if (GlobalVariable *GV = dyn_cast(Arg)) - DeadGlobals.push_back(GV); + if (Constant *C = dyn_cast(Arg)) + DeadConstants.push_back(C); } StopPoint->eraseFromParent(); } @@ -210,8 +215,8 @@ assert(CI->use_empty() && "llvm.dbg intrinsic should have void result"); CI->eraseFromParent(); if (Arg->use_empty()) - if (GlobalVariable *GV = dyn_cast(Arg)) - DeadGlobals.push_back(GV); + if (Constant *C = dyn_cast(Arg)) + DeadConstants.push_back(C); } RegionStart->eraseFromParent(); } @@ -222,8 +227,8 @@ assert(CI->use_empty() && "llvm.dbg intrinsic should have void result"); CI->eraseFromParent(); if (Arg->use_empty()) - if (GlobalVariable *GV = dyn_cast(Arg)) - DeadGlobals.push_back(GV); + if (Constant *C = dyn_cast(Arg)) + DeadConstants.push_back(C); } RegionEnd->eraseFromParent(); } @@ -234,12 +239,15 @@ assert(CI->use_empty() && "llvm.dbg intrinsic should have void result"); CI->eraseFromParent(); if (Arg->use_empty()) - if (GlobalVariable *GV = dyn_cast(Arg)) - DeadGlobals.push_back(GV); + if (Constant *C = dyn_cast(Arg)) + DeadConstants.push_back(C); } Declare->eraseFromParent(); } + SmallPtrSet llvmUsedValues; + findUsedValues(M, llvmUsedValues); + // llvm.dbg.compile_units and llvm.dbg.subprograms are marked as linkonce // but since we are removing all debug information, make them internal now. if (Constant *C = M.getNamedGlobal("llvm.dbg.compile_units")) @@ -249,29 +257,38 @@ if (Constant *C = M.getNamedGlobal("llvm.dbg.subprograms")) if (GlobalVariable *GV = dyn_cast(C)) GV->setLinkage(GlobalValue::InternalLinkage); + + if (Constant *C = M.getNamedGlobal("llvm.dbg.global_variables")) + if (GlobalVariable *GV = dyn_cast(C)) + GV->setLinkage(GlobalValue::InternalLinkage); // Delete all dbg variables. const Type *DbgVTy = M.getTypeByName("llvm.dbg.variable.type"); const Type *DbgGVTy = M.getTypeByName("llvm.dbg.global_variable.type"); if (DbgVTy || DbgGVTy) for (Module::global_iterator I = M.global_begin(), E = M.global_end(); - I != E; ++I) - if (GlobalVariable *GV = dyn_cast(I)) - if (GV->hasName() && GV->use_empty() - && !strncmp(GV->getNameStart(), "llvm.dbg", 8) - && (GV->getType()->getElementType() == DbgVTy - || GV->getType()->getElementType() == DbgGVTy)) - DeadGlobals.push_back(GV); + I != E; ++I) { + GlobalVariable *GV = dyn_cast(I); + if (!GV) continue; + if (GV->use_empty() && llvmUsedValues.count(I) == 0 + && (!GV->hasSection() + || strcmp(GV->getSection().c_str(), "llvm.metadata") == 0)) + DeadConstants.push_back(GV); + } - if (DeadGlobals.empty()) + if (DeadConstants.empty()) return false; // Delete any internal globals that were only used by the debugger intrinsics. - while (!DeadGlobals.empty()) { - GlobalVariable *GV = DeadGlobals.back(); - DeadGlobals.pop_back(); - if (GV->hasInternalLinkage()) - RemoveDeadConstant(GV); + while (!DeadConstants.empty()) { + Constant *C = DeadConstants.back(); + DeadConstants.pop_back(); + if (GlobalVariable *GV = dyn_cast(C)) { + if (GV->hasInternalLinkage()) + RemoveDeadConstant(GV); + } + else + RemoveDeadConstant(C); } // Remove all llvm.dbg types. From baldrick at free.fr Tue Nov 18 15:14:00 2008 From: baldrick at free.fr (Duncan Sands) Date: Tue, 18 Nov 2008 21:14:00 -0000 Subject: [llvm-commits] [llvm] r59548 - in /llvm/trunk/lib/CodeGen/SelectionDAG: LegalizeIntegerTypes.cpp LegalizeTypes.h Message-ID: <200811182114.mAILE0dd015914@zion.cs.uiuc.edu> Author: baldrick Date: Tue Nov 18 15:13:59 2008 New Revision: 59548 URL: http://llvm.org/viewvc/llvm-project?rev=59548&view=rev Log: Remove integer promotion support for FP_EXTEND and FP_ROUND. Not sure what these were doing here - probably they were sometimes (wrongly) created with integer operands somewhere that has since been fixed. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp?rev=59548&r1=59547&r2=59548&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp Tue Nov 18 15:13:59 2008 @@ -591,8 +591,6 @@ case ISD::BUILD_VECTOR: Res = PromoteIntOp_BUILD_VECTOR(N); break; case ISD::CONVERT_RNDSAT: Res = PromoteIntOp_CONVERT_RNDSAT(N); break; - case ISD::FP_EXTEND: Res = PromoteIntOp_FP_EXTEND(N); break; - case ISD::FP_ROUND: Res = PromoteIntOp_FP_ROUND(N); break; case ISD::INSERT_VECTOR_ELT: Res = PromoteIntOp_INSERT_VECTOR_ELT(N, OpNo);break; case ISD::MEMBARRIER: Res = PromoteIntOp_MEMBARRIER(N); break; @@ -764,17 +762,6 @@ N->getOperand(3), N->getOperand(4), CvtCode); } -SDValue DAGTypeLegalizer::PromoteIntOp_FP_EXTEND(SDNode *N) { - SDValue Op = GetPromotedInteger(N->getOperand(0)); - return DAG.getNode(ISD::FP_EXTEND, N->getValueType(0), Op); -} - -SDValue DAGTypeLegalizer::PromoteIntOp_FP_ROUND(SDNode *N) { - SDValue Op = GetPromotedInteger(N->getOperand(0)); - return DAG.getNode(ISD::FP_ROUND, N->getValueType(0), Op, - DAG.getIntPtrConstant(0)); -} - SDValue DAGTypeLegalizer::PromoteIntOp_INSERT_VECTOR_ELT(SDNode *N, unsigned OpNo) { if (OpNo == 1) { Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h?rev=59548&r1=59547&r2=59548&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h Tue Nov 18 15:13:59 2008 @@ -258,7 +258,7 @@ SDValue PromoteIntRes_INT_EXTEND(SDNode *N); SDValue PromoteIntRes_LOAD(LoadSDNode *N); SDValue PromoteIntRes_SDIV(SDNode *N); - SDValue PromoteIntRes_SELECT (SDNode *N); + SDValue PromoteIntRes_SELECT(SDNode *N); SDValue PromoteIntRes_SELECT_CC(SDNode *N); SDValue PromoteIntRes_SETCC(SDNode *N); SDValue PromoteIntRes_SHL(SDNode *N); @@ -279,8 +279,6 @@ SDValue PromoteIntOp_BRCOND(SDNode *N, unsigned OpNo); SDValue PromoteIntOp_BUILD_VECTOR(SDNode *N); SDValue PromoteIntOp_CONVERT_RNDSAT(SDNode *N); - SDValue PromoteIntOp_FP_EXTEND(SDNode *N); - SDValue PromoteIntOp_FP_ROUND(SDNode *N); SDValue PromoteIntOp_INSERT_VECTOR_ELT(SDNode *N, unsigned OpNo); SDValue PromoteIntOp_MEMBARRIER(SDNode *N); SDValue PromoteIntOp_SELECT(SDNode *N, unsigned OpNo); From gohman at apple.com Tue Nov 18 15:14:44 2008 From: gohman at apple.com (Dan Gohman) Date: Tue, 18 Nov 2008 21:14:44 -0000 Subject: [llvm-commits] [llvm] r59549 - /llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Message-ID: <200811182114.mAILEiX9015969@zion.cs.uiuc.edu> Author: djg Date: Tue Nov 18 15:14:44 2008 New Revision: 59549 URL: http://llvm.org/viewvc/llvm-project?rev=59549&view=rev Log: Update a comment to reflect the current code. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp?rev=59549&r1=59548&r2=59549&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Tue Nov 18 15:14:44 2008 @@ -119,9 +119,8 @@ } #endif - // Compute how many cycles it will be before this actually becomes - // available. This is the max of the start time of all predecessors plus - // their latencies. + // Compute the cycle when this SUnit actually becomes available. This + // is the max of the start time of all predecessors plus their latencies. // If this is a token edge, we don't need to wait for the latency of the // preceeding instruction (e.g. a long-latency load) unless there is also // some other data dependence. From gohman at apple.com Tue Nov 18 15:22:20 2008 From: gohman at apple.com (Dan Gohman) Date: Tue, 18 Nov 2008 21:22:20 -0000 Subject: [llvm-commits] [llvm] r59550 - in /llvm/trunk/lib/CodeGen/SelectionDAG: ScheduleDAGFast.cpp ScheduleDAGRRList.cpp Message-ID: <200811182122.mAILMKtB016224@zion.cs.uiuc.edu> Author: djg Date: Tue Nov 18 15:22:20 2008 New Revision: 59550 URL: http://llvm.org/viewvc/llvm-project?rev=59550&view=rev Log: Tidy up ScheduleNodeBottomUp methods, and make them more consistent with ScheduleNodeTopDown methods. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp?rev=59550&r1=59549&r2=59550&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp Tue Nov 18 15:22:20 2008 @@ -161,7 +161,9 @@ void ScheduleDAGFast::ScheduleNodeBottomUp(SUnit *SU, unsigned CurCycle) { DOUT << "*** Scheduling [" << CurCycle << "]: "; DEBUG(SU->dump(this)); + SU->Cycle = CurCycle; + Sequence.push_back(SU); // Bottom up: release predecessors for (SUnit::pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); @@ -589,10 +591,8 @@ if (!CurSU) Sequence.push_back(0); - else { + else ScheduleNodeBottomUp(CurSU, CurCycle); - Sequence.push_back(CurSU); - } ++CurCycle; } Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp?rev=59550&r1=59549&r2=59550&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Tue Nov 18 15:22:20 2008 @@ -302,9 +302,9 @@ void ScheduleDAGRRList::ScheduleNodeBottomUp(SUnit *SU, unsigned CurCycle) { DOUT << "*** Scheduling [" << CurCycle << "]: "; DEBUG(SU->dump(this)); - SU->Cycle = CurCycle; - AvailableQueue->ScheduledNode(SU); + SU->Cycle = CurCycle; + Sequence.push_back(SU); // Bottom up: release predecessors for (SUnit::pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); @@ -339,6 +339,7 @@ } SU->isScheduled = true; + AvailableQueue->ScheduledNode(SU); } /// CapturePred - This does the opposite of ReleasePred. Since SU is being @@ -1060,10 +1061,8 @@ if (!CurSU) Sequence.push_back(0); - else { + else ScheduleNodeBottomUp(CurSU, CurCycle); - Sequence.push_back(CurSU); - } ++CurCycle; } @@ -1193,9 +1192,8 @@ if (!CurSU) Sequence.push_back(0); - else { + else ScheduleNodeTopDown(CurSU, CurCycle); - } ++CurCycle; } From gohman at apple.com Tue Nov 18 15:29:15 2008 From: gohman at apple.com (Dan Gohman) Date: Tue, 18 Nov 2008 21:29:15 -0000 Subject: [llvm-commits] [llvm] r59551 - in /llvm/trunk/lib/Target/X86: X86Instr64bit.td X86InstrInfo.td Message-ID: <200811182129.mAILTFwN016430@zion.cs.uiuc.edu> Author: djg Date: Tue Nov 18 15:29:14 2008 New Revision: 59551 URL: http://llvm.org/viewvc/llvm-project?rev=59551&view=rev Log: Don't set neverHasSideEffects on x86's divide instructions, since they trap on divide-by-zero, and this side effect is otherwise unmodeled. Modified: llvm/trunk/lib/Target/X86/X86Instr64bit.td llvm/trunk/lib/Target/X86/X86InstrInfo.td Modified: llvm/trunk/lib/Target/X86/X86Instr64bit.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Instr64bit.td?rev=59551&r1=59550&r2=59551&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86Instr64bit.td (original) +++ llvm/trunk/lib/Target/X86/X86Instr64bit.td Tue Nov 18 15:29:14 2008 @@ -474,7 +474,6 @@ } // Defs = [EFLAGS] // Unsigned division / remainder -let neverHasSideEffects = 1 in { let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in { def DIV64r : RI<0xF7, MRM6r, (outs), (ins GR64:$src), // RDX:RAX/r64 = RAX,RDX "div{q}\t$src", []>; @@ -488,7 +487,6 @@ "idiv{q}\t$src", []>; } } -} // Unary instructions let Defs = [EFLAGS], CodeSize = 2 in { Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=59551&r1=59550&r2=59551&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Tue Nov 18 15:29:14 2008 @@ -747,6 +747,7 @@ def IMUL32m : I<0xF7, MRM5m, (outs), (ins i32mem:$src), "imul{l}\t$src", []>; // EAX,EDX = EAX*[mem32] } +} // neverHasSideEffects // unsigned division/remainder let Defs = [AL,AH,EFLAGS], Uses = [AX] in @@ -791,7 +792,6 @@ def IDIV32m: I<0xF7, MRM7m, (outs), (ins i32mem:$src), // EDX:EAX/[mem32] = EAX,EDX "idiv{l}\t$src", []>; } -} // neverHasSideEffects //===----------------------------------------------------------------------===// // Two address Instructions. From dpatel at apple.com Tue Nov 18 15:34:39 2008 From: dpatel at apple.com (Devang Patel) Date: Tue, 18 Nov 2008 21:34:39 -0000 Subject: [llvm-commits] [llvm] r59552 - in /llvm/trunk: include/llvm/LinkAllPasses.h include/llvm/Transforms/IPO.h lib/Transforms/IPO/StripSymbols.cpp Message-ID: <200811182134.mAILYd4O016646@zion.cs.uiuc.edu> Author: dpatel Date: Tue Nov 18 15:34:39 2008 New Revision: 59552 URL: http://llvm.org/viewvc/llvm-project?rev=59552&view=rev Log: Add new helper pass that strips all symbol names except debugging information. This pass makes it easier to test wheter debugging info. influences optimization passes or not. Modified: llvm/trunk/include/llvm/LinkAllPasses.h llvm/trunk/include/llvm/Transforms/IPO.h llvm/trunk/lib/Transforms/IPO/StripSymbols.cpp Modified: llvm/trunk/include/llvm/LinkAllPasses.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/LinkAllPasses.h?rev=59552&r1=59551&r2=59552&view=diff ============================================================================== --- llvm/trunk/include/llvm/LinkAllPasses.h (original) +++ llvm/trunk/include/llvm/LinkAllPasses.h Tue Nov 18 15:34:39 2008 @@ -102,6 +102,7 @@ (void) llvm::createSimplifyHalfPowrLibCallsPass(); (void) llvm::createSingleLoopExtractorPass(); (void) llvm::createStripSymbolsPass(); + (void) llvm::createStripNonDebugSymbolsPass(); (void) llvm::createStripDeadPrototypesPass(); (void) llvm::createTailCallEliminationPass(); (void) llvm::createTailDuplicationPass(); Modified: llvm/trunk/include/llvm/Transforms/IPO.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/IPO.h?rev=59552&r1=59551&r2=59552&view=diff ============================================================================== --- llvm/trunk/include/llvm/Transforms/IPO.h (original) +++ llvm/trunk/include/llvm/Transforms/IPO.h Tue Nov 18 15:34:39 2008 @@ -34,6 +34,13 @@ ModulePass *createStripSymbolsPass(bool OnlyDebugInfo = false); //===----------------------------------------------------------------------===// +// +// These functions removes symbols from functions and modules. +// Only debugging information is not removed. +// +ModulePass *createStripNonDebugSymbolsPass(); + +//===----------------------------------------------------------------------===// /// createLowerSetJmpPass - This function lowers the setjmp/longjmp intrinsics /// to invoke/unwind instructions. This should really be part of the C/C++ /// front-end, but it's so much easier to write transformations in LLVM proper. Modified: llvm/trunk/lib/Transforms/IPO/StripSymbols.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/StripSymbols.cpp?rev=59552&r1=59551&r2=59552&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/StripSymbols.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/StripSymbols.cpp Tue Nov 18 15:34:39 2008 @@ -40,13 +40,18 @@ explicit StripSymbols(bool ODI = false) : ModulePass(&ID), OnlyDebugInfo(ODI) {} - /// StripSymbolNames - Strip symbol names. - bool StripSymbolNames(Module &M); + virtual bool runOnModule(Module &M); + + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesAll(); + } + }; - // StripDebugInfo - Strip debug info in the module if it exists. - // To do this, we remove llvm.dbg.func.start, llvm.dbg.stoppoint, and - // llvm.dbg.region.end calls, and any globals they point to if now dead. - bool StripDebugInfo(Module &M); + class VISIBILITY_HIDDEN StripNonDebugSymbols : public ModulePass { + public: + static char ID; // Pass identification, replacement for typeid + explicit StripNonDebugSymbols() + : ModulePass(&ID) {} virtual bool runOnModule(Module &M); @@ -64,6 +69,14 @@ return new StripSymbols(OnlyDebugInfo); } +char StripNonDebugSymbols::ID = 0; +static RegisterPass +Y("strip-nondebug", "Strip all symbols, except dbg symbols, from a module"); + +ModulePass *llvm::createStripNonDebugSymbolsPass() { + return new StripNonDebugSymbols(); +} + /// OnlyUsedBy - Return true if V is only used by Usr. static bool OnlyUsedBy(Value *V, Value *Usr) { for(Value::use_iterator I = V->use_begin(), E = V->use_end(); I != E; ++I) { @@ -96,28 +109,26 @@ // Strip the symbol table of its names. // -static void StripSymtab(ValueSymbolTable &ST) { +static void StripSymtab(ValueSymbolTable &ST, bool PreserveDbgInfo) { for (ValueSymbolTable::iterator VI = ST.begin(), VE = ST.end(); VI != VE; ) { Value *V = VI->getValue(); ++VI; if (!isa(V) || cast(V)->hasInternalLinkage()) { - // Set name to "", removing from symbol table! - V->setName(""); + if (!PreserveDbgInfo || strncmp(V->getNameStart(), "llvm.dbg", 8)) + // Set name to "", removing from symbol table! + V->setName(""); } } } -bool StripSymbols::runOnModule(Module &M) { - bool Changed = false; - Changed |= StripDebugInfo(M); - Changed |= StripSymbolNames(M); - return Changed; -} - // Strip the symbol table of its names. -static void StripTypeSymtab(TypeSymbolTable &ST) { - for (TypeSymbolTable::iterator TI = ST.begin(), E = ST.end(); TI != E; ) - ST.remove(TI++); +static void StripTypeSymtab(TypeSymbolTable &ST, bool PreserveDbgInfo) { + for (TypeSymbolTable::iterator TI = ST.begin(), E = ST.end(); TI != E; ) { + if (PreserveDbgInfo && strncmp(TI->first.c_str(), "llvm.dbg", 8) == 0) + ++TI; + else + ST.remove(TI++); + } } /// Find values that are marked as llvm.used. @@ -143,10 +154,7 @@ } /// StripSymbolNames - Strip symbol names. -bool StripSymbols::StripSymbolNames(Module &M) { - - if (OnlyDebugInfo) - return false; +bool StripSymbolNames(Module &M, bool PreserveDbgInfo) { SmallPtrSet llvmUsedValues; findUsedValues(M, llvmUsedValues); @@ -154,17 +162,19 @@ for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) { if (I->hasInternalLinkage() && llvmUsedValues.count(I) == 0) - I->setName(""); // Internal symbols can't participate in linkage + if (!PreserveDbgInfo || strncmp(I->getNameStart(), "llvm.dbg", 8)) + I->setName(""); // Internal symbols can't participate in linkage } for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { if (I->hasInternalLinkage() && llvmUsedValues.count(I) == 0) - I->setName(""); // Internal symbols can't participate in linkage - StripSymtab(I->getValueSymbolTable()); + if (!PreserveDbgInfo || strncmp(I->getNameStart(), "llvm.dbg", 8)) + I->setName(""); // Internal symbols can't participate in linkage + StripSymtab(I->getValueSymbolTable(), PreserveDbgInfo); } // Remove all names from types. - StripTypeSymtab(M.getTypeSymbolTable()); + StripTypeSymtab(M.getTypeSymbolTable(), PreserveDbgInfo); return true; } @@ -172,7 +182,7 @@ // StripDebugInfo - Strip debug info in the module if it exists. // To do this, we remove llvm.dbg.func.start, llvm.dbg.stoppoint, and // llvm.dbg.region.end calls, and any globals they point to if now dead. -bool StripSymbols::StripDebugInfo(Module &M) { +bool StripDebugInfo(Module &M) { Function *FuncStart = M.getFunction("llvm.dbg.func.start"); Function *StopPoint = M.getFunction("llvm.dbg.stoppoint"); @@ -302,3 +312,16 @@ return true; } + +bool StripSymbols::runOnModule(Module &M) { + bool Changed = false; + Changed |= StripDebugInfo(M); + if (!OnlyDebugInfo) + Changed |= StripSymbolNames(M, false); + return Changed; +} + +bool StripNonDebugSymbols::runOnModule(Module &M) { + return StripSymbolNames(M, true); +} + From isanbard at gmail.com Tue Nov 18 16:10:53 2008 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 18 Nov 2008 22:10:53 -0000 Subject: [llvm-commits] [llvm] r59557 - /llvm/trunk/docs/LangRef.html Message-ID: <200811182210.mAIMArwd018042@zion.cs.uiuc.edu> Author: void Date: Tue Nov 18 16:10:53 2008 New Revision: 59557 URL: http://llvm.org/viewvc/llvm-project?rev=59557&view=rev Log: Documentation for the llvm.stackprotector intrinsic. Modified: llvm/trunk/docs/LangRef.html Modified: llvm/trunk/docs/LangRef.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=59557&r1=59556&r2=59557&view=diff ============================================================================== --- llvm/trunk/docs/LangRef.html (original) +++ llvm/trunk/docs/LangRef.html Tue Nov 18 16:10:53 2008 @@ -214,23 +214,28 @@
  • 'llvm.init.trampoline' Intrinsic
  • -
  • Atomic intrinsics -
      -
    1. llvm.memory_barrier
    2. -
    3. llvm.atomic.cmp.swap
    4. -
    5. llvm.atomic.swap
    6. -
    7. llvm.atomic.load.add
    8. -
    9. llvm.atomic.load.sub
    10. -
    11. llvm.atomic.load.and
    12. -
    13. llvm.atomic.load.nand
    14. -
    15. llvm.atomic.load.or
    16. -
    17. llvm.atomic.load.xor
    18. -
    19. llvm.atomic.load.max
    20. -
    21. llvm.atomic.load.min
    22. -
    23. llvm.atomic.load.umax
    24. -
    25. llvm.atomic.load.umin
    26. -
    -
  • +
  • Stack Protector Intrinsic +
      +
    1. 'llvm.stackprotector' Intrinsic
    2. +
    +
  • +
  • Atomic intrinsics +
      +
    1. llvm.memory_barrier
    2. +
    3. llvm.atomic.cmp.swap
    4. +
    5. llvm.atomic.swap
    6. +
    7. llvm.atomic.load.add
    8. +
    9. llvm.atomic.load.sub
    10. +
    11. llvm.atomic.load.and
    12. +
    13. llvm.atomic.load.nand
    14. +
    15. llvm.atomic.load.or
    16. +
    17. llvm.atomic.load.xor
    18. +
    19. llvm.atomic.load.max
    20. +
    21. llvm.atomic.load.min
    22. +
    23. llvm.atomic.load.umax
    24. +
    25. llvm.atomic.load.umin
    26. +
    +
  • General intrinsics
    1. @@ -5804,6 +5809,54 @@ + +
      +

      + This intrinsic is used when stack protectors are required. LLVM generates a + call to load the randomized stack protector guard's value. The intrinsic is + used so that LLVM can ensure that the stack guard is placed onto the stack in + the appropriate place—before local variables are allocated on the stack. +

      +
      + + + +
      +
      Syntax:
      +
      +declare void @llvm.stackprotector( i8* <guard>, i8** <slot> )
      +
      +
      +
      Overview:
      +

      + The llvm.stackprotector intrinsic takes the guard and stores + it onto the stack at slot. The stack slot is adjusted to ensure that + it's before local variables are allocated on the stack. +

      +
      Arguments:
      +

      + The llvm.stackprotector intrinsic requires two pointer arguments. The + first argument is the value loaded from the stack guard + @__stack_chk_guard. The second variable is an alloca that + has enough space to hold the value of the guard. +

      +
      Semantics:
      +

      + This intrinsic causes the prologue/epilogue inserter to force the position of + the AllocaInst stack slot to be before local variables on the + stack. This is to ensure that if a local variable on the stack is overwritten, + it will destroy the value of the guard. When the function exits, the guard on + the stack is checked against the original guard. If they're different, then + the program aborts by calling the __stack_chk_fail() function. +

      +
      + + + From evan.cheng at apple.com Tue Nov 18 16:27:14 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 18 Nov 2008 22:27:14 -0000 Subject: [llvm-commits] [llvm] r59558 - /llvm/trunk/include/llvm/CodeGen/SelectionDAG.h Message-ID: <200811182227.mAIMREMi018565@zion.cs.uiuc.edu> Author: evancheng Date: Tue Nov 18 16:27:13 2008 New Revision: 59558 URL: http://llvm.org/viewvc/llvm-project?rev=59558&view=rev Log: Fix indentation. Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAG.h Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAG.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAG.h?rev=59558&r1=59557&r2=59558&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/SelectionDAG.h (original) +++ llvm/trunk/include/llvm/CodeGen/SelectionDAG.h Tue Nov 18 16:27:13 2008 @@ -398,35 +398,34 @@ SDValue getNode(unsigned Opcode, SDVTList VTs, SDValue N); SDValue getNode(unsigned Opcode, SDVTList VTs, SDValue N1, SDValue N2); SDValue getNode(unsigned Opcode, SDVTList VTs, - SDValue N1, SDValue N2, SDValue N3); + SDValue N1, SDValue N2, SDValue N3); SDValue getNode(unsigned Opcode, SDVTList VTs, - SDValue N1, SDValue N2, SDValue N3, SDValue N4); + SDValue N1, SDValue N2, SDValue N3, SDValue N4); SDValue getNode(unsigned Opcode, SDVTList VTs, - SDValue N1, SDValue N2, SDValue N3, SDValue N4, - SDValue N5); + SDValue N1, SDValue N2, SDValue N3, SDValue N4, + SDValue N5); SDValue getNode(unsigned Opcode, SDVTList VTs, - const SDValue *Ops, unsigned NumOps); + const SDValue *Ops, unsigned NumOps); SDValue getMemcpy(SDValue Chain, SDValue Dst, SDValue Src, - SDValue Size, unsigned Align, - bool AlwaysInline, - const Value *DstSV, uint64_t DstSVOff, - const Value *SrcSV, uint64_t SrcSVOff); + SDValue Size, unsigned Align, bool AlwaysInline, + const Value *DstSV, uint64_t DstSVOff, + const Value *SrcSV, uint64_t SrcSVOff); SDValue getMemmove(SDValue Chain, SDValue Dst, SDValue Src, - SDValue Size, unsigned Align, - const Value *DstSV, uint64_t DstOSVff, - const Value *SrcSV, uint64_t SrcSVOff); + SDValue Size, unsigned Align, + const Value *DstSV, uint64_t DstOSVff, + const Value *SrcSV, uint64_t SrcSVOff); SDValue getMemset(SDValue Chain, SDValue Dst, SDValue Src, - SDValue Size, unsigned Align, - const Value *DstSV, uint64_t DstSVOff); + SDValue Size, unsigned Align, + const Value *DstSV, uint64_t DstSVOff); /// getSetCC - Helper function to make it easier to build SetCC's if you just /// have an ISD::CondCode instead of an SDValue. /// SDValue getSetCC(MVT VT, SDValue LHS, SDValue RHS, - ISD::CondCode Cond) { + ISD::CondCode Cond) { return getNode(ISD::SETCC, VT, LHS, RHS, getCondCode(Cond)); } @@ -434,7 +433,7 @@ /// if you just have an ISD::CondCode instead of an SDValue. /// SDValue getVSetCC(MVT VT, SDValue LHS, SDValue RHS, - ISD::CondCode Cond) { + ISD::CondCode Cond) { return getNode(ISD::VSETCC, VT, LHS, RHS, getCondCode(Cond)); } @@ -442,7 +441,7 @@ /// just have an ISD::CondCode instead of an SDValue. /// SDValue getSelectCC(SDValue LHS, SDValue RHS, - SDValue True, SDValue False, ISD::CondCode Cond) { + SDValue True, SDValue False, ISD::CondCode Cond) { return getNode(ISD::SELECT_CC, True.getValueType(), LHS, RHS, True, False, getCondCode(Cond)); } @@ -450,19 +449,19 @@ /// getVAArg - VAArg produces a result and token chain, and takes a pointer /// and a source value as input. SDValue getVAArg(MVT VT, SDValue Chain, SDValue Ptr, - SDValue SV); + SDValue SV); /// getAtomic - Gets a node for an atomic op, produces result and chain and /// takes 3 operands SDValue getAtomic(unsigned Opcode, SDValue Chain, SDValue Ptr, - SDValue Cmp, SDValue Swp, const Value* PtrVal, - unsigned Alignment=0); + SDValue Cmp, SDValue Swp, const Value* PtrVal, + unsigned Alignment=0); /// getAtomic - Gets a node for an atomic op, produces result and chain and /// takes 2 operands. SDValue getAtomic(unsigned Opcode, SDValue Chain, SDValue Ptr, - SDValue Val, const Value* PtrVal, - unsigned Alignment = 0); + SDValue Val, const Value* PtrVal, + unsigned Alignment = 0); /// getMemIntrinsicNode - Creates a MemIntrinsicNode that may produce a /// result and takes a list of operands. @@ -482,7 +481,7 @@ /// getMergeValues - Create a MERGE_VALUES node from the given operands. /// Allowed to return something different (and simpler) if Simplify is true. SDValue getMergeValues(const SDValue *Ops, unsigned NumOps, - bool Simplify = true); + bool Simplify = true); /// getMergeValues - Create a MERGE_VALUES node from the given types and ops. /// Allowed to return something different (and simpler) if Simplify is true. From evan.cheng at apple.com Tue Nov 18 16:28:38 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 18 Nov 2008 22:28:38 -0000 Subject: [llvm-commits] [llvm] r59559 - in /llvm/trunk: lib/CodeGen/RegisterScavenging.cpp test/CodeGen/ARM/2008-11-18-ScavengerAssert.ll Message-ID: <200811182228.mAIMScSJ018630@zion.cs.uiuc.edu> Author: evancheng Date: Tue Nov 18 16:28:38 2008 New Revision: 59559 URL: http://llvm.org/viewvc/llvm-project?rev=59559&view=rev Log: Register scavenger should process early clobber defs first. A dead early clobber def should not interfere with a normal def which happens one slot later. Added: llvm/trunk/test/CodeGen/ARM/2008-11-18-ScavengerAssert.ll Modified: llvm/trunk/lib/CodeGen/RegisterScavenging.cpp Modified: llvm/trunk/lib/CodeGen/RegisterScavenging.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegisterScavenging.cpp?rev=59559&r1=59558&r2=59559&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/RegisterScavenging.cpp (original) +++ llvm/trunk/lib/CodeGen/RegisterScavenging.cpp Tue Nov 18 16:28:38 2008 @@ -190,47 +190,61 @@ if (TID.isTerminator()) restoreScavengedReg(); - // Process uses first. - BitVector ChangedRegs(NumPhysRegs); + bool IsImpDef = MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF; + + // Separate register operands into 3 classes: uses, defs, earlyclobbers. + SmallVector UseMOs; + SmallVector DefMOs; + SmallVector EarlyClobberMOs; for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { const MachineOperand &MO = MI->getOperand(i); - if (!MO.isReg() || !MO.isUse()) + if (!MO.isReg() || MO.getReg() == 0) continue; + if (MO.isUse()) + UseMOs.push_back(&MO); + else if (MO.isEarlyClobber()) + EarlyClobberMOs.push_back(&MO); + else + DefMOs.push_back(&MO); + } + // Process uses first. + BitVector UseRegs(NumPhysRegs); + for (unsigned i = 0, e = UseMOs.size(); i != e; ++i) { + const MachineOperand &MO = *UseMOs[i]; unsigned Reg = MO.getReg(); - if (Reg == 0) continue; if (!isUsed(Reg)) { // Register has been scavenged. Restore it! - if (Reg != ScavengedReg) - assert(false && "Using an undefined register!"); - else + if (Reg == ScavengedReg) restoreScavengedReg(); + else + assert(false && "Using an undefined register!"); } if (MO.isKill() && !isReserved(Reg)) { - ChangedRegs.set(Reg); + UseRegs.set(Reg); - // Mark sub-registers as changed if they aren't defined in the same - // instruction. + // Mark sub-registers as used. for (const unsigned *SubRegs = TRI->getSubRegisters(Reg); unsigned SubReg = *SubRegs; ++SubRegs) - ChangedRegs.set(SubReg); + UseRegs.set(SubReg); } } // Change states of all registers after all the uses are processed to guard // against multiple uses. - setUnused(ChangedRegs); - - // Process defs. - bool IsImpDef = MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF; - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { - const MachineOperand &MO = MI->getOperand(i); - - if (!MO.isReg() || !MO.isDef()) - continue; + setUnused(UseRegs); + // Process early clobber defs then process defs. We can have a early clobber + // that is dead, it should not conflict with a def that happens one "slot" + // (see InstrSlots in LiveIntervalAnalysis.h) later. + unsigned NumECs = EarlyClobberMOs.size(); + unsigned NumDefs = DefMOs.size(); + + for (unsigned i = 0, e = NumECs + NumDefs; i != e; ++i) { + const MachineOperand &MO = (i < NumECs) + ? *EarlyClobberMOs[i] : *DefMOs[i-NumECs]; unsigned Reg = MO.getReg(); // If it's dead upon def, then it is now free. @@ -282,7 +296,7 @@ } // Process uses. - BitVector ChangedRegs(NumPhysRegs); + BitVector UseRegs(NumPhysRegs); for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { const MachineOperand &MO = MI->getOperand(i); if (!MO.isReg() || !MO.isUse()) @@ -291,14 +305,14 @@ if (Reg == 0) continue; assert(isUnused(Reg) || isReserved(Reg)); - ChangedRegs.set(Reg); + UseRegs.set(Reg); // Set the sub-registers as "used". for (const unsigned *SubRegs = TRI->getSubRegisters(Reg); unsigned SubReg = *SubRegs; ++SubRegs) - ChangedRegs.set(SubReg); + UseRegs.set(SubReg); } - setUsed(ChangedRegs); + setUsed(UseRegs); } void RegScavenger::getRegsUsed(BitVector &used, bool includeReserved) { Added: llvm/trunk/test/CodeGen/ARM/2008-11-18-ScavengerAssert.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/2008-11-18-ScavengerAssert.ll?rev=59559&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/ARM/2008-11-18-ScavengerAssert.ll (added) +++ llvm/trunk/test/CodeGen/ARM/2008-11-18-ScavengerAssert.ll Tue Nov 18 16:28:38 2008 @@ -0,0 +1,16 @@ +; RUN: llvm-as < %s | llc -march=arm -mattr=+v6,+vfp2 + +define hidden i64 @__muldi3(i64 %u, i64 %v) nounwind { +entry: + %0 = trunc i64 %u to i32 ; [#uses=1] + %asmtmp = tail call { i32, i32, i32, i32, i32 } asm "@ Inlined umul_ppmm\0A\09mov\09$2, $5, lsr #16\0A\09mov\09$0, $6, lsr #16\0A\09bic\09$3, $5, $2, lsl #16\0A\09bic\09$4, $6, $0, lsl #16\0A\09mul\09$1, $3, $4\0A\09mul\09$4, $2, $4\0A\09mul\09$3, $0, $3\0A\09mul\09$0, $2, $0\0A\09adds\09$3, $4, $3\0A\09addcs\09$0, $0, #65536\0A\09adds\09$1, $1, $3, lsl #16\0A\09adc\09$0, $0, $3, lsr #16", "=&r,=r,=&r,=&r,=r,r,r,~{cc}"(i32 %0, i32 0) nounwind ; <{ i32, i32, i32, i32, i32 }> [#uses=1] + %asmresult1 = extractvalue { i32, i32, i32, i32, i32 } %asmtmp, 1 ; [#uses=1] + %asmresult116 = zext i32 %asmresult1 to i64 ; [#uses=1] + %asmresult116.ins = or i64 0, %asmresult116 ; [#uses=1] + %1 = lshr i64 %v, 32 ; [#uses=1] + %2 = mul i64 %1, %u ; [#uses=1] + %3 = add i64 %2, 0 ; [#uses=1] + %4 = shl i64 %3, 32 ; [#uses=1] + %5 = add i64 %asmresult116.ins, %4 ; [#uses=1] + ret i64 %5 +} From evan.cheng at apple.com Tue Nov 18 16:56:19 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 18 Nov 2008 22:56:19 -0000 Subject: [llvm-commits] [llvm] r59562 - /llvm/trunk/lib/CodeGen/RegisterScavenging.cpp Message-ID: <200811182256.mAIMuJ5P019774@zion.cs.uiuc.edu> Author: evancheng Date: Tue Nov 18 16:56:19 2008 New Revision: 59562 URL: http://llvm.org/viewvc/llvm-project?rev=59562&view=rev Log: We also need to keep the operand index for two address check. Modified: llvm/trunk/lib/CodeGen/RegisterScavenging.cpp Modified: llvm/trunk/lib/CodeGen/RegisterScavenging.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegisterScavenging.cpp?rev=59562&r1=59561&r2=59562&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/RegisterScavenging.cpp (original) +++ llvm/trunk/lib/CodeGen/RegisterScavenging.cpp Tue Nov 18 16:56:19 2008 @@ -193,25 +193,25 @@ bool IsImpDef = MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF; // Separate register operands into 3 classes: uses, defs, earlyclobbers. - SmallVector UseMOs; - SmallVector DefMOs; - SmallVector EarlyClobberMOs; + SmallVector, 4> UseMOs; + SmallVector, 4> DefMOs; + SmallVector, 4> EarlyClobberMOs; for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { const MachineOperand &MO = MI->getOperand(i); if (!MO.isReg() || MO.getReg() == 0) continue; if (MO.isUse()) - UseMOs.push_back(&MO); + UseMOs.push_back(std::make_pair(&MO,i)); else if (MO.isEarlyClobber()) - EarlyClobberMOs.push_back(&MO); + EarlyClobberMOs.push_back(std::make_pair(&MO,i)); else - DefMOs.push_back(&MO); + DefMOs.push_back(std::make_pair(&MO,i)); } // Process uses first. BitVector UseRegs(NumPhysRegs); for (unsigned i = 0, e = UseMOs.size(); i != e; ++i) { - const MachineOperand &MO = *UseMOs[i]; + const MachineOperand MO = *UseMOs[i].first; unsigned Reg = MO.getReg(); if (!isUsed(Reg)) { @@ -244,7 +244,9 @@ for (unsigned i = 0, e = NumECs + NumDefs; i != e; ++i) { const MachineOperand &MO = (i < NumECs) - ? *EarlyClobberMOs[i] : *DefMOs[i-NumECs]; + ? *EarlyClobberMOs[i].first : *DefMOs[i-NumECs].first; + unsigned Idx = (i < NumECs) + ? EarlyClobberMOs[i].second : DefMOs[i-NumECs].second; unsigned Reg = MO.getReg(); // If it's dead upon def, then it is now free. @@ -254,7 +256,7 @@ } // Skip two-address destination operand. - if (TID.findTiedToSrcOperand(i) != -1) { + if (TID.findTiedToSrcOperand(Idx) != -1) { assert(isUsed(Reg) && "Using an undefined register!"); continue; } From isanbard at gmail.com Tue Nov 18 17:09:31 2008 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 18 Nov 2008 23:09:31 -0000 Subject: [llvm-commits] [llvm] r59563 - /llvm/trunk/lib/VMCore/Verifier.cpp Message-ID: <200811182309.mAIN9VQv020509@zion.cs.uiuc.edu> Author: void Date: Tue Nov 18 17:09:31 2008 New Revision: 59563 URL: http://llvm.org/viewvc/llvm-project?rev=59563&view=rev Log: Verify that the second parameter of the stacprotector intrinsic is an alloca instruction. Modified: llvm/trunk/lib/VMCore/Verifier.cpp Modified: llvm/trunk/lib/VMCore/Verifier.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Verifier.cpp?rev=59563&r1=59562&r2=59563&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Verifier.cpp (original) +++ llvm/trunk/lib/VMCore/Verifier.cpp Tue Nov 18 17:09:31 2008 @@ -1374,6 +1374,11 @@ "invalid arguments to llvm.prefetch", &CI); break; + case Intrinsic::stackprotector: + Assert1(isa(CI.getOperand(2)), + "llvm.stackprotector parameter #2 must resolve to an alloca.", + &CI); + break; } } From ofv at wanadoo.es Tue Nov 18 17:45:21 2008 From: ofv at wanadoo.es (Oscar Fuentes) Date: Tue, 18 Nov 2008 23:45:21 -0000 Subject: [llvm-commits] [llvm] r59565 - in /llvm/trunk: CMakeLists.txt cmake/config-ix.cmake Message-ID: <200811182345.mAINjLEB022910@zion.cs.uiuc.edu> Author: ofv Date: Tue Nov 18 17:45:21 2008 New Revision: 59565 URL: http://llvm.org/viewvc/llvm-project?rev=59565&view=rev Log: CMake: Option for enabling/disabling threads. Modified: llvm/trunk/CMakeLists.txt llvm/trunk/cmake/config-ix.cmake Modified: llvm/trunk/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/CMakeLists.txt?rev=59565&r1=59564&r2=59565&view=diff ============================================================================== --- llvm/trunk/CMakeLists.txt (original) +++ llvm/trunk/CMakeLists.txt Tue Nov 18 17:45:21 2008 @@ -50,6 +50,8 @@ CACHE STRING "Semicolon-separated list of targets to build, or \"all\".") endif( MSVC ) +option(LLVM_ENABLE_THREADS "Use threads if available." ON) + if( LLVM_TARGETS_TO_BUILD STREQUAL "all" ) set( LLVM_TARGETS_TO_BUILD ${LLVM_ALL_TARGETS} ) endif() Modified: llvm/trunk/cmake/config-ix.cmake URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/cmake/config-ix.cmake?rev=59565&r1=59564&r2=59565&view=diff ============================================================================== --- llvm/trunk/cmake/config-ix.cmake (original) +++ llvm/trunk/cmake/config-ix.cmake Tue Nov 18 17:45:21 2008 @@ -93,8 +93,17 @@ # FIXME: Signal handler return type, currently hardcoded to 'void' set(RETSIGTYPE void) -# Disable multithreading for now -set(ENABLE_THREADS 0) +if( LLVM_ENABLE_THREADS ) + if( HAVE_PTHREAD_H OR WIN32 ) + set(ENABLE_THREADS 1) + endif() +endif() + +if( ENABLE_THREADS ) + message(STATUS "Threads enabled.") +else( ENABLE_THREADS ) + message(STATUS "Threads disabled.") +endif() configure_file( ${LLVM_MAIN_INCLUDE_DIR}/llvm/Config/config.h.cmake From evan.cheng at apple.com Tue Nov 18 17:54:01 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 18 Nov 2008 23:54:01 -0000 Subject: [llvm-commits] [llvm] r59566 - /llvm/trunk/lib/CodeGen/RegisterScavenging.cpp Message-ID: <200811182354.mAINs1eo023520@zion.cs.uiuc.edu> Author: evancheng Date: Tue Nov 18 17:54:01 2008 New Revision: 59566 URL: http://llvm.org/viewvc/llvm-project?rev=59566&view=rev Log: Make the same change to RegScavenger::backward. Modified: llvm/trunk/lib/CodeGen/RegisterScavenging.cpp Modified: llvm/trunk/lib/CodeGen/RegisterScavenging.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegisterScavenging.cpp?rev=59566&r1=59565&r2=59566&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/RegisterScavenging.cpp (original) +++ llvm/trunk/lib/CodeGen/RegisterScavenging.cpp Tue Nov 18 17:54:01 2008 @@ -282,15 +282,38 @@ MBBI = prior(MBBI); MachineInstr *MI = MBBI; - // Process defs first. const TargetInstrDesc &TID = MI->getDesc(); + + // Separate register operands into 3 classes: uses, defs, earlyclobbers. + SmallVector, 4> UseMOs; + SmallVector, 4> DefMOs; + SmallVector, 4> EarlyClobberMOs; for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { const MachineOperand &MO = MI->getOperand(i); - if (!MO.isReg() || !MO.isDef()) + if (!MO.isReg() || MO.getReg() == 0) continue; + if (MO.isUse()) + UseMOs.push_back(std::make_pair(&MO,i)); + else if (MO.isEarlyClobber()) + EarlyClobberMOs.push_back(std::make_pair(&MO,i)); + else + DefMOs.push_back(std::make_pair(&MO,i)); + } + + + // Process defs first. + unsigned NumECs = EarlyClobberMOs.size(); + unsigned NumDefs = DefMOs.size(); + for (unsigned i = 0, e = NumECs + NumDefs; i != e; ++i) { + const MachineOperand &MO = (i < NumDefs) + ? *DefMOs[i].first : *EarlyClobberMOs[i-NumDefs].first; + unsigned Idx = (i < NumECs) + ? DefMOs[i].second : EarlyClobberMOs[i-NumDefs].second; + // Skip two-address destination operand. - if (TID.findTiedToSrcOperand(i) != -1) + if (TID.findTiedToSrcOperand(Idx) != -1) continue; + unsigned Reg = MO.getReg(); assert(isUsed(Reg)); if (!isReserved(Reg)) @@ -299,13 +322,9 @@ // Process uses. BitVector UseRegs(NumPhysRegs); - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { - const MachineOperand &MO = MI->getOperand(i); - if (!MO.isReg() || !MO.isUse()) - continue; + for (unsigned i = 0, e = UseMOs.size(); i != e; ++i) { + const MachineOperand MO = *UseMOs[i].first; unsigned Reg = MO.getReg(); - if (Reg == 0) - continue; assert(isUnused(Reg) || isReserved(Reg)); UseRegs.set(Reg); From gohman at apple.com Tue Nov 18 18:04:44 2008 From: gohman at apple.com (Dan Gohman) Date: Wed, 19 Nov 2008 00:04:44 -0000 Subject: [llvm-commits] [llvm] r59567 - /llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Message-ID: <200811190004.mAJ04i6J024051@zion.cs.uiuc.edu> Author: djg Date: Tue Nov 18 18:04:44 2008 New Revision: 59567 URL: http://llvm.org/viewvc/llvm-project?rev=59567&view=rev Log: Fix debug printing of flagged SDNodes in SUnits so that they print in the correct order. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp?rev=59567&r1=59566&r2=59567&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Tue Nov 18 18:04:44 2008 @@ -461,20 +461,20 @@ /// a group of nodes flagged together. void SUnit::dump(const ScheduleDAG *G) const { cerr << "SU(" << NodeNum << "): "; - if (getNode()) - getNode()->dump(G->DAG); - else + if (getNode()) { + SmallVector FlaggedNodes; + for (SDNode *N = getNode(); N; N = N->getFlaggedNode()) + FlaggedNodes.push_back(N); + while (!FlaggedNodes.empty()) { + cerr << " "; + FlaggedNodes.back()->dump(G->DAG); + cerr << "\n"; + FlaggedNodes.pop_back(); + } + } else { cerr << "CROSS RC COPY "; - cerr << "\n"; - SmallVector FlaggedNodes; - for (SDNode *N = getNode()->getFlaggedNode(); N; N = N->getFlaggedNode()) - FlaggedNodes.push_back(N); - while (!FlaggedNodes.empty()) { - cerr << " "; - FlaggedNodes.back()->dump(G->DAG); - cerr << "\n"; - FlaggedNodes.pop_back(); } + cerr << "\n"; } void SUnit::dumpAll(const ScheduleDAG *G) const { From ofv at wanadoo.es Tue Nov 18 18:10:39 2008 From: ofv at wanadoo.es (Oscar Fuentes) Date: Wed, 19 Nov 2008 00:10:39 -0000 Subject: [llvm-commits] [llvm] r59568 - /llvm/trunk/CMakeLists.txt Message-ID: <200811190010.mAJ0Ad7P024241@zion.cs.uiuc.edu> Author: ofv Date: Tue Nov 18 18:10:39 2008 New Revision: 59568 URL: http://llvm.org/viewvc/llvm-project?rev=59568&view=rev Log: CMake: Support for building 32 bits shared libraries on 64 bits GNU systems. BUILD_32_BITS option renamed to LLVM_BUILD_32_BITS. Modified: llvm/trunk/CMakeLists.txt Modified: llvm/trunk/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/CMakeLists.txt?rev=59568&r1=59567&r2=59568&view=diff ============================================================================== --- llvm/trunk/CMakeLists.txt (original) +++ llvm/trunk/CMakeLists.txt Tue Nov 18 18:10:39 2008 @@ -118,14 +118,14 @@ if( CMAKE_SIZEOF_VOID_P EQUAL 8 AND NOT WIN32 ) # TODO: support other platforms and toolchains. - option(BUILD_32_BITS "Build 32 bits executables and libraries." OFF) - if( BUILD_32_BITS ) + option(LLVM_BUILD_32_BITS "Build 32 bits executables and libraries." OFF) + if( LLVM_BUILD_32_BITS ) message(STATUS "Building 32 bits executables and libraries.") add_definitions( -m32 ) - set( CMAKE_EXE_LINKER_FLAGS "-m32 ${CMAKE_EXE_LINKER_FLAGS}" ) - set( CMAKE_LINK_LIBRARY_FLAG "-m32 ${CMAKE_LINK_LIBRARY_FLAG}" ) + list(APPEND CMAKE_EXE_LINKER_FLAGS -m32) + list(APPEND CMAKE_SHARED_LINKER_FLAGS -m32) set( LLVM_PLO_FLAGS -melf_i386 ${LLVM_PLO_FLAGS} ) - endif( BUILD_32_BITS ) + endif( LLVM_BUILD_32_BITS ) endif( CMAKE_SIZEOF_VOID_P EQUAL 8 AND NOT WIN32 ) if( MSVC ) From dpatel at apple.com Tue Nov 18 18:19:18 2008 From: dpatel at apple.com (Devang Patel) Date: Wed, 19 Nov 2008 00:19:18 -0000 Subject: [llvm-commits] [llvm] r59569 - /llvm/trunk/lib/Transforms/IPO/StripSymbols.cpp Message-ID: <200811190019.mAJ0JIVM024519@zion.cs.uiuc.edu> Author: dpatel Date: Tue Nov 18 18:19:18 2008 New Revision: 59569 URL: http://llvm.org/viewvc/llvm-project?rev=59569&view=rev Log: Fix typo. Modified: llvm/trunk/lib/Transforms/IPO/StripSymbols.cpp Modified: llvm/trunk/lib/Transforms/IPO/StripSymbols.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/StripSymbols.cpp?rev=59569&r1=59568&r2=59569&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/StripSymbols.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/StripSymbols.cpp Tue Nov 18 18:19:18 2008 @@ -249,7 +249,7 @@ assert(CI->use_empty() && "llvm.dbg intrinsic should have void result"); CI->eraseFromParent(); if (Arg->use_empty()) - if (Constant *C = dyn_cast(Arg)) + if (Constant *C = dyn_cast(Arg)) DeadConstants.push_back(C); } Declare->eraseFromParent(); From dpatel at apple.com Tue Nov 18 18:22:02 2008 From: dpatel at apple.com (Devang Patel) Date: Wed, 19 Nov 2008 00:22:02 -0000 Subject: [llvm-commits] [llvm] r59570 - /llvm/trunk/lib/Transforms/IPO/StripSymbols.cpp Message-ID: <200811190022.mAJ0M2Vo024657@zion.cs.uiuc.edu> Author: dpatel Date: Tue Nov 18 18:22:02 2008 New Revision: 59570 URL: http://llvm.org/viewvc/llvm-project?rev=59570&view=rev Log: Remove unused variables. Modified: llvm/trunk/lib/Transforms/IPO/StripSymbols.cpp Modified: llvm/trunk/lib/Transforms/IPO/StripSymbols.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/StripSymbols.cpp?rev=59570&r1=59569&r2=59570&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/StripSymbols.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/StripSymbols.cpp Tue Nov 18 18:22:02 2008 @@ -273,18 +273,15 @@ GV->setLinkage(GlobalValue::InternalLinkage); // Delete all dbg variables. - const Type *DbgVTy = M.getTypeByName("llvm.dbg.variable.type"); - const Type *DbgGVTy = M.getTypeByName("llvm.dbg.global_variable.type"); - if (DbgVTy || DbgGVTy) - for (Module::global_iterator I = M.global_begin(), E = M.global_end(); - I != E; ++I) { - GlobalVariable *GV = dyn_cast(I); - if (!GV) continue; - if (GV->use_empty() && llvmUsedValues.count(I) == 0 - && (!GV->hasSection() - || strcmp(GV->getSection().c_str(), "llvm.metadata") == 0)) - DeadConstants.push_back(GV); - } + for (Module::global_iterator I = M.global_begin(), E = M.global_end(); + I != E; ++I) { + GlobalVariable *GV = dyn_cast(I); + if (!GV) continue; + if (GV->use_empty() && llvmUsedValues.count(I) == 0 + && (!GV->hasSection() + || strcmp(GV->getSection().c_str(), "llvm.metadata") == 0)) + DeadConstants.push_back(GV); + } if (DeadConstants.empty()) return false; From dpatel at apple.com Tue Nov 18 18:27:57 2008 From: dpatel at apple.com (Devang Patel) Date: Wed, 19 Nov 2008 00:27:57 -0000 Subject: [llvm-commits] [test-suite] r59572 - /test-suite/trunk/TEST.dbgopt.Makefile Message-ID: <200811190027.mAJ0RvDT024863@zion.cs.uiuc.edu> Author: dpatel Date: Tue Nov 18 18:27:56 2008 New Revision: 59572 URL: http://llvm.org/viewvc/llvm-project?rev=59572&view=rev Log: $ opt input.bc -strip -std-compile-output -o first.bc $ opt input.bc -std-compile-output -strip -o second.bc Here first.bc and second.bc may not match because during optimization the optimizer may create new symbols whose name based on the names of exisiting symbols. Strip symbol names in the beginning and strip at the end to eliminate these symbol names differences. $ opt input.bc -strip-nondebug -strip-debug -std-compile-output -strip -o first.bc $ opt input.bc -strip-nondebug -std-compile-output -strip -o second.bc Modified: test-suite/trunk/TEST.dbgopt.Makefile Modified: test-suite/trunk/TEST.dbgopt.Makefile URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/TEST.dbgopt.Makefile?rev=59572&r1=59571&r2=59572&view=diff ============================================================================== --- test-suite/trunk/TEST.dbgopt.Makefile (original) +++ test-suite/trunk/TEST.dbgopt.Makefile Tue Nov 18 18:27:56 2008 @@ -7,8 +7,8 @@ # first.bc and second.bc should match. Otherwise debugging information # is influencing the optimizer. # -# $ opt input.bc -strip -std-compile-output -o first.bc -# $ opt input.bc -std-compile-output -strip -o second.bc +# $ opt input.bc -strip-nondebug -strip-debug -std-compile-output -strip -o first.bc +# $ opt input.bc -strip-nondebug -std-compile-output -strip -o second.bc # ##===----------------------------------------------------------------------===## @@ -19,10 +19,10 @@ Output/%.diff: %.cpp Output/.dir $(LLVMGXX) $(LOPT) $(LDIS) $(LLVMGXX) $*.cpp -g --emit-llvm -c -o Output/$*.bc - $(LOPT) Output/$*.bc -strip -std-compile-opts -f -o Output/$*.bc - $(LDIS) Output/$*.bc -f -o Output/$*.first.ll - $(LOPT) Output/$*.bc -std-compile-opts -strip -f -o Output/$*.bc - $(LDIS) Output/$*.bc -f -o Output/$*.second.ll + $(LOPT) Output/$*.bc -strip-nondebug -strip-debug -std-compile-opts -strip -f -o Output/$*.t.bc + $(LDIS) Output/$*.t.bc -f -o Output/$*.first.ll + $(LOPT) Output/$*.bc -strip-nondebug -std-compile-opts -strip -f -o Output/$*.t.bc + $(LDIS) Output/$*.t.bc -f -o Output/$*.second.ll @-if diff Output/$*.first.ll Output/$*.second.ll > Output/$*.diff; then \ echo "--------- TEST-PASS: $*"; \ else \ @@ -32,12 +32,13 @@ Output/%.diff: %.c Output/.dir $(LLVMGCC) $(LOPT) $(LDIS) $(LLVMGCC) $*.c -g --emit-llvm -c -o Output/$*.bc - $(LOPT) Output/$*.bc -strip -std-compile-opts -f -o Output/$*.bc - $(LDIS) Output/$*.bc -f -o Output/$*.first.ll - $(LOPT) Output/$*.bc -std-compile-opts -strip -f -o Output/$*.bc - $(LDIS) Output/$*.bc -f -o Output/$*.second.ll + $(LOPT) Output/$*.bc -strip-nondebug -strip-debug -std-compile-opts -strip -f -o Output/$*.t.bc + $(LDIS) Output/$*.t.bc -f -o Output/$*.first.ll + $(LOPT) Output/$*.bc -strip-nondebug -std-compile-opts -strip -f -o Output/$*.t.bc + $(LDIS) Output/$*.t.bc -f -o Output/$*.second.ll @-if diff Output/$*.first.ll Output/$*.second.ll > Output/$*.diff; then \ echo "--------- TEST-PASS: $*"; \ else \ echo "--------- TEST-FAIL: $*"; \ fi + From isanbard at gmail.com Tue Nov 18 19:15:05 2008 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 19 Nov 2008 01:15:05 -0000 Subject: [llvm-commits] [llvm] r59576 - /llvm/trunk/lib/VMCore/Verifier.cpp Message-ID: <200811190115.mAJ1F6Wi026372@zion.cs.uiuc.edu> Author: void Date: Tue Nov 18 19:15:05 2008 New Revision: 59576 URL: http://llvm.org/viewvc/llvm-project?rev=59576&view=rev Log: Match an element of the return type if it returns a structure. Modified: llvm/trunk/lib/VMCore/Verifier.cpp Modified: llvm/trunk/lib/VMCore/Verifier.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Verifier.cpp?rev=59576&r1=59575&r2=59576&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Verifier.cpp (original) +++ llvm/trunk/lib/VMCore/Verifier.cpp Tue Nov 18 19:15:05 2008 @@ -1395,8 +1395,18 @@ if (VT < 0) { int Match = ~VT; - if (Match == 0) { - if (Ty != FTy->getReturnType()) { + const Type *RetTy = FTy->getReturnType(); + const StructType *ST = cast(RetTy); + unsigned NumRets = 1; + + if (ST) + NumRets = ST->getNumElements(); + + if (Match <= static_cast(NumRets - 1)) { + if (ST) + RetTy = ST->getElementType(Match); + + if (Ty != RetTy) { CheckFailed("Intrinsic parameter #" + utostr(ArgNo - 1) + " does not " "match return type.", F); return false; From isanbard at gmail.com Tue Nov 18 19:25:41 2008 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 19 Nov 2008 01:25:41 -0000 Subject: [llvm-commits] [llvm] r59577 - /llvm/trunk/lib/VMCore/Verifier.cpp Message-ID: <200811190125.mAJ1Pfru026756@zion.cs.uiuc.edu> Author: void Date: Tue Nov 18 19:25:41 2008 New Revision: 59577 URL: http://llvm.org/viewvc/llvm-project?rev=59577&view=rev Log: Use dyn_cast instead of cast. Modified: llvm/trunk/lib/VMCore/Verifier.cpp Modified: llvm/trunk/lib/VMCore/Verifier.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Verifier.cpp?rev=59577&r1=59576&r2=59577&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Verifier.cpp (original) +++ llvm/trunk/lib/VMCore/Verifier.cpp Tue Nov 18 19:25:41 2008 @@ -1396,7 +1396,7 @@ if (VT < 0) { int Match = ~VT; const Type *RetTy = FTy->getReturnType(); - const StructType *ST = cast(RetTy); + const StructType *ST = dyn_cast(RetTy); unsigned NumRets = 1; if (ST) From gohman at apple.com Tue Nov 18 20:00:33 2008 From: gohman at apple.com (Dan Gohman) Date: Wed, 19 Nov 2008 02:00:33 -0000 Subject: [llvm-commits] [llvm] r59580 - /llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Message-ID: <200811190200.mAJ20Xmh028853@zion.cs.uiuc.edu> Author: djg Date: Tue Nov 18 20:00:32 2008 New Revision: 59580 URL: http://llvm.org/viewvc/llvm-project?rev=59580&view=rev Log: Rearrange code to reduce the nesting level. No functionality change. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp?rev=59580&r1=59579&r2=59580&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Tue Nov 18 20:00:32 2008 @@ -1754,44 +1754,44 @@ unsigned NumRes = TID.getNumDefs(); unsigned NumOps = TID.getNumOperands() - NumRes; for (unsigned j = 0; j != NumOps; ++j) { - if (TID.getOperandConstraint(j+NumRes, TOI::TIED_TO) != -1) { - SDNode *DU = SU->getNode()->getOperand(j).getNode(); - if (DU->getNodeId() == -1) + if (TID.getOperandConstraint(j+NumRes, TOI::TIED_TO) == -1) + continue; + SDNode *DU = SU->getNode()->getOperand(j).getNode(); + if (DU->getNodeId() == -1) + continue; + const SUnit *DUSU = &(*SUnits)[DU->getNodeId()]; + if (!DUSU) continue; + for (SUnit::const_succ_iterator I = DUSU->Succs.begin(), + E = DUSU->Succs.end(); I != E; ++I) { + if (I->isCtrl) continue; + SUnit *SuccSU = I->Dep; + if (SuccSU == SU) continue; - const SUnit *DUSU = &(*SUnits)[DU->getNodeId()]; - if (!DUSU) continue; - for (SUnit::const_succ_iterator I = DUSU->Succs.begin(), - E = DUSU->Succs.end(); I != E; ++I) { - if (I->isCtrl) continue; - SUnit *SuccSU = I->Dep; - if (SuccSU == SU) - continue; - // Be conservative. Ignore if nodes aren't at roughly the same - // depth and height. - if (SuccSU->Height < SU->Height && (SU->Height - SuccSU->Height) > 1) - continue; - if (!SuccSU->getNode() || !SuccSU->getNode()->isMachineOpcode()) - continue; - // Don't constrain nodes with physical register defs if the - // predecessor can clobber them. - if (SuccSU->hasPhysRegDefs) { - if (canClobberPhysRegDefs(SuccSU, SU, TII, TRI)) - continue; - } - // Don't constraint extract_subreg / insert_subreg these may be - // coalesced away. We don't them close to their uses. - unsigned SuccOpc = SuccSU->getNode()->getMachineOpcode(); - if (SuccOpc == TargetInstrInfo::EXTRACT_SUBREG || - SuccOpc == TargetInstrInfo::INSERT_SUBREG) + // Be conservative. Ignore if nodes aren't at roughly the same + // depth and height. + if (SuccSU->Height < SU->Height && (SU->Height - SuccSU->Height) > 1) + continue; + if (!SuccSU->getNode() || !SuccSU->getNode()->isMachineOpcode()) + continue; + // Don't constrain nodes with physical register defs if the + // predecessor can clobber them. + if (SuccSU->hasPhysRegDefs) { + if (canClobberPhysRegDefs(SuccSU, SU, TII, TRI)) continue; - if ((!canClobber(SuccSU, DUSU) || - (hasCopyToRegUse(SU) && !hasCopyToRegUse(SuccSU)) || - (!SU->isCommutable && SuccSU->isCommutable)) && - !scheduleDAG->IsReachable(SuccSU, SU)) { - DOUT << "Adding an edge from SU # " << SU->NodeNum - << " to SU #" << SuccSU->NodeNum << "\n"; - scheduleDAG->AddPred(SU, SuccSU, true, true); - } + } + // Don't constraint extract_subreg / insert_subreg these may be + // coalesced away. We don't them close to their uses. + unsigned SuccOpc = SuccSU->getNode()->getMachineOpcode(); + if (SuccOpc == TargetInstrInfo::EXTRACT_SUBREG || + SuccOpc == TargetInstrInfo::INSERT_SUBREG) + continue; + if ((!canClobber(SuccSU, DUSU) || + (hasCopyToRegUse(SU) && !hasCopyToRegUse(SuccSU)) || + (!SU->isCommutable && SuccSU->isCommutable)) && + !scheduleDAG->IsReachable(SuccSU, SU)) { + DOUT << "Adding an edge from SU # " << SU->NodeNum + << " to SU #" << SuccSU->NodeNum << "\n"; + scheduleDAG->AddPred(SU, SuccSU, true, true); } } } From daniel at zuster.org Tue Nov 18 20:37:41 2008 From: daniel at zuster.org (Daniel Dunbar) Date: Wed, 19 Nov 2008 02:37:41 -0000 Subject: [llvm-commits] [llvm] r59581 - /llvm/trunk/docs/DeveloperPolicy.html Message-ID: <200811190237.mAJ2bfku029952@zion.cs.uiuc.edu> Author: ddunbar Date: Tue Nov 18 20:37:39 2008 New Revision: 59581 URL: http://llvm.org/viewvc/llvm-project?rev=59581&view=rev Log: Grammar. Modified: llvm/trunk/docs/DeveloperPolicy.html Modified: llvm/trunk/docs/DeveloperPolicy.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/DeveloperPolicy.html?rev=59581&r1=59580&r2=59581&view=diff ============================================================================== --- llvm/trunk/docs/DeveloperPolicy.html (original) +++ llvm/trunk/docs/DeveloperPolicy.html Tue Nov 18 20:37:39 2008 @@ -429,7 +429,7 @@ their contributors. However, we do not want the source code to be littered with random attributions "this code written by J Random Guy" (this is noisy and distracting). In practice, the revision control system keeps a perfect - history of who change what, and the CREDITS.txt file describes higher-level + history of who changed what, and the CREDITS.txt file describes higher-level contributions. If you commit a patch for someone else, please say "patch contributed by J Random Guy!" in the commit message.

      From daniel at zuster.org Tue Nov 18 20:59:02 2008 From: daniel at zuster.org (Daniel Dunbar) Date: Wed, 19 Nov 2008 02:59:02 -0000 Subject: [llvm-commits] [llvm] r59582 - in /llvm/trunk: include/llvm/CompilerDriver/Tools.td test/LLVMC/include.c Message-ID: <200811190259.mAJ2x2aR030617@zion.cs.uiuc.edu> Author: ddunbar Date: Tue Nov 18 20:59:00 2008 New Revision: 59582 URL: http://llvm.org/viewvc/llvm-project?rev=59582&view=rev Log: LLVMC2: Teach llvm_gcc_c tool about -include and -fsyntax-only. - Only focusing on llvm_gcc_c for now, eventually this needs to be refactored so it can be shared via all the gcc-like tools. Added: llvm/trunk/test/LLVMC/include.c Modified: llvm/trunk/include/llvm/CompilerDriver/Tools.td Modified: llvm/trunk/include/llvm/CompilerDriver/Tools.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CompilerDriver/Tools.td?rev=59582&r1=59581&r2=59582&view=diff ============================================================================== --- llvm/trunk/include/llvm/CompilerDriver/Tools.td (original) +++ llvm/trunk/include/llvm/CompilerDriver/Tools.td Tue Nov 18 20:59:00 2008 @@ -21,10 +21,16 @@ "llvm-gcc -E -x c++ $INFILE -o $OUTFILE", (default), "llvm-gcc -E -x c++ $INFILE"), + (switch_on "fsyntax-only"), + "llvm-gcc -c -x c $INFILE", (default), "llvm-gcc -c -x c $INFILE -o $OUTFILE -emit-llvm")), (switch_option "E", (stop_compilation), (help "Stop after the preprocessing stage, do not run the compiler")), + (switch_option "fsyntax-only", (stop_compilation), + (help "Stop after checking the input for syntax errors")), + (parameter_list_option "include", (forward), + (help "Include the named file prior to preprocessing")), (sink) ]>; Added: llvm/trunk/test/LLVMC/include.c URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/LLVMC/include.c?rev=59582&view=auto ============================================================================== --- llvm/trunk/test/LLVMC/include.c (added) +++ llvm/trunk/test/LLVMC/include.c Tue Nov 18 20:59:00 2008 @@ -0,0 +1,9 @@ +/* + * Check that the 'include' options work. + * RUN: echo "int x;\n" > %t1.inc + * RUN: llvmc2 -include %t1.inc -fsyntax-only %s + */ + +int f0(void) { + return x; +} From nicholas at mxc.ca Tue Nov 18 21:38:08 2008 From: nicholas at mxc.ca (Nick Lewycky) Date: Tue, 18 Nov 2008 19:38:08 -0800 Subject: [llvm-commits] [llvm] r59528 - in /llvm/trunk: lib/Analysis/ScalarEvolution.cpp test/Analysis/ScalarEvolution/2008-11-18-LessThanOrEqual.ll test/Analysis/ScalarEvolution/2008-11-18-Stride1.ll test/Analysis/ScalarEvolution/2008-11-18-Stride2.ll In-Reply-To: <4C90C36A-77D6-4006-9F3F-19002F2E561A@apple.com> References: <200811181510.mAIFAtVS001882@zion.cs.uiuc.edu> <4C90C36A-77D6-4006-9F3F-19002F2E561A@apple.com> Message-ID: <49238A20.3010803@mxc.ca> Evan Cheng wrote: > Hi Nicholas, > > What does "trueWhenEqual" mean? Should it default to true / false? Like isSigned, it defines whether the comparison is true when equal, ie., it's an SLT/ULT vs. SLE/ULE. There is no default, but the old version only knew how to handle trueWhenEqual=false (ie., SLT/ULT). Nick > Thanks, > > Evan > > On Nov 18, 2008, at 7:10 AM, Nick Lewycky wrote: > >> Author: nicholas >> Date: Tue Nov 18 09:10:54 2008 >> New Revision: 59528 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=59528&view=rev >> Log: >> Add a utility function that detects whether a loop is guaranteed to >> be finite. >> >> Use it to safely handle less-than-or-equals-to exit conditions in >> loops. These >> also occur when the loop exit branch is exit on true because SCEV >> inverses the >> icmp predicate. >> >> Use it again to handle non-zero strides, but only with an unsigned >> comparison >> in the exit condition. >> >> Added: >> llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18- >> LessThanOrEqual.ll >> llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride1.ll >> llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride2.ll >> Modified: >> llvm/trunk/lib/Analysis/ScalarEvolution.cpp >> >> Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=59528&r1=59527&r2=59528&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> ====================================================================== >> --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original) >> +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Tue Nov 18 09:10:54 >> 2008 >> @@ -1477,7 +1477,7 @@ >> /// specified less-than comparison will execute. If not >> computable, return >> /// UnknownValue. isSigned specifies whether the less-than is >> signed. >> SCEVHandle HowManyLessThans(SCEV *LHS, SCEV *RHS, const Loop *L, >> - bool isSigned); >> + bool isSigned, bool trueWhenEqual); >> >> /// getPredecessorWithUniqueSuccessorForBB - Return a >> predecessor of BB >> /// (which may not be an immediate predecessor) which has >> exactly one >> @@ -1487,7 +1487,13 @@ >> >> /// executesAtLeastOnce - Test whether entry to the loop is >> protected by >> /// a conditional between LHS and RHS. >> - bool executesAtLeastOnce(const Loop *L, bool isSigned, SCEV >> *LHS, SCEV *RHS); >> + bool executesAtLeastOnce(const Loop *L, bool isSigned, bool >> trueWhenEqual, >> + SCEV *LHS, SCEV *RHS); >> + >> + /// potentialInfiniteLoop - Test whether the loop might jump >> over the exit value >> + /// due to wrapping. >> + bool potentialInfiniteLoop(SCEV *Stride, SCEV *RHS, bool >> isSigned, >> + bool trueWhenEqual); >> >> /// getConstantEvolutionLoopExitValue - If we know that the >> specified Phi is >> /// in the header of its containing loop, we know the loop >> executes a >> @@ -2025,24 +2031,46 @@ >> break; >> } >> case ICmpInst::ICMP_SLT: { >> - SCEVHandle TC = HowManyLessThans(LHS, RHS, L, true); >> + SCEVHandle TC = HowManyLessThans(LHS, RHS, L, true, false); >> if (!isa(TC)) return TC; >> break; >> } >> case ICmpInst::ICMP_SGT: { >> SCEVHandle TC = HowManyLessThans(SE.getNotSCEV(LHS), >> - SE.getNotSCEV(RHS), L, true); >> + SE.getNotSCEV(RHS), L, true, >> false); >> if (!isa(TC)) return TC; >> break; >> } >> case ICmpInst::ICMP_ULT: { >> - SCEVHandle TC = HowManyLessThans(LHS, RHS, L, false); >> + SCEVHandle TC = HowManyLessThans(LHS, RHS, L, false, false); >> if (!isa(TC)) return TC; >> break; >> } >> case ICmpInst::ICMP_UGT: { >> SCEVHandle TC = HowManyLessThans(SE.getNotSCEV(LHS), >> - SE.getNotSCEV(RHS), L, false); >> + SE.getNotSCEV(RHS), L, false, >> false); >> + if (!isa(TC)) return TC; >> + break; >> + } >> + case ICmpInst::ICMP_SLE: { >> + SCEVHandle TC = HowManyLessThans(LHS, RHS, L, true, true); >> + if (!isa(TC)) return TC; >> + break; >> + } >> + case ICmpInst::ICMP_SGE: { >> + SCEVHandle TC = HowManyLessThans(SE.getNotSCEV(LHS), >> + SE.getNotSCEV(RHS), L, true, >> true); >> + if (!isa(TC)) return TC; >> + break; >> + } >> + case ICmpInst::ICMP_ULE: { >> + SCEVHandle TC = HowManyLessThans(LHS, RHS, L, false, true); >> + if (!isa(TC)) return TC; >> + break; >> + } >> + case ICmpInst::ICMP_UGE: { >> + SCEVHandle TC = HowManyLessThans(SE.getNotSCEV(LHS), >> + SE.getNotSCEV(RHS), L, false, >> true); >> if (!isa(TC)) return TC; >> break; >> } >> @@ -2738,6 +2766,7 @@ >> /// executesAtLeastOnce - Test whether entry to the loop is >> protected by >> /// a conditional between LHS and RHS. >> bool ScalarEvolutionsImpl::executesAtLeastOnce(const Loop *L, bool >> isSigned, >> + bool trueWhenEqual, >> SCEV *LHS, SCEV *RHS) { >> BasicBlock *Preheader = L->getLoopPreheader(); >> BasicBlock *PreheaderDest = L->getHeader(); >> @@ -2770,20 +2799,36 @@ >> >> switch (Cond) { >> case ICmpInst::ICMP_UGT: >> - if (isSigned) continue; >> + if (isSigned || trueWhenEqual) continue; >> std::swap(PreCondLHS, PreCondRHS); >> Cond = ICmpInst::ICMP_ULT; >> break; >> case ICmpInst::ICMP_SGT: >> - if (!isSigned) continue; >> + if (!isSigned || trueWhenEqual) continue; >> std::swap(PreCondLHS, PreCondRHS); >> Cond = ICmpInst::ICMP_SLT; >> break; >> case ICmpInst::ICMP_ULT: >> - if (isSigned) continue; >> + if (isSigned || trueWhenEqual) continue; >> break; >> case ICmpInst::ICMP_SLT: >> - if (!isSigned) continue; >> + if (!isSigned || trueWhenEqual) continue; >> + break; >> + case ICmpInst::ICMP_UGE: >> + if (isSigned || !trueWhenEqual) continue; >> + std::swap(PreCondLHS, PreCondRHS); >> + Cond = ICmpInst::ICMP_ULE; >> + break; >> + case ICmpInst::ICMP_SGE: >> + if (!isSigned || !trueWhenEqual) continue; >> + std::swap(PreCondLHS, PreCondRHS); >> + Cond = ICmpInst::ICMP_SLE; >> + break; >> + case ICmpInst::ICMP_ULE: >> + if (isSigned || !trueWhenEqual) continue; >> + break; >> + case ICmpInst::ICMP_SLE: >> + if (!isSigned || !trueWhenEqual) continue; >> break; >> default: >> continue; >> @@ -2802,11 +2847,46 @@ >> return false; >> } >> >> +/// potentialInfiniteLoop - Test whether the loop might jump over >> the exit value >> +/// due to wrapping around 2^n. >> +bool ScalarEvolutionsImpl::potentialInfiniteLoop(SCEV *Stride, SCEV >> *RHS, >> + bool isSigned, >> bool trueWhenEqual) { >> + // Return true when the distance from RHS to maxint > Stride. >> + >> + if (!isa(Stride)) >> + return true; >> + SCEVConstant *SC = cast(Stride); >> + >> + if (SC->getValue()->isZero()) >> + return true; >> + if (!trueWhenEqual && SC->getValue()->isOne()) >> + return false; >> + >> + if (!isa(RHS)) >> + return true; >> + SCEVConstant *R = cast(RHS); >> + >> + if (isSigned) >> + return true; // XXX: because we don't have an sdiv scev. >> + >> + // If negative, it wraps around every iteration, but we don't >> care about that. >> + APInt S = SC->getValue()->getValue().abs(); >> + >> + APInt Dist = APInt::getMaxValue(R->getValue()->getBitWidth()) - >> + R->getValue()->getValue(); >> + >> + if (trueWhenEqual) >> + return !S.ult(Dist); >> + else >> + return !S.ule(Dist); >> +} >> + >> /// HowManyLessThans - Return the number of times a backedge >> containing the >> /// specified less-than comparison will execute. If not computable, >> return >> /// UnknownValue. >> SCEVHandle ScalarEvolutionsImpl:: >> -HowManyLessThans(SCEV *LHS, SCEV *RHS, const Loop *L, bool >> isSigned) { >> +HowManyLessThans(SCEV *LHS, SCEV *RHS, const Loop *L, >> + bool isSigned, bool trueWhenEqual) { >> // Only handle: "ADDREC < LoopInvariant". >> if (!RHS->isLoopInvariant(L)) return UnknownValue; >> >> @@ -2815,34 +2895,50 @@ >> return UnknownValue; >> >> if (AddRec->isAffine()) { >> - // FORNOW: We only support unit strides. >> - SCEVHandle One = SE.getIntegerSCEV(1, RHS->getType()); >> - if (AddRec->getOperand(1) != One) >> + SCEVHandle Stride = AddRec->getOperand(1); >> + if (potentialInfiniteLoop(Stride, RHS, isSigned, trueWhenEqual)) >> return UnknownValue; >> >> - // We know the LHS is of the form {n,+,1} and the RHS is some >> loop-invariant >> - // m. So, we count the number of iterations in which {n,+,1} < >> m is true. >> - // Note that we cannot simply return max(m-n,0) because it's >> not safe to >> + // We know the LHS is of the form {n,+,s} and the RHS is some >> loop-invariant >> + // m. So, we count the number of iterations in which {n,+,s} < >> m is true. >> + // Note that we cannot simply return max(m-n,0)/s because it's >> not safe to >> // treat m-n as signed nor unsigned due to overflow possibility. >> >> // First, we get the value of the LHS in the first iteration: n >> SCEVHandle Start = AddRec->getOperand(0); >> >> - if (executesAtLeastOnce(L, isSigned, >> - SE.getMinusSCEV(AddRec->getOperand(0), >> One), RHS)) { >> - // Since we know that the condition is true in order to enter >> the loop, >> - // we know that it will run exactly m-n times. >> - return SE.getMinusSCEV(RHS, Start); >> - } else { >> - // Then, we get the value of the LHS in the first iteration >> in which the >> - // above condition doesn't hold. This equals to max(m,n). >> - SCEVHandle End = isSigned ? SE.getSMaxExpr(RHS, Start) >> - : SE.getUMaxExpr(RHS, Start); >> - >> - // Finally, we subtract these two values to get the number of >> times the >> - // backedge is executed: max(m,n)-n. >> - return SE.getMinusSCEV(End, Start); >> + SCEVHandle One = SE.getIntegerSCEV(1, RHS->getType()); >> + >> + // Assuming that the loop will run at least once, we know that >> it will >> + // run (m-n)/s times. >> + SCEVHandle End = RHS; >> + >> + if (!executesAtLeastOnce(L, isSigned, trueWhenEqual, >> + SE.getMinusSCEV(Start, One), RHS)) { >> + // If not, we get the value of the LHS in the first iteration >> in which >> + // the above condition doesn't hold. This equals to max(m,n). >> + End = isSigned ? SE.getSMaxExpr(RHS, Start) >> + : SE.getUMaxExpr(RHS, Start); >> } >> + >> + // If the expression is less-than-or-equal to, we need to >> extend the >> + // loop by one iteration. >> + // >> + // The loop won't actually run (m-n)/s times because the loop >> iterations >> + // won't divide evenly. For example, if you have {2,+,5} u< 10 >> the >> + // division would equal one, but the loop runs twice putting the >> + // induction variable at 12. >> + >> + if (!trueWhenEqual) >> + // (Stride - 1) is correct only because we know it's unsigned. >> + // What we really want is to decrease the magnitude of Stride >> by one. >> + Start = SE.getMinusSCEV(Start, SE.getMinusSCEV(Stride, One)); >> + else >> + Start = SE.getMinusSCEV(Start, Stride); >> + >> + // Finally, we subtract these two values to get the number of >> times the >> + // backedge is executed: max(m,n)-n. >> + return SE.getUDivExpr(SE.getMinusSCEV(End, Start), Stride); >> } >> >> return UnknownValue; >> >> Added: llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18- >> LessThanOrEqual.ll >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-LessThanOrEqual.ll?rev=59528&view=auto >> >> = >> = >> = >> = >> = >> = >> = >> = >> ====================================================================== >> --- llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18- >> LessThanOrEqual.ll (added) >> +++ llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18- >> LessThanOrEqual.ll Tue Nov 18 09:10:54 2008 >> @@ -0,0 +1,31 @@ >> +; RUN: llvm-as < %s | opt -analyze -scalar-evolution |& \ >> +; RUN: grep {Loop bb: (7 + (-1 \\* %argc)) iterations!} >> + >> +define i32 @main(i32 %argc, i8** %argv) nounwind { >> +entry: >> + %0 = icmp ugt i32 %argc, 7 ; [#uses=1] >> + br i1 %0, label %bb2, label %bb.nph >> + >> +bb.nph: ; preds = %entry >> + br label %bb >> + >> +bb: ; preds = %bb.nph, %bb1 >> + %indvar = phi i32 [ 0, %bb.nph ], [ %indvar.next, %bb1 ] ; >> [#uses=2] >> + %argc_addr.04 = add i32 %indvar, %argc ; [#uses=1] >> + tail call void (...)* @Test() nounwind >> + %1 = add i32 %argc_addr.04, 1 ; [#uses=1] >> + br label %bb1 >> + >> +bb1: ; preds = %bb >> + %phitmp = icmp ugt i32 %1, 7 ; [#uses=1] >> + %indvar.next = add i32 %indvar, 1 ; [#uses=1] >> + br i1 %phitmp, label %bb1.bb2_crit_edge, label %bb >> + >> +bb1.bb2_crit_edge: ; preds = %bb1 >> + br label %bb2 >> + >> +bb2: ; preds = %bb1.bb2_crit_edge, %entry >> + ret i32 0 >> +} >> + >> +declare void @Test(...) >> >> Added: llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride1.ll >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride1.ll?rev=59528&view=auto >> >> = >> = >> = >> = >> = >> = >> = >> = >> ====================================================================== >> --- llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride1.ll >> (added) >> +++ llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride1.ll >> Tue Nov 18 09:10:54 2008 >> @@ -0,0 +1,30 @@ >> +; RUN: llvm-as < %s | opt -analyze -scalar-evolution |& grep {/u 3} >> + >> +define i32 @f(i32 %x) nounwind readnone { >> +entry: >> + %0 = icmp ugt i32 %x, 4 ; [#uses=1] >> + br i1 %0, label %bb.nph, label %bb2 >> + >> +bb.nph: ; preds = %entry >> + br label %bb >> + >> +bb: ; preds = %bb.nph, %bb1 >> + %indvar = phi i32 [ 0, %bb.nph ], [ %indvar.next, %bb1 ] ; >> [#uses=2] >> + %tmp = mul i32 %indvar, -3 ; [#uses=1] >> + %x_addr.04 = add i32 %tmp, %x ; [#uses=1] >> + %1 = add i32 %x_addr.04, -3 ; [#uses=2] >> + br label %bb1 >> + >> +bb1: ; preds = %bb >> + %2 = icmp ugt i32 %1, 4 ; [#uses=1] >> + %indvar.next = add i32 %indvar, 1 ; [#uses=1] >> + br i1 %2, label %bb, label %bb1.bb2_crit_edge >> + >> +bb1.bb2_crit_edge: ; preds = %bb1 >> + %.lcssa = phi i32 [ %1, %bb1 ] ; [#uses=1] >> + br label %bb2 >> + >> +bb2: ; preds = %bb1.bb2_crit_edge, %entry >> + %x_addr.0.lcssa = phi i32 [ %.lcssa, %bb1.bb2_crit_edge ], [ %x, >> %entry ] ; [#uses=1] >> + ret i32 %x_addr.0.lcssa >> +} >> >> Added: llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride2.ll >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride2.ll?rev=59528&view=auto >> >> = >> = >> = >> = >> = >> = >> = >> = >> ====================================================================== >> --- llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride2.ll >> (added) >> +++ llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride2.ll >> Tue Nov 18 09:10:54 2008 >> @@ -0,0 +1,30 @@ >> +; RUN: llvm-as < %s | opt -analyze -scalar-evolution |& grep {/u 3} >> + >> +define i32 @f(i32 %x) nounwind readnone { >> +entry: >> + %0 = icmp ugt i32 %x, 999 ; [#uses=1] >> + br i1 %0, label %bb2, label %bb.nph >> + >> +bb.nph: ; preds = %entry >> + br label %bb >> + >> +bb: ; preds = %bb.nph, %bb1 >> + %indvar = phi i32 [ 0, %bb.nph ], [ %indvar.next, %bb1 ] ; >> [#uses=2] >> + %tmp = mul i32 %indvar, 3 ; [#uses=1] >> + %x_addr.04 = add i32 %tmp, %x ; [#uses=1] >> + %1 = add i32 %x_addr.04, 3 ; [#uses=2] >> + br label %bb1 >> + >> +bb1: ; preds = %bb >> + %2 = icmp ugt i32 %1, 999 ; [#uses=1] >> + %indvar.next = add i32 %indvar, 1 ; [#uses=1] >> + br i1 %2, label %bb1.bb2_crit_edge, label %bb >> + >> +bb1.bb2_crit_edge: ; preds = %bb1 >> + %.lcssa = phi i32 [ %1, %bb1 ] ; [#uses=1] >> + br label %bb2 >> + >> +bb2: ; preds = %bb1.bb2_crit_edge, %entry >> + %x_addr.0.lcssa = phi i32 [ %.lcssa, %bb1.bb2_crit_edge ], [ %x, >> %entry ] ; [#uses=1] >> + ret i32 %x_addr.0.lcssa >> +} >> >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From kremenek at apple.com Tue Nov 18 21:57:11 2008 From: kremenek at apple.com (Ted Kremenek) Date: Wed, 19 Nov 2008 03:57:11 -0000 Subject: [llvm-commits] [llvm] r59584 - /llvm/tags/checker/checker-130/ Message-ID: <200811190357.mAJ3vBAv032653@zion.cs.uiuc.edu> Author: kremenek Date: Tue Nov 18 21:57:11 2008 New Revision: 59584 URL: http://llvm.org/viewvc/llvm-project?rev=59584&view=rev Log: Tagging checker-130. Added: llvm/tags/checker/checker-130/ - copied from r59583, llvm/trunk/ From daniel at zuster.org Tue Nov 18 22:15:58 2008 From: daniel at zuster.org (Daniel Dunbar) Date: Wed, 19 Nov 2008 04:15:58 -0000 Subject: [llvm-commits] [llvm] r59586 - in /llvm/trunk: include/llvm/CompilerDriver/Tools.td test/LLVMC/emit-llvm.c Message-ID: <200811190415.mAJ4FxFi000985@zion.cs.uiuc.edu> Author: ddunbar Date: Tue Nov 18 22:15:56 2008 New Revision: 59586 URL: http://llvm.org/viewvc/llvm-project?rev=59586&view=rev Log: LLVMC2: -emit-llvm stops compilation. Added: llvm/trunk/test/LLVMC/emit-llvm.c Modified: llvm/trunk/include/llvm/CompilerDriver/Tools.td Modified: llvm/trunk/include/llvm/CompilerDriver/Tools.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CompilerDriver/Tools.td?rev=59586&r1=59585&r2=59586&view=diff ============================================================================== --- llvm/trunk/include/llvm/CompilerDriver/Tools.td (original) +++ llvm/trunk/include/llvm/CompilerDriver/Tools.td Tue Nov 18 22:15:56 2008 @@ -25,6 +25,8 @@ "llvm-gcc -c -x c $INFILE", (default), "llvm-gcc -c -x c $INFILE -o $OUTFILE -emit-llvm")), + (switch_option "emit-llvm", (stop_compilation), + (help "Emit LLVM intermediate files instead of native object files")), (switch_option "E", (stop_compilation), (help "Stop after the preprocessing stage, do not run the compiler")), (switch_option "fsyntax-only", (stop_compilation), Added: llvm/trunk/test/LLVMC/emit-llvm.c URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/LLVMC/emit-llvm.c?rev=59586&view=auto ============================================================================== --- llvm/trunk/test/LLVMC/emit-llvm.c (added) +++ llvm/trunk/test/LLVMC/emit-llvm.c Tue Nov 18 22:15:56 2008 @@ -0,0 +1,4 @@ +// RUN: llvmc2 -c -emit-llvm -o - %s | llvm-dis | grep "@f0()" | count 1 + +int f0(void) { +} From resistor at mac.com Tue Nov 18 22:28:30 2008 From: resistor at mac.com (Owen Anderson) Date: Wed, 19 Nov 2008 04:28:30 -0000 Subject: [llvm-commits] [llvm] r59587 - in /llvm/trunk: lib/CodeGen/PreAllocSplitting.cpp test/CodeGen/X86/pre-split2.ll Message-ID: <200811190428.mAJ4SUqX001355@zion.cs.uiuc.edu> Author: resistor Date: Tue Nov 18 22:28:29 2008 New Revision: 59587 URL: http://llvm.org/viewvc/llvm-project?rev=59587&view=rev Log: Add support for rematerialization in pre-alloc-splitting. Modified: llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp llvm/trunk/test/CodeGen/X86/pre-split2.ll Modified: llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp?rev=59587&r1=59586&r2=59587&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp (original) +++ llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp Tue Nov 18 22:28:29 2008 @@ -39,6 +39,7 @@ static cl::opt PreSplitLimit("pre-split-limit", cl::init(-1), cl::Hidden); STATISTIC(NumSplits, "Number of intervals split"); +STATISTIC(NumRemats, "Number of intervals split by rematerialization"); namespace { class VISIBILITY_HIDDEN PreAllocSplitting : public MachineFunctionPass { @@ -153,6 +154,11 @@ bool createsNewJoin(LiveRange* LR, MachineBasicBlock* DefMBB, MachineBasicBlock* BarrierMBB); + bool Rematerialize(unsigned vreg, VNInfo* ValNo, + MachineInstr* DefMI, + MachineBasicBlock::iterator RestorePt, + unsigned RestoreIdx, + SmallPtrSet& RefsInMBB); }; } // end anonymous namespace @@ -627,6 +633,90 @@ return; } +bool PreAllocSplitting::Rematerialize(unsigned vreg, VNInfo* ValNo, + MachineInstr* DefMI, + MachineBasicBlock::iterator RestorePt, + unsigned RestoreIdx, + SmallPtrSet& RefsInMBB) { + MachineBasicBlock& MBB = *RestorePt->getParent(); + + MachineBasicBlock::iterator KillPt = BarrierMBB->end(); + unsigned KillIdx = 0; + if (ValNo->def == ~0U || DefMI->getParent() == BarrierMBB) + KillPt = findSpillPoint(BarrierMBB, Barrier, NULL, RefsInMBB, KillIdx); + else + KillPt = findNextEmptySlot(DefMI->getParent(), DefMI, KillIdx); + + if (KillPt == DefMI->getParent()->end()) + return false; + + TII->reMaterialize(MBB, RestorePt, vreg, DefMI); + LIs->InsertMachineInstrInMaps(prior(RestorePt), RestoreIdx); + + if (KillPt->getParent() == BarrierMBB) { + UpdateRegisterInterval(ValNo, LIs->getUseIndex(KillIdx)+1, + LIs->getDefIndex(RestoreIdx)); + + ++NumSplits; + ++NumRemats; + return true; + } + + // Shrink wrap the live interval by walking up the CFG and find the + // new kills. + // Now let's find all the uses of the val#. + DenseMap > Uses; + DenseMap > UseMIs; + SmallPtrSet Seen; + SmallVector UseMBBs; + for (MachineRegisterInfo::use_iterator UI = MRI->use_begin(CurrLI->reg), + UE = MRI->use_end(); UI != UE; ++UI) { + MachineOperand &UseMO = UI.getOperand(); + MachineInstr *UseMI = UseMO.getParent(); + unsigned UseIdx = LIs->getInstructionIndex(UseMI); + LiveInterval::iterator ULR = CurrLI->FindLiveRangeContaining(UseIdx); + if (ULR->valno != ValNo) + continue; + MachineBasicBlock *UseMBB = UseMI->getParent(); + // Remember which other mbb's use this val#. + if (Seen.insert(UseMBB) && UseMBB != BarrierMBB) + UseMBBs.push_back(UseMBB); + DenseMap >::iterator + UMII = Uses.find(UseMBB); + if (UMII != Uses.end()) { + DenseMap >::iterator + UMII2 = UseMIs.find(UseMBB); + UMII->second.push_back(&UseMO); + UMII2->second.insert(UseMI); + } else { + SmallVector Ops; + Ops.push_back(&UseMO); + Uses.insert(std::make_pair(UseMBB, Ops)); + SmallPtrSet MIs; + MIs.insert(UseMI); + UseMIs.insert(std::make_pair(UseMBB, MIs)); + } + } + + // Walk up the predecessor chains. + SmallPtrSet Visited; + ShrinkWrapLiveInterval(ValNo, BarrierMBB, NULL, DefMI->getParent(), Visited, + Uses, UseMIs, UseMBBs); + + // FIXME: If ValNo->hasPHIKill is false, then renumber the val# by + // the restore. + + // Remove live range from barrier to the restore. FIXME: Find a better + // point to re-start the live interval. + UpdateRegisterInterval(ValNo, LIs->getUseIndex(BarrierIdx)+1, + LIs->getDefIndex(RestoreIdx)); + + ++NumSplits; + ++NumRemats; + return true; + +} + /// SplitRegLiveInterval - Split (spill and restore) the given live interval /// so it would not cross the barrier that's being processed. Shrink wrap /// (minimize) the live interval to the last uses. @@ -644,11 +734,8 @@ abort(); } - // FIXME: For now, if definition is rematerializable, do not split. MachineInstr *DefMI = (ValNo->def != ~0U) ? LIs->getInstructionFromIndex(ValNo->def) : NULL; - if (DefMI && LIs->isReMaterializable(*LI, ValNo, DefMI)) - return false; // If this would create a new join point, do not split. if (DefMI && createsNewJoin(LR, DefMI->getParent(), Barrier->getParent())) @@ -670,6 +757,11 @@ if (RestorePt == BarrierMBB->end()) return false; + if (DefMI && LIs->isReMaterializable(*LI, ValNo, DefMI)) + if (Rematerialize(LI->reg, ValNo, DefMI, RestorePt, + RestoreIndex, RefsInMBB)) + return true; + // Add a spill either before the barrier or after the definition. MachineBasicBlock *DefMBB = DefMI ? DefMI->getParent() : NULL; const TargetRegisterClass *RC = MRI->getRegClass(CurrLI->reg); Modified: llvm/trunk/test/CodeGen/X86/pre-split2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/pre-split2.ll?rev=59587&r1=59586&r2=59587&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/pre-split2.ll (original) +++ llvm/trunk/test/CodeGen/X86/pre-split2.ll Tue Nov 18 22:28:29 2008 @@ -1,5 +1,5 @@ ; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 -pre-alloc-split -stats |& \ -; RUN: not grep {pre-alloc-split} +; RUN: grep {pre-alloc-split} | count 2 define i32 @t() { entry: From monping at apple.com Tue Nov 18 22:33:03 2008 From: monping at apple.com (Mon Ping Wang) Date: Tue, 18 Nov 2008 20:33:03 -0800 Subject: [llvm-commits] [llvm] r59399 - in /llvm/trunk: lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp test/CodeGen/X86/vec_shuffle-25.ll test/CodeGen/X86/vec_shuffle-26.ll test/CodeGen/X86/vec_shuffle-27.ll In-Reply-To: References: <200811160506.mAG56SV9023318@zion.cs.uiuc.edu> Message-ID: Hi Evan, On Nov 18, 2008, at 10:00 AM, Evan Cheng wrote: > Hi Mon Ping, > > Thanks. Some nitpicks below. > > Evan > > On Nov 15, 2008, at 9:06 PM, Mon P Wang wrote: > >> [deleted text] >> >> >> void SelectionDAGLowering::visitShuffleVector(User &I) { >> - SDValue V1 = getValue(I.getOperand(0)); >> - SDValue V2 = getValue(I.getOperand(1)); >> + SDValue Srcs[2]; >> + Srcs[0] = getValue(I.getOperand(0)); >> + Srcs[1] = getValue(I.getOperand(1)); > > A common idiom used is: > SDValue Srcs[] = { getValue(I.getOperand(0), > getValue(I.getOperand(1)) }; > > Is an array preferrable to V1 and V2? > Probably not. Src1 and Src2 is preferable to V1 and V2 as it is a little more descriptive. I'll make the change. > >> >> SDValue Mask = getValue(I.getOperand(2)); >> >> MVT VT = TLI.getValueType(I.getType()); >> - MVT VT1 = V1.getValueType(); >> - unsigned MaskNumElts = Mask.getNumOperands(); >> - unsigned Src1NumElts = VT1.getVectorNumElements(); >> + MVT SrcVT = Srcs[0].getValueType(); >> + int MaskNumElts = Mask.getNumOperands(); >> + int SrcNumElts = SrcVT.getVectorNumElements(); > > Why int instead of unsigned? > When I was checking the range for the indexes, I set the values to be out of range, i.e., -1 and SrcNumElts. This makes the range a integer and since I compare with SrcNumElts, I would be doing a signed to unsigned comparison. Making them all int avoid this. >> [Deleted Text] >> + >> + if (SrcNumElts < MaskNumElts && MaskNumElts % SrcNumElts == 0) { >> + // Mask is longer than the source vectors and is a multiple of >> the source >> + // vectors. We can use concatenate vector to make the mask and >> vectors >> + // length match. > > lengthes. > I'll fix this. >> + if (SrcNumElts*2 == MaskNumElts && SequentialMask(Mask, 0)) { >> + // The shuffle is concatenating two vectors together. >> + setValue(&I, DAG.getNode(ISD::CONCAT_VECTORS, VT, Srcs[0], >> Srcs[1])); >> return; >> } >> >> - // Pad both vectors with undefs to the same size as the mask. >> - unsigned NumConcat = MaskNumElts / Src1NumElts; >> - std::vector UnOps(Src1NumElts, >> - DAG.getNode(ISD::UNDEF, >> - >> VT1.getVectorElementType())); >> - SDValue UndefVal = DAG.getNode(ISD::BUILD_VECTOR, VT1, >> - &UnOps[0], UnOps.size()); >> + // Pad both vectors with undefs to make them the same length as >> the mask. >> + unsigned NumConcat = MaskNumElts / SrcNumElts; >> + SDValue UndefVal = DAG.getNode(ISD::UNDEF, SrcVT); >> >> SmallVector MOps1, MOps2; >> - MOps1.push_back(V1); >> - MOps2.push_back(V2); >> + MOps1.push_back(Srcs[0]); >> + MOps2.push_back(Srcs[1]); >> for (unsigned i = 1; i != NumConcat; ++i) { >> MOps1.push_back(UndefVal); >> MOps2.push_back(UndefVal); >> } > > It seems silly to use vectors instead of arrays here. We could use a dynamically allocated array via new. >>>> [Deleted Text] >> >> >> >> + int Idx = cast(Arg)->getZExtValue(); >> + int Input = 0; >> + if (Idx >= SrcNumElts) { >> + Input = 1; >> + Idx -= SrcNumElts; >> } >> - Mask = DAG.getNode(ISD::BUILD_VECTOR, Mask.getValueType(), >> - &MappedOps[0], MappedOps.size()); >> + if (Idx > MaxRange[Input]) >> + MaxRange[Input] = Idx; >> + if (Idx < MinRange[Input]) >> + MinRange[Input] = Idx; >> + } >> + } >> >> - setValue(&I, DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V1, V2, >> Mask)); >> - return; >> + // Check if the access is smaller than the vector size and can >> we find >> + // a reasonable extract index. >> + int RangeUse[2]; // 0 = Unused, 1 = Extract, 2 = Can not >> Extract. > > Perhaps initialize RangeUse with 2's to eliminate some nesting below? > That make sense. I can remove a few cases. >> >> + int StartIdx[2]; // StartIdx to extract from >> + for (int Input=0; Input < 2; ++Input) { > > int -> unsigned? > See above. Thanks for the comments, -- Mon Ping -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20081118/515bab4e/attachment.html From isanbard at gmail.com Tue Nov 18 23:56:17 2008 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 19 Nov 2008 05:56:17 -0000 Subject: [llvm-commits] [llvm] r59592 - /llvm/trunk/docs/LangRef.html Message-ID: <200811190556.mAJ5uH1M004382@zion.cs.uiuc.edu> Author: void Date: Tue Nov 18 23:56:17 2008 New Revision: 59592 URL: http://llvm.org/viewvc/llvm-project?rev=59592&view=rev Log: - Move the stackprotector intrinsic to the general section. - Rewrite the sentence to make it look as if English is my first language. Modified: llvm/trunk/docs/LangRef.html Modified: llvm/trunk/docs/LangRef.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=59592&r1=59591&r2=59592&view=diff ============================================================================== --- llvm/trunk/docs/LangRef.html (original) +++ llvm/trunk/docs/LangRef.html Tue Nov 18 23:56:17 2008 @@ -214,11 +214,6 @@
    2. 'llvm.init.trampoline' Intrinsic
  • -
  • Stack Protector Intrinsic -
      -
    1. 'llvm.stackprotector' Intrinsic
    2. -
    -
  • Atomic intrinsics
    1. llvm.memory_barrier
    2. @@ -239,11 +234,13 @@
    3. General intrinsics
      1. - llvm.var.annotation' Intrinsic
      2. + 'llvm.var.annotation' Intrinsic
      3. - llvm.annotation.*' Intrinsic
      4. + 'llvm.annotation.*' Intrinsic
      5. - llvm.trap' Intrinsic
      6. + 'llvm.trap' Intrinsic +
      7. + 'llvm.stackprotector' Intrinsic
    @@ -5809,54 +5806,6 @@ - -
    -

    - This intrinsic is used when stack protectors are required. LLVM generates a - call to load the randomized stack protector guard's value. The intrinsic is - used so that LLVM can ensure that the stack guard is placed onto the stack in - the appropriate place—before local variables are allocated on the stack. -

    -
    - - - -
    -
    Syntax:
    -
    -declare void @llvm.stackprotector( i8* <guard>, i8** <slot> )
    -
    -
    -
    Overview:
    -

    - The llvm.stackprotector intrinsic takes the guard and stores - it onto the stack at slot. The stack slot is adjusted to ensure that - it's before local variables are allocated on the stack. -

    -
    Arguments:
    -

    - The llvm.stackprotector intrinsic requires two pointer arguments. The - first argument is the value loaded from the stack guard - @__stack_chk_guard. The second variable is an alloca that - has enough space to hold the value of the guard. -

    -
    Semantics:
    -

    - This intrinsic causes the prologue/epilogue inserter to force the position of - the AllocaInst stack slot to be before local variables on the - stack. This is to ensure that if a local variable on the stack is overwritten, - it will destroy the value of the guard. When the function exits, the guard on - the stack is checked against the original guard. If they're different, then - the program aborts by calling the __stack_chk_fail() function. -

    -
    - - - @@ -6472,6 +6421,40 @@

    + + +
    +
    Syntax:
    +
    +declare void @llvm.stackprotector( i8* <guard>, i8** <slot> )
    +
    +
    +
    Overview:
    +

    + The llvm.stackprotector intrinsic takes the guard and stores + it onto the stack at slot. The stack slot is adjusted to ensure that + it is placed on the stack before local variables. +

    +
    Arguments:
    +

    + The llvm.stackprotector intrinsic requires two pointer arguments. The + first argument is the value loaded from the stack guard + @__stack_chk_guard. The second variable is an alloca that + has enough space to hold the value of the guard. +

    +
    Semantics:
    +

    + This intrinsic causes the prologue/epilogue inserter to force the position of + the AllocaInst stack slot to be before local variables on the + stack. This is to ensure that if a local variable on the stack is overwritten, + it will destroy the value of the guard. When the function exits, the guard on + the stack is checked against the original guard. If they're different, then + the program aborts by calling the __stack_chk_fail() function. +

    +
    +
    From evan.cheng at apple.com Wed Nov 19 00:09:24 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 18 Nov 2008 22:09:24 -0800 Subject: [llvm-commits] [llvm] r59587 - in /llvm/trunk: lib/CodeGen/PreAllocSplitting.cpp test/CodeGen/X86/pre-split2.ll In-Reply-To: <200811190428.mAJ4SUqX001355@zion.cs.uiuc.edu> References: <200811190428.mAJ4SUqX001355@zion.cs.uiuc.edu> Message-ID: <724773FF-32A5-4695-B93A-B9E6AB176E0C@apple.com> Awesome! Thanks Owen. Can you refactor to avoid code duplication in Rematerialize? Evan On Nov 18, 2008, at 8:28 PM, Owen Anderson wrote: > Author: resistor > Date: Tue Nov 18 22:28:29 2008 > New Revision: 59587 > > URL: http://llvm.org/viewvc/llvm-project?rev=59587&view=rev > Log: > Add support for rematerialization in pre-alloc-splitting. > > Modified: > llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp > llvm/trunk/test/CodeGen/X86/pre-split2.ll > > Modified: llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp?rev=59587&r1=59586&r2=59587&view=diff > > === > === > === > ===================================================================== > --- llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp (original) > +++ llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp Tue Nov 18 22:28:29 > 2008 > @@ -39,6 +39,7 @@ > static cl::opt PreSplitLimit("pre-split-limit", cl::init(-1), > cl::Hidden); > > STATISTIC(NumSplits, "Number of intervals split"); > +STATISTIC(NumRemats, "Number of intervals split by > rematerialization"); > > namespace { > class VISIBILITY_HIDDEN PreAllocSplitting : public > MachineFunctionPass { > @@ -153,6 +154,11 @@ > > bool createsNewJoin(LiveRange* LR, MachineBasicBlock* DefMBB, > MachineBasicBlock* BarrierMBB); > + bool Rematerialize(unsigned vreg, VNInfo* ValNo, > + MachineInstr* DefMI, > + MachineBasicBlock::iterator RestorePt, > + unsigned RestoreIdx, > + SmallPtrSet& RefsInMBB); > }; > } // end anonymous namespace > > @@ -627,6 +633,90 @@ > return; > } > > +bool PreAllocSplitting::Rematerialize(unsigned vreg, VNInfo* ValNo, > + MachineInstr* DefMI, > + MachineBasicBlock::iterator > RestorePt, > + unsigned RestoreIdx, > + SmallPtrSet& > RefsInMBB) { > + MachineBasicBlock& MBB = *RestorePt->getParent(); > + > + MachineBasicBlock::iterator KillPt = BarrierMBB->end(); > + unsigned KillIdx = 0; > + if (ValNo->def == ~0U || DefMI->getParent() == BarrierMBB) > + KillPt = findSpillPoint(BarrierMBB, Barrier, NULL, RefsInMBB, > KillIdx); > + else > + KillPt = findNextEmptySlot(DefMI->getParent(), DefMI, KillIdx); > + > + if (KillPt == DefMI->getParent()->end()) > + return false; > + > + TII->reMaterialize(MBB, RestorePt, vreg, DefMI); > + LIs->InsertMachineInstrInMaps(prior(RestorePt), RestoreIdx); > + > + if (KillPt->getParent() == BarrierMBB) { > + UpdateRegisterInterval(ValNo, LIs->getUseIndex(KillIdx)+1, > + LIs->getDefIndex(RestoreIdx)); > + > + ++NumSplits; > + ++NumRemats; > + return true; > + } > + > + // Shrink wrap the live interval by walking up the CFG and find the > + // new kills. > + // Now let's find all the uses of the val#. > + DenseMap > > Uses; > + DenseMap > > UseMIs; > + SmallPtrSet Seen; > + SmallVector UseMBBs; > + for (MachineRegisterInfo::use_iterator UI = MRI->use_begin(CurrLI- > >reg), > + UE = MRI->use_end(); UI != UE; ++UI) { > + MachineOperand &UseMO = UI.getOperand(); > + MachineInstr *UseMI = UseMO.getParent(); > + unsigned UseIdx = LIs->getInstructionIndex(UseMI); > + LiveInterval::iterator ULR = CurrLI- > >FindLiveRangeContaining(UseIdx); > + if (ULR->valno != ValNo) > + continue; > + MachineBasicBlock *UseMBB = UseMI->getParent(); > + // Remember which other mbb's use this val#. > + if (Seen.insert(UseMBB) && UseMBB != BarrierMBB) > + UseMBBs.push_back(UseMBB); > + DenseMap > >::iterator > + UMII = Uses.find(UseMBB); > + if (UMII != Uses.end()) { > + DenseMap > >::iterator > + UMII2 = UseMIs.find(UseMBB); > + UMII->second.push_back(&UseMO); > + UMII2->second.insert(UseMI); > + } else { > + SmallVector Ops; > + Ops.push_back(&UseMO); > + Uses.insert(std::make_pair(UseMBB, Ops)); > + SmallPtrSet MIs; > + MIs.insert(UseMI); > + UseMIs.insert(std::make_pair(UseMBB, MIs)); > + } > + } > + > + // Walk up the predecessor chains. > + SmallPtrSet Visited; > + ShrinkWrapLiveInterval(ValNo, BarrierMBB, NULL, DefMI- > >getParent(), Visited, > + Uses, UseMIs, UseMBBs); > + > + // FIXME: If ValNo->hasPHIKill is false, then renumber the val# by > + // the restore. > + > + // Remove live range from barrier to the restore. FIXME: Find a > better > + // point to re-start the live interval. > + UpdateRegisterInterval(ValNo, LIs->getUseIndex(BarrierIdx)+1, > + LIs->getDefIndex(RestoreIdx)); > + > + ++NumSplits; > + ++NumRemats; > + return true; > + > +} > + > /// SplitRegLiveInterval - Split (spill and restore) the given live > interval > /// so it would not cross the barrier that's being processed. Shrink > wrap > /// (minimize) the live interval to the last uses. > @@ -644,11 +734,8 @@ > abort(); > } > > - // FIXME: For now, if definition is rematerializable, do not split. > MachineInstr *DefMI = (ValNo->def != ~0U) > ? LIs->getInstructionFromIndex(ValNo->def) : NULL; > - if (DefMI && LIs->isReMaterializable(*LI, ValNo, DefMI)) > - return false; > > // If this would create a new join point, do not split. > if (DefMI && createsNewJoin(LR, DefMI->getParent(), Barrier- > >getParent())) > @@ -670,6 +757,11 @@ > if (RestorePt == BarrierMBB->end()) > return false; > > + if (DefMI && LIs->isReMaterializable(*LI, ValNo, DefMI)) > + if (Rematerialize(LI->reg, ValNo, DefMI, RestorePt, > + RestoreIndex, RefsInMBB)) > + return true; > + > // Add a spill either before the barrier or after the definition. > MachineBasicBlock *DefMBB = DefMI ? DefMI->getParent() : NULL; > const TargetRegisterClass *RC = MRI->getRegClass(CurrLI->reg); > > Modified: llvm/trunk/test/CodeGen/X86/pre-split2.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/pre-split2.ll?rev=59587&r1=59586&r2=59587&view=diff > > === > === > === > ===================================================================== > --- llvm/trunk/test/CodeGen/X86/pre-split2.ll (original) > +++ llvm/trunk/test/CodeGen/X86/pre-split2.ll Tue Nov 18 22:28:29 2008 > @@ -1,5 +1,5 @@ > ; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 -pre-alloc-split - > stats |& \ > -; RUN: not grep {pre-alloc-split} > +; RUN: grep {pre-alloc-split} | count 2 > > define i32 @t() { > entry: > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From sabre at nondot.org Wed Nov 19 00:45:08 2008 From: sabre at nondot.org (Chris Lattner) Date: Wed, 19 Nov 2008 06:45:08 -0000 Subject: [llvm-commits] [llvm] r59595 - /llvm/trunk/include/llvm/Support/Streams.h Message-ID: <200811190645.mAJ6j8Ro006038@zion.cs.uiuc.edu> Author: lattner Date: Wed Nov 19 00:45:06 2008 New Revision: 59595 URL: http://llvm.org/viewvc/llvm-project?rev=59595&view=rev Log: add a write method. Modified: llvm/trunk/include/llvm/Support/Streams.h Modified: llvm/trunk/include/llvm/Support/Streams.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/Streams.h?rev=59595&r1=59594&r2=59595&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/Streams.h (original) +++ llvm/trunk/include/llvm/Support/Streams.h Wed Nov 19 00:45:06 2008 @@ -64,6 +64,12 @@ return *this; } + template + BaseStream &write(const Ty &A, unsigned N) { + if (Stream) Stream->write(A, N); + return *this; + } + operator StreamTy* () { return Stream; } bool operator == (const StreamTy &S) { return &S == Stream; } From baldrick at free.fr Wed Nov 19 02:01:08 2008 From: baldrick at free.fr (Duncan Sands) Date: Wed, 19 Nov 2008 09:01:08 +0100 Subject: [llvm-commits] [llvm] r59563 - /llvm/trunk/lib/VMCore/Verifier.cpp In-Reply-To: <200811182309.mAIN9VQv020509@zion.cs.uiuc.edu> References: <200811182309.mAIN9VQv020509@zion.cs.uiuc.edu> Message-ID: <200811190901.09006.baldrick@free.fr> > Verify that the second parameter of the stacprotector intrinsic is an alloca > instruction. Or a bitcast of an alloca? (If so, I suggest you use stripPointerCasts). Ciao, Duncan. From sanjiv.gupta at microchip.com Wed Nov 19 02:50:19 2008 From: sanjiv.gupta at microchip.com (Sanjiv Gupta) Date: Wed, 19 Nov 2008 08:50:19 -0000 Subject: [llvm-commits] [llvm] r59612 - /llvm/trunk/include/llvm/Intrinsics.td Message-ID: <200811190850.mAJ8oJY4015533@zion.cs.uiuc.edu> Author: sgupta Date: Wed Nov 19 02:50:17 2008 New Revision: 59612 URL: http://llvm.org/viewvc/llvm-project?rev=59612&view=rev Log: Int type for PIC16 is i16. Added i16 intrinsics for memmove, memcpy and memset. Modified: llvm/trunk/include/llvm/Intrinsics.td Modified: llvm/trunk/include/llvm/Intrinsics.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Intrinsics.td?rev=59612&r1=59611&r2=59612&view=diff ============================================================================== --- llvm/trunk/include/llvm/Intrinsics.td (original) +++ llvm/trunk/include/llvm/Intrinsics.td Wed Nov 19 02:50:17 2008 @@ -190,18 +190,27 @@ // let Properties = [IntrWriteArgMem] in { + def int_memcpy_i16 : Intrinsic<[llvm_void_ty], + [llvm_ptr_ty, llvm_ptr_ty, + llvm_i16_ty, llvm_i16_ty]>; def int_memcpy_i32 : Intrinsic<[llvm_void_ty], [llvm_ptr_ty, llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty]>; def int_memcpy_i64 : Intrinsic<[llvm_void_ty], [llvm_ptr_ty, llvm_ptr_ty, llvm_i64_ty, llvm_i32_ty]>; + def int_memmove_i16 : Intrinsic<[llvm_void_ty], + [llvm_ptr_ty, llvm_ptr_ty, + llvm_i16_ty, llvm_i16_ty]>; def int_memmove_i32 : Intrinsic<[llvm_void_ty], [llvm_ptr_ty, llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty]>; def int_memmove_i64 : Intrinsic<[llvm_void_ty], [llvm_ptr_ty, llvm_ptr_ty, llvm_i64_ty, llvm_i32_ty]>; + def int_memset_i16 : Intrinsic<[llvm_void_ty], + [llvm_ptr_ty, llvm_i8_ty, + llvm_i16_ty, llvm_i16_ty]>; def int_memset_i32 : Intrinsic<[llvm_void_ty], [llvm_ptr_ty, llvm_i8_ty, llvm_i32_ty, llvm_i32_ty]>; From isanbard at gmail.com Wed Nov 19 03:17:16 2008 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 19 Nov 2008 09:17:16 -0000 Subject: [llvm-commits] [llvm] r59614 - /llvm/trunk/lib/VMCore/Verifier.cpp Message-ID: <200811190917.mAJ9HH9a021435@zion.cs.uiuc.edu> Author: void Date: Wed Nov 19 03:17:16 2008 New Revision: 59614 URL: http://llvm.org/viewvc/llvm-project?rev=59614&view=rev Log: Use stripPointerCasts when checking for AllocaInsts for the stackprotector intrinsic. Modified: llvm/trunk/lib/VMCore/Verifier.cpp Modified: llvm/trunk/lib/VMCore/Verifier.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Verifier.cpp?rev=59614&r1=59613&r2=59614&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Verifier.cpp (original) +++ llvm/trunk/lib/VMCore/Verifier.cpp Wed Nov 19 03:17:16 2008 @@ -1375,7 +1375,7 @@ &CI); break; case Intrinsic::stackprotector: - Assert1(isa(CI.getOperand(2)), + Assert1(isa(CI.getOperand(2)->stripPointerCasts()), "llvm.stackprotector parameter #2 must resolve to an alloca.", &CI); break; From isanbard at gmail.com Wed Nov 19 03:17:15 2008 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 19 Nov 2008 01:17:15 -0800 Subject: [llvm-commits] [llvm] r59563 - /llvm/trunk/lib/VMCore/Verifier.cpp In-Reply-To: <200811190901.09006.baldrick@free.fr> References: <200811182309.mAIN9VQv020509@zion.cs.uiuc.edu> <200811190901.09006.baldrick@free.fr> Message-ID: <8F467E74-FD11-4AE2-ABD5-DF2F9BE923C4@gmail.com> Okay. Done. -bw On Nov 19, 2008, at 12:01 AM, Duncan Sands wrote: >> Verify that the second parameter of the stacprotector intrinsic is >> an alloca >> instruction. > > Or a bitcast of an alloca? (If so, I suggest you use > stripPointerCasts). > > Ciao, > > Duncan. From wangmp at apple.com Wed Nov 19 04:15:27 2008 From: wangmp at apple.com (Mon Ping Wang) Date: Wed, 19 Nov 2008 02:15:27 -0800 Subject: [llvm-commits] Patch: Widening in LegalizeType Message-ID: <78927E77-7EDF-41BD-98E7-4FC8C725E216@apple.com> Hi, This is a patch for adding widening support into LegalizeType. One issue that I ran into is that for Vector shuffles, the mask operand doesn't need to be widened even though it type might indicate that it should be widened .e.g, a shuffle of v2i64 would have a shuffle mask v2i32. To avoid this problem when scanning the operands, it checks if it is a vector shuffle and if it is the second operand. If so, it adds the node to the set of result nodes to ignore and continue. I didn't include the tests that will go into the check in. Please let me know if you have any comments. Thanks, -- Mon Ping -------------- next part -------------- A non-text attachment was scrubbed... Name: widen.patch Type: application/octet-stream Size: 45135 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20081119/898864e6/attachment.obj From baldrick at free.fr Wed Nov 19 04:32:12 2008 From: baldrick at free.fr (Duncan Sands) Date: Wed, 19 Nov 2008 11:32:12 +0100 Subject: [llvm-commits] Patch: Widening in LegalizeType In-Reply-To: <78927E77-7EDF-41BD-98E7-4FC8C725E216@apple.com> References: <78927E77-7EDF-41BD-98E7-4FC8C725E216@apple.com> Message-ID: <200811191132.12845.baldrick@free.fr> Hi Mon Ping, > ... One issue that I ran into is that for Vector shuffles, the mask operand > doesn't need to be widened even though it type might indicate that it > should be widened .e.g, a shuffle of v2i64 would have a shuffle mask > v2i32. this is a general problem with vector shuffle, see PR2957. I will comment on the patch tomorrow (hopefully). Ciao, Duncan. From wangmp at apple.com Wed Nov 19 04:49:23 2008 From: wangmp at apple.com (Mon Ping Wang) Date: Wed, 19 Nov 2008 02:49:23 -0800 Subject: [llvm-commits] Patch: Widening in LegalizeType In-Reply-To: <200811191132.12845.baldrick@free.fr> References: <78927E77-7EDF-41BD-98E7-4FC8C725E216@apple.com> <200811191132.12845.baldrick@free.fr> Message-ID: I totally missed that bug when it came through. Thanks for the pointer. -- Mon Ping On Nov 19, 2008, at 2:32 AM, Duncan Sands wrote: > Hi Mon Ping, > >> ... One issue that I ran into is that for Vector shuffles, the mask >> operand >> doesn't need to be widened even though it type might indicate that it >> should be widened .e.g, a shuffle of v2i64 would have a shuffle mask >> v2i32. > > this is a general problem with vector shuffle, see PR2957. I will > comment > on the patch tomorrow (hopefully). > > Ciao, > > Duncan. From sanjiv.gupta at microchip.com Wed Nov 19 05:00:58 2008 From: sanjiv.gupta at microchip.com (Sanjiv Gupta) Date: Wed, 19 Nov 2008 11:00:58 -0000 Subject: [llvm-commits] [llvm] r59617 - in /llvm/trunk/lib/Target/PIC16: PIC16.h PIC16.td PIC16AsmPrinter.cpp PIC16CallingConv.td PIC16ConstantPoolValue.cpp PIC16ConstantPoolValue.h PIC16ISelDAGToDAG.cpp PIC16ISelDAGToDAG.h PIC16ISelLowering.cpp PIC16ISelLowering.h PIC16InstrFormats.td PIC16InstrInfo.cpp PIC16InstrInfo.h PIC16InstrInfo.td PIC16RegisterInfo.cpp PIC16RegisterInfo.h PIC16RegisterInfo.td PIC16Subtarget.cpp PIC16Subtarget.h PIC16TargetAsmInfo.cpp PIC16TargetAsmInfo.h PIC16TargetMachine.cpp PIC16TargetMachine.h Message-ID: <200811191100.mAJB0xC0026723@zion.cs.uiuc.edu> Author: sgupta Date: Wed Nov 19 05:00:54 2008 New Revision: 59617 URL: http://llvm.org/viewvc/llvm-project?rev=59617&view=rev Log: Added a more function PIC16 backend. However to get this working a patch in ExpandIntegerOperand (LegalizeIntegerTypes.cpp) is needed which is yet to be reworked and submitted. Added: llvm/trunk/lib/Target/PIC16/PIC16ISelDAGToDAG.h Removed: llvm/trunk/lib/Target/PIC16/PIC16CallingConv.td llvm/trunk/lib/Target/PIC16/PIC16ConstantPoolValue.cpp llvm/trunk/lib/Target/PIC16/PIC16ConstantPoolValue.h Modified: llvm/trunk/lib/Target/PIC16/PIC16.h llvm/trunk/lib/Target/PIC16/PIC16.td llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.cpp llvm/trunk/lib/Target/PIC16/PIC16ISelDAGToDAG.cpp llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.h llvm/trunk/lib/Target/PIC16/PIC16InstrFormats.td llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.cpp llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.h llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.td llvm/trunk/lib/Target/PIC16/PIC16RegisterInfo.cpp llvm/trunk/lib/Target/PIC16/PIC16RegisterInfo.h llvm/trunk/lib/Target/PIC16/PIC16RegisterInfo.td llvm/trunk/lib/Target/PIC16/PIC16Subtarget.cpp llvm/trunk/lib/Target/PIC16/PIC16Subtarget.h llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.cpp llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.h llvm/trunk/lib/Target/PIC16/PIC16TargetMachine.cpp llvm/trunk/lib/Target/PIC16/PIC16TargetMachine.h Modified: llvm/trunk/lib/Target/PIC16/PIC16.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16.h?rev=59617&r1=59616&r2=59617&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16.h (original) +++ llvm/trunk/lib/Target/PIC16/PIC16.h Wed Nov 19 05:00:54 2008 @@ -12,14 +12,13 @@ // //===----------------------------------------------------------------------===// -#ifndef TARGET_PIC16_H -#define TARGET_PIC16_H +#ifndef LLVM_TARGET_PIC16_H +#define LLVM_TARGET_PIC16_H #include namespace llvm { class PIC16TargetMachine; - class FunctionPassManager; class FunctionPass; class MachineCodeEmitter; class raw_ostream; Modified: llvm/trunk/lib/Target/PIC16/PIC16.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16.td?rev=59617&r1=59616&r2=59617&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16.td (original) +++ llvm/trunk/lib/Target/PIC16/PIC16.td Wed Nov 19 05:00:54 2008 @@ -15,30 +15,24 @@ include "../Target.td" -//===----------------------------------------------------------------------===// -// Descriptions -//===----------------------------------------------------------------------===// - include "PIC16RegisterInfo.td" -include "PIC16CallingConv.td" include "PIC16InstrInfo.td" -def PIC16InstrInfo : InstrInfo { - let TSFlagsFields = []; - let TSFlagsShifts = []; -} - - - -// Not currently supported, but work as SubtargetFeature placeholder. -def FeaturePIC16Old : SubtargetFeature<"pic16old", "IsPIC16Old", "true", - "PIC16 Old ISA Support">; +//===----------------------------------------------------------------------===// +// Subtarget Features. +//===----------------------------------------------------------------------===// +def FeatureCooper : SubtargetFeature<"cooper", "IsCooper", "true", + "PIC16 Cooper ISA Support">; //===----------------------------------------------------------------------===// -// PIC16 processors supported. +// PIC16 supported processors. //===----------------------------------------------------------------------===// def : Processor<"generic", NoItineraries, []>; +def : Processor<"cooper", NoItineraries, [FeatureCooper]>; + + +def PIC16InstrInfo : InstrInfo {} def PIC16 : Target { let InstructionSet = PIC16InstrInfo; Modified: llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.cpp?rev=59617&r1=59616&r2=59617&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.cpp Wed Nov 19 05:00:54 2008 @@ -12,194 +12,70 @@ // //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "asm-printer" -#include "PIC16.h" -#include "PIC16TargetMachine.h" -#include "PIC16ConstantPoolValue.h" -#include "PIC16InstrInfo.h" -#include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" +#include "PIC16AsmPrinter.h" +#include "PIC16TargetAsmInfo.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/Support/Mangler.h" +#include "llvm/Function.h" #include "llvm/Module.h" -#include "llvm/ADT/Statistic.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/CodeGen/AsmPrinter.h" -#include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/CodeGen/MachineConstantPool.h" #include "llvm/CodeGen/MachineFrameInfo.h" -#include "llvm/CodeGen/MachineInstr.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/Mangler.h" -#include "llvm/Support/MathExtras.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/Target/TargetAsmInfo.h" -#include "llvm/Target/TargetData.h" -#include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetOptions.h" -#include +#include "llvm/DerivedTypes.h" using namespace llvm; -STATISTIC(EmittedInsts, "Number of machine instrs printed"); - -namespace { - struct VISIBILITY_HIDDEN PIC16AsmPrinter : public AsmPrinter { - PIC16AsmPrinter(raw_ostream &O, TargetMachine &TM, const TargetAsmInfo *T) - : AsmPrinter(O, TM, T) { - } - - - /// We name each basic block in a Function with a unique number, so - /// that we can consistently refer to them later. This is cleared - /// at the beginning of each call to runOnMachineFunction(). - /// - typedef std::map ValueMapTy; - ValueMapTy NumberForBB; - - /// Keeps the set of GlobalValues that require non-lazy-pointers for - /// indirect access. - std::set GVNonLazyPtrs; - - /// Keeps the set of external function GlobalAddresses that the asm - /// printer should generate stubs for. - std::set FnStubs; - - /// True if asm printer is printing a series of CONSTPOOL_ENTRY. - bool InCPMode; - - virtual const char *getPassName() const { - return "PIC16 Assembly Printer"; - } - - void printOperand(const MachineInstr *MI, int opNum, - const char *Modifier = 0); - - void printSOImmOperand(const MachineInstr *MI, int opNum); - - void printAddrModeOperand(const MachineInstr *MI, int OpNo); - - void printRegisterList(const MachineInstr *MI, int opNum); - void printCPInstOperand(const MachineInstr *MI, int opNum, - const char *Modifier); - - - bool printInstruction(const MachineInstr *MI); // autogenerated. - void emitFunctionStart(MachineFunction &F); - bool runOnMachineFunction(MachineFunction &F); - bool doInitialization(Module &M); - bool doFinalization(Module &M); - - virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV); - - void getAnalysisUsage(AnalysisUsage &AU) const; - - public: - void SwitchToTextSection(const char *NewSection, - const GlobalValue *GV = NULL); - void SwitchToDataSection(const char *NewSection, - const GlobalValue *GV = NULL); - void SwitchToDataOvrSection(const char *NewSection, - const GlobalValue *GV = NULL); - }; -} // end of anonymous namespace - #include "PIC16GenAsmWriter.inc" -/// createPIC16CodePrinterPass - Returns a pass that prints the PIC16 -/// assembly code for a MachineFunction to the given output stream, -/// using the given target machine description. This should work -/// regardless of whether the function is in SSA form. -/// -FunctionPass *llvm::createPIC16CodePrinterPass(raw_ostream &o, - PIC16TargetMachine &tm) { - return new PIC16AsmPrinter(o, tm, tm.getTargetAsmInfo()); -} - -void PIC16AsmPrinter::getAnalysisUsage(AnalysisUsage &AU) const -{ - // FIXME: Currently unimplemented. -} - - -void PIC16AsmPrinter :: -EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) -{ - printDataDirective(MCPV->getType()); - - PIC16ConstantPoolValue *ACPV = (PIC16ConstantPoolValue*)MCPV; - GlobalValue *GV = ACPV->getGV(); - std::string Name = GV ? Mang->getValueName(GV) : TAI->getGlobalPrefix(); - if (!GV) - Name += ACPV->getSymbol(); - if (ACPV->isNonLazyPointer()) { - GVNonLazyPtrs.insert(Name); - O << TAI->getPrivateGlobalPrefix() << Name << "$non_lazy_ptr"; - } else if (ACPV->isStub()) { - FnStubs.insert(Name); - O << TAI->getPrivateGlobalPrefix() << Name << "$stub"; - } else { - O << Name; - } - - if (ACPV->hasModifier()) O << "(" << ACPV->getModifier() << ")"; - - if (ACPV->getPCAdjustment() != 0) { - O << "-(" << TAI->getPrivateGlobalPrefix() << "PC" - << utostr(ACPV->getLabelId()) - << "+" << (unsigned)ACPV->getPCAdjustment(); - - if (ACPV->mustAddCurrentAddress()) - O << "-."; - - O << ")"; - } - O << "\n"; - - // If the constant pool value is a extern weak symbol, remember to emit - // the weak reference. - if (GV && GV->hasExternalWeakLinkage()) - ExtWeakSymbols.insert(GV); -} - -/// emitFunctionStart - Emit the directives used by ASM on the start of -/// functions. -void PIC16AsmPrinter::emitFunctionStart(MachineFunction &MF) -{ - // Print out the label for the function. - const Function *F = MF.getFunction(); - MachineFrameInfo *FrameInfo = MF.getFrameInfo(); - if (FrameInfo->hasStackObjects()) { - int indexBegin = FrameInfo->getObjectIndexBegin(); - int indexEnd = FrameInfo->getObjectIndexEnd(); - while (indexBegin < indexEnd) { - if (indexBegin == 0) - SwitchToDataOvrSection(F->getParent()->getModuleIdentifier().c_str(), - F); - - O << "\t\t" << CurrentFnName << "_" << indexBegin << " " << "RES" - << " " << FrameInfo->getObjectSize(indexBegin) << "\n" ; - indexBegin++; +bool PIC16AsmPrinter::printMachineInstruction(const MachineInstr *MI) { + std::string NewBankselLabel; + unsigned Operands = MI->getNumOperands(); + if (Operands > 1) { + // Global address or external symbol should be second operand from last + // if we want to print banksel for it. + const MachineOperand &Op = MI->getOperand(Operands-2); + unsigned OpType = Op.getType(); + if (OpType == MachineOperand::MO_GlobalAddress || + OpType == MachineOperand::MO_ExternalSymbol) { + if (OpType == MachineOperand::MO_GlobalAddress ) + NewBankselLabel = Mang->getValueName(Op.getGlobal()); + else + NewBankselLabel = Op.getSymbolName(); + + // Operand after global address or external symbol should be banksel. + // Value 1 for this operand means we need to generate banksel else do not + // generate banksel. + const MachineOperand &BS = MI->getOperand(Operands-1); + if (((int)BS.getImm() == 1) && + (strcmp (CurrentBankselLabelInBasicBlock.c_str(), + NewBankselLabel.c_str()))) { + CurrentBankselLabelInBasicBlock = NewBankselLabel; + O << "\tbanksel "; + printOperand(MI, Operands-2); + O << "\n"; + } } } - SwitchToTextSection(CurrentFnName.c_str(), F); - O << "_" << CurrentFnName << ":" ; - O << "\n"; + printInstruction(MI); + return true; } - /// runOnMachineFunction - This uses the printInstruction() /// method to print assembly for each instruction. /// -bool PIC16AsmPrinter::runOnMachineFunction(MachineFunction &MF) -{ +bool PIC16AsmPrinter::runOnMachineFunction(MachineFunction &MF) { + // This calls the base class function required to be called at beginning + // of runOnMachineFunction. SetupMachineFunction(MF); - O << "\n"; - // What's my mangled name? - CurrentFnName = Mang->getValueName(MF.getFunction()); + // Get the mangled name. + const Function *F = MF.getFunction(); + CurrentFnName = Mang->getValueName(F); - // Emit the function start directives - emitFunctionStart(MF); + // Emit the function variables. + emitFunctionData(MF); + std::string codeSection; + codeSection = "code." + CurrentFnName + ".#"; + O << "\n"; + SwitchToTextSection (codeSection.c_str(),F); // Print out code for the function. for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); @@ -209,319 +85,317 @@ printBasicBlockLabel(I, true); O << '\n'; } + else + O << "_" << CurrentFnName << ":\n"; + CurrentBankselLabelInBasicBlock = ""; for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); II != E; ++II) { // Print the assembly for the instruction. - O << '\t'; - printInstruction(II); - ++EmittedInsts; + printMachineInstruction(II); } } + return false; // we didn't modify anything. +} - // We didn't modify anything. - return false; +/// createPIC16CodePrinterPass - Returns a pass that prints the PIC16 +/// assembly code for a MachineFunction to the given output stream, +/// using the given target machine description. This should work +/// regardless of whether the function is in SSA form. +/// +FunctionPass *llvm::createPIC16CodePrinterPass(raw_ostream &o, + PIC16TargetMachine &tm) { + return new PIC16AsmPrinter(o, tm, tm.getTargetAsmInfo()); } -void PIC16AsmPrinter:: -printOperand(const MachineInstr *MI, int opNum, const char *Modifier) -{ +void PIC16AsmPrinter::printOperand(const MachineInstr *MI, int opNum) { const MachineOperand &MO = MI->getOperand(opNum); - const TargetRegisterInfo &RI = *TM.getRegisterInfo(); switch (MO.getType()) { case MachineOperand::MO_Register: if (TargetRegisterInfo::isPhysicalRegister(MO.getReg())) - O << RI.get(MO.getReg()).Name; + O << TM.getRegisterInfo()->get(MO.getReg()).AsmName; else assert(0 && "not implemented"); - break; + return; - case MachineOperand::MO_Immediate: - if (!Modifier || strcmp(Modifier, "no_hash") != 0) - O << "#"; + case MachineOperand::MO_Immediate: O << (int)MO.getImm(); - break; - - case MachineOperand::MO_MachineBasicBlock: - printBasicBlockLabel(MO.getMBB()); return; - case MachineOperand::MO_GlobalAddress: - O << Mang->getValueName(MO.getGlobal())<<'+'<getValueName(MO.getGlobal()); break; - case MachineOperand::MO_ExternalSymbol: + case MachineOperand::MO_ExternalSymbol: O << MO.getSymbolName(); break; - case MachineOperand::MO_ConstantPoolIndex: - O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() - << '_' << MO.getIndex(); - break; - - case MachineOperand::MO_FrameIndex: - O << "_" << CurrentFnName - << '+' << MO.getIndex(); - break; - - case MachineOperand::MO_JumpTableIndex: - O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() - << '_' << MO.getIndex(); - break; - default: - O << ""; abort (); - break; - } // end switch. + assert(0 && " Operand type not supported."); + } } -static void -printSOImm(raw_ostream &O, int64_t V, const TargetAsmInfo *TAI) -{ - assert(V < (1 << 12) && "Not a valid so_imm value!"); - - O << (unsigned) V; +bool PIC16AsmPrinter::doInitialization (Module &M) { + bool Result = AsmPrinter::doInitialization(M); + // FIXME:: This is temporary solution to generate the include file. + // The processor should be passed to llc as in input and the header file + // should be generated accordingly. + O << "\t#include P16F1937.INC\n"; + + EmitInitData (M); + EmitUnInitData(M); + EmitRomData(M); + return Result; } -/// printSOImmOperand - SOImm is 4-bit rotated amount in bits 8-11 with 8-bit -/// immediate in bits 0-7. -void PIC16AsmPrinter::printSOImmOperand(const MachineInstr *MI, int OpNum) +void PIC16AsmPrinter::EmitInitData (Module &M) { - const MachineOperand &MO = MI->getOperand(OpNum); - assert(MO.isImm() && "Not a valid so_imm value!"); - printSOImm(O, MO.getImm(), TAI); -} + std::string iDataSection = "idata.#"; + SwitchToDataSection(iDataSection.c_str()); + for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); + I != E; ++I) { + if (!I->hasInitializer()) // External global require no code. + continue; + Constant *C = I->getInitializer(); + const PointerType *PtrTy = I->getType(); + int AddrSpace = PtrTy->getAddressSpace(); -void PIC16AsmPrinter::printAddrModeOperand(const MachineInstr *MI, int Op) -{ - const MachineOperand &MO1 = MI->getOperand(Op); - const MachineOperand &MO2 = MI->getOperand(Op+1); + if ((!C->isNullValue()) && (AddrSpace == PIC16ISD::RAM_SPACE)) { + + if (EmitSpecialLLVMGlobal(I)) + continue; - if (MO2.isFI()) { - printOperand(MI, Op+1); - return; - } + // Any variables reaching here with "." in its name is a local scope + // variable and should not be printed in global data section. + std::string name = Mang->getValueName(I); + if (name.find(".") != std::string::npos) + continue; - if (!MO1.isReg()) { - // FIXME: This is for CP entries, but isn't right. - printOperand(MI, Op); - return; + O << name; + EmitGlobalConstant(C); + } } +} - // If this is Stack Slot - if (MO1.isReg()) { - if (strcmp(TM.getRegisterInfo()->get(MO1.getReg()).Name, "SP") == 0) { - O << CurrentFnName <<"_"<< MO2.getImm(); - return; +void PIC16AsmPrinter::EmitConstantValueOnly(const Constant* CV) { + if (const ConstantInt *CI = dyn_cast(CV)) { + unsigned BitWidth = CI->getBitWidth(); + int Val = CI->getZExtValue(); + if (BitWidth == 8) { + // Expecting db directive here. In case of romdata we need to pad the + // word with zeros. + if (IsRomData) + O << 0 <<", "; + O << Val; + } + else if (BitWidth == 16) { + unsigned Element1, Element2; + Element1 = 0x00ff & Val; + Element2 = 0x00ff & (Val >> 8); + if (IsRomData) + O << 0 <<", "<> 8); + Element3 = 0x00ff & (Val >> 16); + Element4 = 0x00ff & (Val >> 24); + if (IsRomData) + O << 0 <<", "<< Element1 <<", "<< 0 <<", "<< Element2 <<", "<< 0 + <<", "<< Element3 <<", "<< 0 <<", "<< Element4; + else + O << Element1 <<", "<< Element2 <<", "<< Element3 <<", "<< Element4; } - O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).Name; - O << "+"; - O << MO2.getImm(); - O << "]"; return; } - - O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).Name; - O << "]"; + AsmPrinter::EmitConstantValueOnly(CV); } - -void PIC16AsmPrinter::printRegisterList(const MachineInstr *MI, int opNum) +void PIC16AsmPrinter::EmitRomData (Module &M) { - O << "{"; - for (unsigned i = opNum, e = MI->getNumOperands(); i != e; ++i) { - printOperand(MI, i); - if (i != e-1) O << ", "; - } - O << "}"; -} + std::string romDataSection = "romdata.#"; + SwitchToRomDataSection(romDataSection.c_str()); + IsRomData = true; + for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); + I != E; ++I) { + if (!I->hasInitializer()) // External global require no code. + continue; -void PIC16AsmPrinter:: -printCPInstOperand(const MachineInstr *MI, int OpNo, const char *Modifier) -{ - assert(Modifier && "This operand only works with a modifier!"); + Constant *C = I->getInitializer(); + const PointerType *PtrTy = I->getType(); + int AddrSpace = PtrTy->getAddressSpace(); + if ((!C->isNullValue()) && (AddrSpace == PIC16ISD::ROM_SPACE)) { - // There are two aspects to a CONSTANTPOOL_ENTRY operand, the label and the - // data itself. - if (!strcmp(Modifier, "label")) { - unsigned ID = MI->getOperand(OpNo).getImm(); - O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() - << '_' << ID << ":\n"; - } else { - assert(!strcmp(Modifier, "cpentry") && "Unknown modifier for CPE"); - unsigned CPI = MI->getOperand(OpNo).getIndex(); + if (EmitSpecialLLVMGlobal(I)) + continue; - const MachineConstantPoolEntry &MCPE = // Chasing pointers is fun? - MI->getParent()->getParent()->getConstantPool()->getConstants()[CPI]; - - if (MCPE.isMachineConstantPoolEntry()) - EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal); - else { - EmitGlobalConstant(MCPE.Val.ConstVal); - // remember to emit the weak reference - if (const GlobalValue *GV = dyn_cast(MCPE.Val.ConstVal)) - if (GV->hasExternalWeakLinkage()) - ExtWeakSymbols.insert(GV); + // Any variables reaching here with "." in its name is a local scope + // variable and should not be printed in global data section. + std::string name = Mang->getValueName(I); + if (name.find(".") != std::string::npos) + continue; + + O << name; + EmitGlobalConstant(C); + O << "\n"; } } + IsRomData = false; } -bool PIC16AsmPrinter::doInitialization(Module &M) -{ - bool Result = AsmPrinter::doInitialization(M); - return Result; -} - -bool PIC16AsmPrinter::doFinalization(Module &M) +void PIC16AsmPrinter::EmitUnInitData (Module &M) { + std::string uDataSection = "udata.#"; + SwitchToUDataSection(uDataSection.c_str()); const TargetData *TD = TM.getTargetData(); for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) { - if (!I->hasInitializer()) // External global require no code + if (!I->hasInitializer()) // External global require no code. continue; - if (EmitSpecialLLVMGlobal(I)) { - continue; + Constant *C = I->getInitializer(); + if (C->isNullValue()) { + + if (EmitSpecialLLVMGlobal(I)) + continue; + + // Any variables reaching here with "." in its name is a local scope + // variable and should not be printed in global data section. + std::string name = Mang->getValueName(I); + if (name.find(".") != std::string::npos) + continue; + + const Type *Ty = C->getType(); + unsigned Size = TD->getABITypeSize(Ty); + O << name << " " <<"RES"<< " " << Size ; + O << "\n"; } + } +} - std::string name = Mang->getValueName(I); +bool PIC16AsmPrinter::doFinalization(Module &M) { + O << "\t" << "END\n"; + bool Result = AsmPrinter::doFinalization(M); + return Result; +} + +void PIC16AsmPrinter::emitFunctionData(MachineFunction &MF) { + const Function *F = MF.getFunction(); + std::string FuncName = Mang->getValueName(F); + const Module *M = F->getParent(); + const TargetData *TD = TM.getTargetData(); + + // Emit the data section name. + O << "\n"; + std::string fDataSection = "fdata." + CurrentFnName + ".#"; + SwitchToUDataSection(fDataSection.c_str(), F); + // Emit the label for data section of current function. + O << "_frame_" << CurrentFnName << ":" ; + O << "\n"; + + // Emit the function variables. + + if (F->hasExternalLinkage()) { + O << "\t" << "GLOBAL _frame_" << CurrentFnName << "\n"; + O << "\t" << "GLOBAL _" << CurrentFnName << "\n"; + } + // In PIC16 all the function arguments and local variables are global. + // Therefore to get the variable belonging to this function entire + // global list will be traversed and variables belonging to this function + // will be emitted in the current data section. + for (Module::const_global_iterator I = M->global_begin(), E = M->global_end(); + I != E; ++I) { + std::string VarName = Mang->getValueName(I); + + // The variables of a function are of form FuncName.* . If this variable + // does not belong to this function then continue. + if (!(VarName.find(FuncName + ".") == 0 ? true : false)) + continue; + Constant *C = I->getInitializer(); const Type *Ty = C->getType(); unsigned Size = TD->getABITypeSize(Ty); - unsigned Align = TD->getPreferredAlignmentLog(I); + // Emit memory reserve directive. + O << VarName << " RES " << Size << "\n"; + } + emitFunctionTempData(MF); +} - const char *VisibilityDirective = NULL; - if (I->hasHiddenVisibility()) - VisibilityDirective = TAI->getHiddenDirective(); - else if (I->hasProtectedVisibility()) - VisibilityDirective = TAI->getProtectedDirective(); +void PIC16AsmPrinter::emitFunctionTempData(MachineFunction &MF) { + // Emit temporary variables. + MachineFrameInfo *FrameInfo = MF.getFrameInfo(); + if (FrameInfo->hasStackObjects()) { + int indexBegin = FrameInfo->getObjectIndexBegin(); + int indexEnd = FrameInfo->getObjectIndexEnd(); - if (VisibilityDirective) - O << VisibilityDirective << name << "\n"; + if (indexBegin < indexEnd) + O << CurrentFnName << ".tmp RES"<< " " + <isNullValue()) { - if (I->hasExternalLinkage()) { - if (const char *Directive = TAI->getZeroFillDirective()) { - O << "\t.globl\t" << name << "\n"; - O << Directive << "__DATA__, __common, " << name << ", " - << Size << ", " << Align << "\n"; - continue; - } - } +/// The function is same as AsmPrinter::SwitchtoDataSection except the call +/// to getUDataSectionStartSuffix. +void PIC16AsmPrinter::SwitchToUDataSection(const char *NewSection, + const GlobalValue *GV) { + std::string NS; + if (GV && GV->hasSection()) + NS = TAI->getSwitchToSectionDirective() + GV->getSection(); + else + NS = NewSection; - if (!I->hasSection() && - (I->hasInternalLinkage() || I->hasWeakLinkage() || - I->hasLinkOnceLinkage() || I->hasCommonLinkage())) { - if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it. - SwitchToDataSection(M.getModuleIdentifier().c_str(), I); - if (TAI->getLCOMMDirective() != NULL) { - if (I->hasInternalLinkage()) { - O << TAI->getLCOMMDirective() << name << "," << Size; - } else - O << TAI->getCOMMDirective() << name << "," << Size; - } else { - if (I->hasInternalLinkage()) - O << "\t.local\t" << name << "\n"; - - O << TAI->getCOMMDirective() <<"\t" << name << " " <<"RES"<< " " - << Size; - O << "\n\t\tGLOBAL" <<" "<< name; - if (TAI->getCOMMDirectiveTakesAlignment()) - O << "," << (TAI->getAlignmentIsInBytes() ? (1 << Align) : Align); - } - continue; - } - } + // If we're already in this section, we're done. + if (CurrentSection == NS) return; - switch (I->getLinkage()) { - case GlobalValue::AppendingLinkage: - // FIXME: appending linkage variables should go into a section of - // their name or something. For now, just emit them as external. - // FALL THROUGH - - case GlobalValue::ExternalLinkage: - O << "\t.globl " << name << "\n"; - // FALL THROUGH + // Close the current section, if applicable. + if (TAI->getSectionEndDirectiveSuffix() && !CurrentSection.empty()) + O << CurrentSection << TAI->getSectionEndDirectiveSuffix() << '\n'; - case GlobalValue::InternalLinkage: - break; + CurrentSection = NS; - default: - assert(0 && "Unknown linkage type!"); - break; - } // end switch. + if (!CurrentSection.empty()){} + O << CurrentSection << (static_cast(TAI))-> + getUDataSectionStartSuffix() << '\n'; - EmitAlignment(Align, I); - O << name << ":\t\t\t\t" << TAI->getCommentString() << " " << I->getName() - << "\n"; + IsInTextSection = false; +} - // If the initializer is a extern weak symbol, remember to emit the weak - // reference! - if (const GlobalValue *GV = dyn_cast(C)) - if (GV->hasExternalWeakLinkage()) - ExtWeakSymbols.insert(GV); +/// The function is same as AsmPrinter::SwitchtoDataSection except the call +/// to getRomDataSectionStartSuffix. +void PIC16AsmPrinter::SwitchToRomDataSection(const char *NewSection, + const GlobalValue *GV) { + std::string NS; + if (GV && GV->hasSection()) + NS = TAI->getSwitchToSectionDirective() + GV->getSection(); + else + NS = NewSection; - EmitGlobalConstant(C); - O << '\n'; - } // end for. + // If we're already in this section, we're done. + if (CurrentSection == NS) return; - O << "\n "<< "END"; - return AsmPrinter::doFinalization(M); -} + // Close the current section, if applicable. + if (TAI->getSectionEndDirectiveSuffix() && !CurrentSection.empty()) + O << CurrentSection << TAI->getSectionEndDirectiveSuffix() << '\n'; -void PIC16AsmPrinter:: -SwitchToTextSection(const char *NewSection, const GlobalValue *GV) -{ - O << "\n"; - if (NewSection && *NewSection) { - std::string codeSection = "code_"; - codeSection += NewSection; - codeSection += " "; - codeSection += "CODE"; - AsmPrinter::SwitchToTextSection(codeSection.c_str(), GV); - } - else - AsmPrinter::SwitchToTextSection(NewSection, GV); -} + CurrentSection = NS; -void PIC16AsmPrinter:: -SwitchToDataSection(const char *NewSection, const GlobalValue *GV) -{ - // Need to append index for page. - O << "\n"; - if (NewSection && *NewSection) { - std::string dataSection = "udata_"; - dataSection += NewSection; - if (dataSection.substr(dataSection.length() - 2).compare(".o") == 0) { - dataSection = dataSection.substr(0, dataSection.length() - 2); - } - dataSection += " "; - dataSection += "UDATA"; - AsmPrinter::SwitchToDataSection(dataSection.c_str(), GV); - } - else - AsmPrinter::SwitchToDataSection(NewSection, GV); -} + if (!CurrentSection.empty()) {} + O << CurrentSection << (static_cast< const PIC16TargetAsmInfo *>(TAI))-> + getRomDataSectionStartSuffix() << '\n'; -void PIC16AsmPrinter:: -SwitchToDataOvrSection(const char *NewSection, const GlobalValue *GV) -{ - O << "\n"; - if (NewSection && *NewSection) { - std::string dataSection = "frame_"; - dataSection += NewSection; - if (dataSection.substr(dataSection.length() - 2).compare(".o") == 0) { - dataSection = dataSection.substr(0, dataSection.length() - 2); - } - dataSection += "_"; - dataSection += CurrentFnName; - dataSection += " "; - dataSection += "UDATA_OVR"; - AsmPrinter::SwitchToDataSection(dataSection.c_str(), GV); - } - else - AsmPrinter::SwitchToDataSection(NewSection, GV); + IsInTextSection = false; } + Removed: llvm/trunk/lib/Target/PIC16/PIC16CallingConv.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16CallingConv.td?rev=59616&view=auto ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16CallingConv.td (original) +++ llvm/trunk/lib/Target/PIC16/PIC16CallingConv.td (removed) @@ -1,16 +0,0 @@ -//===- PIC16CallingConv.td - Calling Conventions PIC16 -----*- tablegen -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This describes the calling conventions for the PIC16 architectures. -// -//===----------------------------------------------------------------------===// - -//===----------------------------------------------------------------------===// -// Return Value Calling Conventions -//===----------------------------------------------------------------------===// Removed: llvm/trunk/lib/Target/PIC16/PIC16ConstantPoolValue.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16ConstantPoolValue.cpp?rev=59616&view=auto ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16ConstantPoolValue.cpp (original) +++ llvm/trunk/lib/Target/PIC16/PIC16ConstantPoolValue.cpp (removed) @@ -1,89 +0,0 @@ -//===- PIC16ConstantPoolValue.cpp - PIC16 constantpool value --------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the PIC16 specific constantpool value class. -// -//===----------------------------------------------------------------------===// - -#include "PIC16ConstantPoolValue.h" -#include "llvm/ADT/FoldingSet.h" -#include "llvm/GlobalValue.h" -#include "llvm/Type.h" -#include "llvm/Support/raw_ostream.h" -using namespace llvm; - -PIC16ConstantPoolValue::PIC16ConstantPoolValue(GlobalValue *gv, unsigned id, - PIC16CP::PIC16CPKind k, - unsigned char PCAdj, - const char *Modif, bool AddCA) - : MachineConstantPoolValue((const Type*)gv->getType()), - GV(gv), S(NULL), LabelId(id), Kind(k), PCAdjust(PCAdj), - Modifier(Modif), AddCurrentAddress(AddCA) {} - -PIC16ConstantPoolValue::PIC16ConstantPoolValue(const char *s, unsigned id, - PIC16CP::PIC16CPKind k, - unsigned char PCAdj, - const char *Modif, bool AddCA) - : MachineConstantPoolValue((const Type*)Type::Int32Ty), - GV(NULL), S(s), LabelId(id), Kind(k), PCAdjust(PCAdj), - Modifier(Modif), AddCurrentAddress(AddCA) {} - -PIC16ConstantPoolValue::PIC16ConstantPoolValue(GlobalValue *gv, - PIC16CP::PIC16CPKind k, - const char *Modif) - : MachineConstantPoolValue((const Type*)Type::Int32Ty), - GV(gv), S(NULL), LabelId(0), Kind(k), PCAdjust(0), - Modifier(Modif) {} - -int PIC16ConstantPoolValue::getExistingMachineCPValue(MachineConstantPool *CP, - unsigned Alignment) { - unsigned AlignMask = (1 << Alignment)-1; - const std::vector Constants = CP->getConstants(); - for (unsigned i = 0, e = Constants.size(); i != e; ++i) { - if (Constants[i].isMachineConstantPoolEntry() && - (Constants[i].Offset & AlignMask) == 0) { - PIC16ConstantPoolValue *CPV = - (PIC16ConstantPoolValue *)Constants[i].Val.MachineCPVal; - if (CPV->GV == GV && - CPV->S == S && - CPV->LabelId == LabelId && - CPV->Kind == Kind && - CPV->PCAdjust == PCAdjust) - return i; - } - } - - return -1; -} - -void -PIC16ConstantPoolValue::AddSelectionDAGCSEId(FoldingSetNodeID &ID) { - ID.AddPointer(GV); - ID.AddPointer(S); - ID.AddInteger(LabelId); - ID.AddInteger((unsigned)Kind); - ID.AddInteger(PCAdjust); -} - -void PIC16ConstantPoolValue::print(raw_ostream &O) const { - if (GV) - O << GV->getName(); - else - O << S; - if (isNonLazyPointer()) O << "$non_lazy_ptr"; - else if (isStub()) O << "$stub"; - if (Modifier) O << "(" << Modifier << ")"; - if (PCAdjust != 0) { - O << "-(LPIC" << LabelId << "+" - << (unsigned)PCAdjust; - if (AddCurrentAddress) - O << "-."; - O << ")"; - } -} Removed: llvm/trunk/lib/Target/PIC16/PIC16ConstantPoolValue.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16ConstantPoolValue.h?rev=59616&view=auto ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16ConstantPoolValue.h (original) +++ llvm/trunk/lib/Target/PIC16/PIC16ConstantPoolValue.h (removed) @@ -1,77 +0,0 @@ -//===- PIC16ConstantPoolValue.h - PIC16 constantpool value ------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the PIC16 specific constantpool value class. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_TARGET_PIC16_CONSTANTPOOLVALUE_H -#define LLVM_TARGET_PIC16_CONSTANTPOOLVALUE_H - -#include "llvm/CodeGen/MachineConstantPool.h" - -namespace llvm { - -class GlobalValue; - -namespace PIC16CP { - enum PIC16CPKind { - CPValue, - CPNonLazyPtr, - CPStub - }; -} - -/// PIC16ConstantPoolValue - PIC16 specific constantpool value. This is used to -/// represent PC relative displacement between the address of the load -/// instruction and the global value being loaded, i.e. (&GV-(LPIC+8)). -class PIC16ConstantPoolValue : public MachineConstantPoolValue { - GlobalValue *GV; // GlobalValue being loaded. - const char *S; // ExtSymbol being loaded. - unsigned LabelId; // Label id of the load. - PIC16CP::PIC16CPKind Kind; // non_lazy_ptr or stub? - unsigned char PCAdjust; // Extra adjustment if constantpool is pc relative. - // 8 for PIC16 - const char *Modifier; // GV modifier i.e. (&GV(modifier)-(LPIC+8)) - bool AddCurrentAddress; - -public: - PIC16ConstantPoolValue(GlobalValue *gv, unsigned id, - PIC16CP::PIC16CPKind Kind = PIC16CP::CPValue, - unsigned char PCAdj = 0, const char *Modifier = NULL, - bool AddCurrentAddress = false); - PIC16ConstantPoolValue(const char *s, unsigned id, - PIC16CP::PIC16CPKind Kind = PIC16CP::CPValue, - unsigned char PCAdj = 0, const char *Modifier = NULL, - bool AddCurrentAddress = false); - PIC16ConstantPoolValue(GlobalValue *GV, PIC16CP::PIC16CPKind Kind, - const char *Modifier); - - - GlobalValue *getGV() const { return GV; } - const char *getSymbol() const { return S; } - const char *getModifier() const { return Modifier; } - bool hasModifier() const { return Modifier != NULL; } - bool mustAddCurrentAddress() const { return AddCurrentAddress; } - unsigned getLabelId() const { return LabelId; } - bool isNonLazyPointer() const { return Kind == PIC16CP::CPNonLazyPtr; } - bool isStub() const { return Kind == PIC16CP::CPStub; } - unsigned char getPCAdjustment() const { return PCAdjust; } - - virtual int getExistingMachineCPValue(MachineConstantPool *CP, - unsigned Alignment); - - virtual void AddSelectionDAGCSEId(FoldingSetNodeID &ID); - - virtual void print(raw_ostream &O) const; -}; - -} - -#endif Modified: llvm/trunk/lib/Target/PIC16/PIC16ISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16ISelDAGToDAG.cpp?rev=59617&r1=59616&r2=59617&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16ISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/PIC16/PIC16ISelDAGToDAG.cpp Wed Nov 19 05:00:54 2008 @@ -13,263 +13,47 @@ #define DEBUG_TYPE "pic16-isel" -#include "PIC16.h" -#include "PIC16ISelLowering.h" -#include "PIC16RegisterInfo.h" -#include "PIC16Subtarget.h" -#include "PIC16TargetMachine.h" -#include "llvm/GlobalValue.h" -#include "llvm/Instructions.h" -#include "llvm/Intrinsics.h" -#include "llvm/Type.h" -#include "llvm/CodeGen/MachineConstantPool.h" -#include "llvm/CodeGen/MachineFunction.h" -#include "llvm/CodeGen/MachineFrameInfo.h" -#include "llvm/CodeGen/MachineInstrBuilder.h" -#include "llvm/CodeGen/SelectionDAGISel.h" -#include "llvm/Support/CFG.h" -#include "llvm/Support/Compiler.h" +#include "PIC16ISelDAGToDAG.h" #include "llvm/Support/Debug.h" -#include "llvm/Target/TargetMachine.h" -using namespace llvm; - -//===----------------------------------------------------------------------===// -// Instruction Selector Implementation -//===----------------------------------------------------------------------===// - -//===----------------------------------------------------------------------===// -// PIC16DAGToDAGISel - PIC16 specific code to select PIC16 machine -// instructions for SelectionDAG operations. -//===----------------------------------------------------------------------===// -namespace { - -class VISIBILITY_HIDDEN PIC16DAGToDAGISel : public SelectionDAGISel { - - /// TM - Keep a reference to PIC16TargetMachine. - PIC16TargetMachine &TM; - -public: - explicit PIC16DAGToDAGISel(PIC16TargetMachine &tm) : - SelectionDAGISel(*tm.getTargetLowering()), - TM(tm) {} - - virtual void InstructionSelect(); - - // Pass Name - virtual const char *getPassName() const { - return "PIC16 DAG->DAG Pattern Instruction Selection"; - } - -private: - // Include the pieces autogenerated from the target description. -#include "PIC16GenDAGISel.inc" - - SDNode *Select(SDValue N); - - // Select addressing mode. currently assume base + offset addr mode. - bool SelectAM(SDValue Op, SDValue N, SDValue &Base, SDValue &Offset); - bool SelectDirectAM(SDValue Op, SDValue N, SDValue &Base, - SDValue &Offset); - bool StoreInDirectAM(SDValue Op, SDValue N, SDValue &fsr); - bool LoadFSR(SDValue Op, SDValue N, SDValue &Base, SDValue &Offset); - bool LoadNothing(SDValue Op, SDValue N, SDValue &Base, - SDValue &Offset); - - // getI8Imm - Return a target constant with the specified - // value, of type i8. - inline SDValue getI8Imm(unsigned Imm) { - return CurDAG->getTargetConstant(Imm, MVT::i8); - } - -#ifndef NDEBUG - unsigned Indent; -#endif -}; +using namespace llvm; +/// createPIC16ISelDag - This pass converts a legalized DAG into a +/// PIC16-specific DAG, ready for instruction scheduling. +FunctionPass *llvm::createPIC16ISelDag(PIC16TargetMachine &TM) { + return new PIC16DAGToDAGISel(TM); } + /// InstructionSelect - This callback is invoked by /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. -void PIC16DAGToDAGISel::InstructionSelect() -{ +void PIC16DAGToDAGISel::InstructionSelect() { DEBUG(BB->dump()); - // Codegen the basic block. - - DOUT << "===== Instruction selection begins:\n"; -#ifndef NDEBUG - Indent = 0; -#endif - - // Select target instructions for the DAG. SelectRoot(*CurDAG); - - DOUT << "===== Instruction selection ends:\n"; - CurDAG->RemoveDeadNodes(); } - -bool PIC16DAGToDAGISel:: -SelectDirectAM (SDValue Op, SDValue N, SDValue &Base, SDValue &Offset) -{ - GlobalAddressSDNode *GA; - ConstantSDNode *GC; - - // if Address is FI, get the TargetFrameIndex. - if (FrameIndexSDNode *FIN = dyn_cast(N)) { - DOUT << "--------- its frame Index\n"; - Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); - Offset = CurDAG->getTargetConstant(0, MVT::i32); - return true; - } - - if (N.getOpcode() == ISD::GlobalAddress) { - GA = dyn_cast(N); - Offset = CurDAG->getTargetConstant((unsigned char)GA->getOffset(), MVT::i8); - Base = CurDAG->getTargetGlobalAddress(GA->getGlobal(), MVT::i16, - GA->getOffset()); - return true; - } - - if (N.getOpcode() == ISD::ADD) { - GC = dyn_cast(N.getOperand(1)); - Offset = CurDAG->getTargetConstant((unsigned char)GC->getZExtValue(), - MVT::i8); - if ((GA = dyn_cast(N.getOperand(0)))) { - Base = CurDAG->getTargetGlobalAddress(GA->getGlobal(), MVT::i16, - GC->getZExtValue()); - return true; - } - else if (FrameIndexSDNode *FIN - = dyn_cast(N.getOperand(0))) { - Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); - return true; - } - } - - return false; -} - - -// FIXME: must also account for preinc/predec/postinc/postdec. -bool PIC16DAGToDAGISel:: -StoreInDirectAM (SDValue Op, SDValue N, SDValue &fsr) -{ - RegisterSDNode *Reg; - if (N.getOpcode() == ISD::LOAD) { - LoadSDNode *LD = dyn_cast(N); - if (LD) { - fsr = LD->getBasePtr(); - } - else if (isa(N.getNode())) { - //FIXME an attempt to retrieve the register number - //but does not work - DOUT << "this is a register\n"; - Reg = dyn_cast(N.getNode()); - fsr = CurDAG->getRegister(Reg->getReg(),MVT::i16); - } - else { - DOUT << "this is not a register\n"; - // FIXME must use whatever load is using - fsr = CurDAG->getRegister(1,MVT::i16); - } - return true; - } - return false; -} - -bool PIC16DAGToDAGISel:: -LoadFSR (SDValue Op, SDValue N, SDValue &Base, SDValue &Offset) -{ - GlobalAddressSDNode *GA; - - if (N.getOpcode() == ISD::GlobalAddress) { - GA = dyn_cast(N); - Offset = CurDAG->getTargetConstant((unsigned char)GA->getOffset(), MVT::i8); - Base = CurDAG->getTargetGlobalAddress(GA->getGlobal(), MVT::i16, - GA->getOffset()); - return true; - } - else if (N.getOpcode() == PIC16ISD::Package) { - CurDAG->setGraphColor(Op.getNode(), "blue"); - CurDAG->viewGraph(); - } - - return false; -} - -// LoadNothing - Don't thake this seriously, it will change. -bool PIC16DAGToDAGISel:: -LoadNothing (SDValue Op, SDValue N, SDValue &Base, SDValue &Offset) -{ - GlobalAddressSDNode *GA; - if (N.getOpcode() == ISD::GlobalAddress) { - GA = dyn_cast(N); - DOUT << "==========" << GA->getOffset() << "\n"; - Offset = CurDAG->getTargetConstant((unsigned char)GA->getOffset(), MVT::i8); - Base = CurDAG->getTargetGlobalAddress(GA->getGlobal(), MVT::i16, - GA->getOffset()); - return true; - } - - return false; -} - - /// Select - Select instructions not customized! Used for /// expanded, promoted and normal instructions. -SDNode* PIC16DAGToDAGISel::Select(SDValue N) -{ - SDNode *Node = N.getNode(); - unsigned Opcode = Node->getOpcode(); - - // Dump information about the Node being selected -#ifndef NDEBUG - DOUT << std::string(Indent, ' ') << "Selecting: "; - DEBUG(Node->dump(CurDAG)); - DOUT << "\n"; - Indent += 2; -#endif - - // If we have a custom node, we already have selected! - if (Node->isMachineOpcode()) { -#ifndef NDEBUG - DOUT << std::string(Indent-2, ' ') << "== "; - DEBUG(Node->dump(CurDAG)); - DOUT << "\n"; - Indent -= 2; -#endif - return NULL; - } - - /// - // FIXME: Instruction Selection not handled by custom or by the - // auto-generated tablegen selection should be handled here. - /// - switch(Opcode) { - default: break; - } +SDNode* PIC16DAGToDAGISel::Select(SDValue N) { // Select the default instruction. SDNode *ResNode = SelectCode(N); -#ifndef NDEBUG - DOUT << std::string(Indent-2, ' ') << "=> "; - if (ResNode == NULL || ResNode == N.getNode()) - DEBUG(N.getNode()->dump(CurDAG)); - else - DEBUG(ResNode->dump(CurDAG)); - DOUT << "\n"; - Indent -= 2; -#endif - return ResNode; } -/// createPIC16ISelDag - This pass converts a legalized DAG into a -/// PIC16-specific DAG, ready for instruction scheduling. -FunctionPass *llvm::createPIC16ISelDag(PIC16TargetMachine &TM) { - return new PIC16DAGToDAGISel(TM); -} +// SelectDirectAddr - Match a direct address for DAG. +// A direct address could be a globaladdress or externalsymbol. +bool PIC16DAGToDAGISel::SelectDirectAddr(SDValue Op, SDValue N, + SDValue &Address) { + // Return true if TGA or ES. + if (N.getOpcode() == ISD::TargetGlobalAddress + || N.getOpcode() == ISD::TargetExternalSymbol) { + Address = N; + return true; + } + + return false; +} Added: llvm/trunk/lib/Target/PIC16/PIC16ISelDAGToDAG.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16ISelDAGToDAG.h?rev=59617&view=auto ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16ISelDAGToDAG.h (added) +++ llvm/trunk/lib/Target/PIC16/PIC16ISelDAGToDAG.h Wed Nov 19 05:00:54 2008 @@ -0,0 +1,60 @@ +//===-- PIC16ISelDAGToDAG.cpp - A dag to dag inst selector for PIC16 ------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines an instruction selector for the PIC16 target. +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "pic16-isel" + +#include "PIC16.h" +#include "PIC16ISelLowering.h" +#include "PIC16RegisterInfo.h" +#include "PIC16TargetMachine.h" +#include "llvm/CodeGen/SelectionDAGISel.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Intrinsics.h" +using namespace llvm; + +namespace { + +class VISIBILITY_HIDDEN PIC16DAGToDAGISel : public SelectionDAGISel { + + /// TM - Keep a reference to PIC16TargetMachine. + PIC16TargetMachine &TM; + + /// PIC16Lowering - This object fully describes how to lower LLVM code to an + /// PIC16-specific SelectionDAG. + PIC16TargetLowering PIC16Lowering; + +public: + explicit PIC16DAGToDAGISel(PIC16TargetMachine &tm) : + SelectionDAGISel(PIC16Lowering), + TM(tm), PIC16Lowering(*TM.getTargetLowering()) {} + + // Pass Name + virtual const char *getPassName() const { + return "PIC16 DAG->DAG Pattern Instruction Selection"; + } + + virtual void InstructionSelect(); + +private: + // Include the pieces autogenerated from the target description. +#include "PIC16GenDAGISel.inc" + + SDNode *Select(SDValue N); + + // Match direct address complex pattern. + bool SelectDirectAddr(SDValue Op, SDValue N, SDValue &Address); + +}; + +} + Modified: llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp?rev=59617&r1=59616&r2=59617&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp Wed Nov 19 05:00:54 2008 @@ -17,751 +17,662 @@ #include "PIC16ISelLowering.h" #include "PIC16TargetMachine.h" #include "llvm/DerivedTypes.h" +#include "llvm/GlobalValue.h" #include "llvm/Function.h" -#include "llvm/Intrinsics.h" -#include "llvm/CallingConv.h" -#include "llvm/CodeGen/CallingConvLower.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" -#include "llvm/CodeGen/MachineInstrBuilder.h" -#include "llvm/CodeGen/MachineRegisterInfo.h" -#include "llvm/CodeGen/SelectionDAGISel.h" -#include "llvm/CodeGen/ValueTypes.h" -#include "llvm/Support/Debug.h" -using namespace llvm; -const char *PIC16TargetLowering:: getTargetNodeName(unsigned Opcode) const -{ - switch (Opcode) { - case PIC16ISD::Hi : return "PIC16ISD::Hi"; - case PIC16ISD::Lo : return "PIC16ISD::Lo"; - case PIC16ISD::Package : return "PIC16ISD::Package"; - case PIC16ISD::Wrapper : return "PIC16ISD::Wrapper"; - case PIC16ISD::SetBank : return "PIC16ISD::SetBank"; - case PIC16ISD::SetPage : return "PIC16ISD::SetPage"; - case PIC16ISD::Branch : return "PIC16ISD::Branch"; - case PIC16ISD::Cmp : return "PIC16ISD::Cmp"; - case PIC16ISD::BTFSS : return "PIC16ISD::BTFSS"; - case PIC16ISD::BTFSC : return "PIC16ISD::BTFSC"; - case PIC16ISD::XORCC : return "PIC16ISD::XORCC"; - case PIC16ISD::SUBCC : return "PIC16ISD::SUBCC"; - default : return NULL; - } -} - -PIC16TargetLowering:: -PIC16TargetLowering(PIC16TargetMachine &TM): TargetLowering(TM) -{ - // Set up the register classes. - addRegisterClass(MVT::i8, PIC16::CPURegsRegisterClass); - addRegisterClass(MVT::i16, PIC16::PTRRegsRegisterClass); - - // Load extented operations for i1 types must be promoted . - setLoadExtAction(ISD::EXTLOAD, MVT::i1, Promote); - setLoadExtAction(ISD::ZEXTLOAD, MVT::i1, Promote); - setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote); - - setOperationAction(ISD::ADD, MVT::i1, Promote); - setOperationAction(ISD::ADD, MVT::i8, Legal); - setOperationAction(ISD::ADD, MVT::i16, Custom); - setOperationAction(ISD::ADD, MVT::i32, Expand); - setOperationAction(ISD::ADD, MVT::i64, Expand); - - setOperationAction(ISD::SUB, MVT::i1, Promote); - setOperationAction(ISD::SUB, MVT::i8, Legal); - setOperationAction(ISD::SUB, MVT::i16, Custom); - setOperationAction(ISD::SUB, MVT::i32, Expand); - setOperationAction(ISD::SUB, MVT::i64, Expand); - - setOperationAction(ISD::ADDC, MVT::i1, Promote); - setOperationAction(ISD::ADDC, MVT::i8, Legal); - setOperationAction(ISD::ADDC, MVT::i16, Custom); - setOperationAction(ISD::ADDC, MVT::i32, Expand); - setOperationAction(ISD::ADDC, MVT::i64, Expand); - - setOperationAction(ISD::ADDE, MVT::i1, Promote); - setOperationAction(ISD::ADDE, MVT::i8, Legal); - setOperationAction(ISD::ADDE, MVT::i16, Custom); - setOperationAction(ISD::ADDE, MVT::i32, Expand); - setOperationAction(ISD::ADDE, MVT::i64, Expand); - - setOperationAction(ISD::SUBC, MVT::i1, Promote); - setOperationAction(ISD::SUBC, MVT::i8, Legal); - setOperationAction(ISD::SUBC, MVT::i16, Custom); - setOperationAction(ISD::SUBC, MVT::i32, Expand); - setOperationAction(ISD::SUBC, MVT::i64, Expand); - - setOperationAction(ISD::SUBE, MVT::i1, Promote); - setOperationAction(ISD::SUBE, MVT::i8, Legal); - setOperationAction(ISD::SUBE, MVT::i16, Custom); - setOperationAction(ISD::SUBE, MVT::i32, Expand); - setOperationAction(ISD::SUBE, MVT::i64, Expand); - - // PIC16 does not have these NodeTypes below. - setOperationAction(ISD::SETCC, MVT::i1, Expand); - setOperationAction(ISD::SETCC, MVT::i8, Expand); - setOperationAction(ISD::SETCC, MVT::Other, Expand); - setOperationAction(ISD::SELECT_CC, MVT::i1, Custom); - setOperationAction(ISD::SELECT_CC, MVT::i8, Custom); - - setOperationAction(ISD::BRCOND, MVT::i1, Expand); - setOperationAction(ISD::BRCOND, MVT::i8, Expand); - setOperationAction(ISD::BRCOND, MVT::Other, Expand); - setOperationAction(ISD::BR_CC, MVT::i1, Custom); - setOperationAction(ISD::BR_CC, MVT::i8, Custom); +using namespace llvm; - setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand); +// PIC16TargetLowering Constructor. +PIC16TargetLowering::PIC16TargetLowering(PIC16TargetMachine &TM) + : TargetLowering(TM) { - // FIXME: Do we really need to Custom lower the GA ?? - setOperationAction(ISD::GlobalAddress, MVT::i8, Custom); - setOperationAction(ISD::RET, MVT::Other, Custom); - - setOperationAction(ISD::CTPOP, MVT::i32, Expand); - setOperationAction(ISD::CTTZ, MVT::i32, Expand); - setOperationAction(ISD::CTLZ, MVT::i32, Expand); - setOperationAction(ISD::ROTL, MVT::i32, Expand); - setOperationAction(ISD::ROTR, MVT::i32, Expand); - setOperationAction(ISD::BSWAP, MVT::i32, Expand); - - setOperationAction(ISD::SHL_PARTS, MVT::i32, Expand); - setOperationAction(ISD::SRA_PARTS, MVT::i32, Expand); - setOperationAction(ISD::SRL_PARTS, MVT::i32, Expand); - - // We don't have line number support yet. - setOperationAction(ISD::DBG_STOPPOINT, MVT::Other, Expand); - setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand); - setOperationAction(ISD::DBG_LABEL, MVT::Other, Expand); - setOperationAction(ISD::EH_LABEL, MVT::Other, Expand); - - // Use the default for now. - setOperationAction(ISD::STACKSAVE, MVT::Other, Expand); - setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand); - - setOperationAction(ISD::LOAD, MVT::i1, Promote); - setOperationAction(ISD::LOAD, MVT::i8, Legal); - - setTargetDAGCombine(ISD::LOAD); - setTargetDAGCombine(ISD::STORE); - setTargetDAGCombine(ISD::ADDE); - setTargetDAGCombine(ISD::ADDC); - setTargetDAGCombine(ISD::ADD); - setTargetDAGCombine(ISD::SUBE); - setTargetDAGCombine(ISD::SUBC); - setTargetDAGCombine(ISD::SUB); + Subtarget = &TM.getSubtarget(); - setStackPointerRegisterToSaveRestore(PIC16::STKPTR); - computeRegisterProperties(); -} + addRegisterClass(MVT::i8, PIC16::GPRRegisterClass); + setShiftAmountType(MVT::i8); + setShiftAmountFlavor(Extend); -SDValue PIC16TargetLowering:: LowerOperation(SDValue Op, SelectionDAG &DAG) -{ - SDVTList VTList16 = DAG.getVTList(MVT::i16, MVT::i16, MVT::Other); - switch (Op.getOpcode()) { - case ISD::STORE: - DOUT << "reduce store\n"; - break; - case ISD::FORMAL_ARGUMENTS: - DOUT << "==== lowering formal args\n"; - return LowerFORMAL_ARGUMENTS(Op, DAG); + setOperationAction(ISD::GlobalAddress, MVT::i16, Custom); - case ISD::GlobalAddress: - DOUT << "==== lowering GA\n"; - return LowerGlobalAddress(Op, DAG); - - case ISD::RET: - DOUT << "==== lowering ret\n"; - return LowerRET(Op, DAG); - - case ISD::FrameIndex: - DOUT << "==== lowering frame index\n"; - return LowerFrameIndex(Op, DAG); - - case ISD::ADDE: - DOUT << "==== lowering adde\n"; - break; + setOperationAction(ISD::LOAD, MVT::i8, Legal); + setOperationAction(ISD::LOAD, MVT::i16, Custom); + setOperationAction(ISD::LOAD, MVT::i32, Custom); - case ISD::LOAD: - case ISD::ADD: - break; + setOperationAction(ISD::STORE, MVT::i8, Legal); + setOperationAction(ISD::STORE, MVT::i16, Custom); + setOperationAction(ISD::STORE, MVT::i32, Custom); - case ISD::BR_CC: - DOUT << "==== lowering BR_CC\n"; - return LowerBR_CC(Op, DAG); - } // end switch. - return SDValue(); -} + setOperationAction(ISD::ADDE, MVT::i8, Custom); + setOperationAction(ISD::ADDC, MVT::i8, Custom); + setOperationAction(ISD::SUBE, MVT::i8, Custom); + setOperationAction(ISD::SUBC, MVT::i8, Custom); + setOperationAction(ISD::ADD, MVT::i8, Legal); + setOperationAction(ISD::ADD, MVT::i16, Custom); + setOperationAction(ISD::SHL, MVT::i16, Custom); + setOperationAction(ISD::SHL, MVT::i32, Custom); -//===----------------------------------------------------------------------===// -// Lower helper functions -//===----------------------------------------------------------------------===// - -SDValue PIC16TargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) -{ - MVT VT = Op.getValueType(); - SDValue Chain = Op.getOperand(0); - ISD::CondCode CC = cast(Op.getOperand(1))->get(); - SDValue LHS = Op.getOperand(2); - SDValue RHS = Op.getOperand(3); - SDValue JumpVal = Op.getOperand(4); - SDValue Result; - unsigned cmpOpcode; - unsigned branchOpcode; - SDValue branchOperand; - - SDValue StatusReg = DAG.getRegister(PIC16::STATUSREG, MVT::i8); - SDValue CPUReg = DAG.getRegister(PIC16::WREG, MVT::i8); - switch(CC) { - default: - assert(0 && "This condition code is not handled yet!!"); - abort(); + //setOperationAction(ISD::TRUNCATE, MVT::i16, Custom); + setTruncStoreAction(MVT::i16, MVT::i8, Custom); - case ISD::SETNE: - DOUT << "setne\n"; - cmpOpcode = PIC16ISD::XORCC; - branchOpcode = PIC16ISD::BTFSS; - branchOperand = DAG.getConstant(2, MVT::i8); - break; - - case ISD::SETEQ: - DOUT << "seteq\n"; - cmpOpcode = PIC16ISD::XORCC; - branchOpcode = PIC16ISD::BTFSC; - branchOperand = DAG.getConstant(2, MVT::i8); - break; - - case ISD::SETGT: - assert(0 && "Greater Than condition code is not handled yet!!"); - abort(); - break; - - case ISD::SETGE: - DOUT << "setge\n"; - cmpOpcode = PIC16ISD::SUBCC; - branchOpcode = PIC16ISD::BTFSS; - branchOperand = DAG.getConstant(1, MVT::i8); - break; - - case ISD::SETLT: - DOUT << "setlt\n"; - cmpOpcode = PIC16ISD::SUBCC; - branchOpcode = PIC16ISD::BTFSC; - branchOperand = DAG.getConstant(1,MVT::i8); - break; - - case ISD::SETLE: - assert(0 && "Less Than Equal condition code is not handled yet!!"); - abort(); - break; - } // End of Switch - - SDVTList VTList = DAG.getVTList(MVT::i8, MVT::Flag); - SDValue CmpValue = DAG.getNode(cmpOpcode, VTList, LHS, RHS).getValue(1); - Result = DAG.getNode(branchOpcode, VT, Chain, JumpVal, branchOperand, - StatusReg, CmpValue); - return Result; -} - - -//===----------------------------------------------------------------------===// -// Misc Lower Operation implementation -//===----------------------------------------------------------------------===// - -// LowerGlobalAddress - Create a constant pool entry for global value -// and wrap it in a wrapper node. -SDValue -PIC16TargetLowering::LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) -{ - MVT PtrVT = getPointerTy(); - GlobalAddressSDNode *GSDN = cast(Op); - GlobalValue *GV = GSDN->getGlobal(); - - // FIXME: for now only do the ram. - SDValue CPAddr = DAG.getTargetConstantPool(GV, PtrVT, 2); - SDValue CPBank = DAG.getNode(PIC16ISD::SetBank, MVT::i8, CPAddr); - CPAddr = DAG.getNode(PIC16ISD::Wrapper, MVT::i8, CPAddr,CPBank); - - return CPAddr; -} - -SDValue -PIC16TargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG) -{ - switch(Op.getNumOperands()) { - default: - assert(0 && "Do not know how to return this many arguments!"); - abort(); + // Now deduce the information based on the above mentioned + // actions + computeRegisterProperties(); +} - case 1: - return SDValue(); // ret void is legal +const char *PIC16TargetLowering::getTargetNodeName(unsigned Opcode) const { + switch (Opcode) { + default: return NULL; + case PIC16ISD::Lo: return "PIC16ISD::Lo"; + case PIC16ISD::Hi: return "PIC16ISD::Hi"; + case PIC16ISD::MTLO: return "PIC16ISD::MTLO"; + case PIC16ISD::MTHI: return "PIC16ISD::MTHI"; + case PIC16ISD::Banksel: return "PIC16ISD::Banksel"; + case PIC16ISD::PIC16Load: return "PIC16ISD::PIC16Load"; + case PIC16ISD::PIC16Store: return "PIC16ISD::PIC16Store"; + case PIC16ISD::BCF: return "PIC16ISD::BCF"; + case PIC16ISD::LSLF: return "PIC16ISD::LSLF"; + case PIC16ISD::LRLF: return "PIC16ISD::LRLF"; + case PIC16ISD::RLF: return "PIC16ISD::RLF"; + case PIC16ISD::RRF: return "PIC16ISD::RRF"; + case PIC16ISD::Dummy: return "PIC16ISD::Dummy"; } } -SDValue -PIC16TargetLowering::LowerFrameIndex(SDValue N, SelectionDAG &DAG) -{ - if (FrameIndexSDNode *FIN = dyn_cast(N)) { - return DAG.getTargetFrameIndex(FIN->getIndex(), MVT::i32); - } - - return N; -} - -SDValue -PIC16TargetLowering::LowerLOAD(SDNode *N, - SelectionDAG &DAG, - DAGCombinerInfo &DCI) const -{ - SDValue Outs[2]; - SDValue TF; //TokenFactor - SDValue OutChains[2]; - SDValue Chain = N->getOperand(0); - SDValue Src = N->getOperand(1); - SDValue retVal; - SDVTList VTList; - - // If this load is directly stored, replace the load value with the stored - // value. - // FIXME: Handle store large -> read small portion. - // FIXME: Handle TRUNCSTORE/LOADEXT - LoadSDNode *LD = cast(N); - SDValue Ptr = LD->getBasePtr(); - if (LD->getExtensionType() == ISD::NON_EXTLOAD) { - if (ISD::isNON_TRUNCStore(Chain.getNode())) { - StoreSDNode *PrevST = cast(Chain); - if (PrevST->getBasePtr() == Ptr && - PrevST->getValue().getValueType() == N->getValueType(0)) - return DCI.CombineTo(N, Chain.getOperand(1), Chain); +SDNode *PIC16TargetLowering::ReplaceNodeResults(SDNode *N, SelectionDAG &DAG) { + switch (N->getOpcode()) { + case ISD::GlobalAddress: + return ExpandGlobalAddress(N, DAG); + case ISD::STORE: + return ExpandStore(N, DAG); + case ISD::LOAD: + return ExpandLoad(N, DAG); + case ISD::ADD: + return ExpandAdd(N, DAG); + case ISD::SHL: + return ExpandShift(N, DAG); + default: + assert (0 && "not implemented"); + } +} + +SDNode *PIC16TargetLowering::ExpandStore(SDNode *N, SelectionDAG &DAG) { + StoreSDNode *St = cast(N); + SDValue Chain = St->getChain(); + SDValue Src = St->getValue(); + SDValue Ptr = St->getBasePtr(); + MVT ValueType = Src.getValueType(); + unsigned StoreOffset = 0; + + SDValue PtrLo, PtrHi; + LegalizeAddress(Ptr, DAG, PtrLo, PtrHi, StoreOffset); + + if (ValueType == MVT::i8) { + SDValue Store = DAG.getNode (PIC16ISD::PIC16Store, MVT::Other, Chain, Src, + PtrLo, PtrHi, DAG.getConstant (0, MVT::i8)); + return Store.getNode(); + } + else if (ValueType == MVT::i16) { + // Get the Lo and Hi parts from MERGE_VALUE or BUILD_PAIR. + SDValue SrcLo, SrcHi; + GetExpandedParts(Src, DAG, SrcLo, SrcHi); + SDValue ChainLo = Chain, ChainHi = Chain; + if (Chain.getOpcode() == ISD::TokenFactor) { + ChainLo = Chain.getOperand(0); + ChainHi = Chain.getOperand(1); } + SDValue Store1 = DAG.getNode(PIC16ISD::PIC16Store, MVT::Other, + ChainLo, + SrcLo, PtrLo, PtrHi, + DAG.getConstant (0 + StoreOffset, MVT::i8)); + + SDValue Store2 = DAG.getNode(PIC16ISD::PIC16Store, MVT::Other, ChainHi, + SrcHi, PtrLo, PtrHi, + DAG.getConstant (1 + StoreOffset, MVT::i8)); + + return DAG.getNode(ISD::TokenFactor, MVT::Other, getChain(Store1), + getChain(Store2)).getNode(); } + else if (ValueType == MVT::i32) { + // Get the Lo and Hi parts from MERGE_VALUE or BUILD_PAIR. + SDValue SrcLo, SrcHi; + GetExpandedParts(Src, DAG, SrcLo, SrcHi); + + // Get the expanded parts of each of SrcLo and SrcHi. + SDValue SrcLo1, SrcLo2, SrcHi1, SrcHi2; + GetExpandedParts(SrcLo, DAG, SrcLo1, SrcLo2); + GetExpandedParts(SrcHi, DAG, SrcHi1, SrcHi2); + + SDValue ChainLo = Chain, ChainHi = Chain; + if (Chain.getOpcode() == ISD::TokenFactor) { + ChainLo = Chain.getOperand(0); + ChainHi = Chain.getOperand(1); + } + SDValue ChainLo1 = ChainLo, ChainLo2 = ChainLo, ChainHi1 = ChainHi, + ChainHi2 = ChainHi; + if (ChainLo.getOpcode() == ISD::TokenFactor) { + ChainLo1 = ChainLo.getOperand(0); + ChainLo2 = ChainLo.getOperand(1); + } + if (ChainHi.getOpcode() == ISD::TokenFactor) { + ChainHi1 = ChainHi.getOperand(0); + ChainHi2 = ChainHi.getOperand(1); + } + SDValue Store1 = DAG.getNode(PIC16ISD::PIC16Store, MVT::Other, + ChainLo1, + SrcLo1, PtrLo, PtrHi, + DAG.getConstant (0 + StoreOffset, MVT::i8)); + + SDValue Store2 = DAG.getNode(PIC16ISD::PIC16Store, MVT::Other, ChainLo2, + SrcLo2, PtrLo, PtrHi, + DAG.getConstant (1 + StoreOffset, MVT::i8)); + + SDValue Store3 = DAG.getNode(PIC16ISD::PIC16Store, MVT::Other, ChainHi1, + SrcHi1, PtrLo, PtrHi, + DAG.getConstant (2 + StoreOffset, MVT::i8)); + + SDValue Store4 = DAG.getNode(PIC16ISD::PIC16Store, MVT::Other, ChainHi2, + SrcHi2, PtrLo, PtrHi, + DAG.getConstant (3 + StoreOffset, MVT::i8)); + + SDValue RetLo = DAG.getNode(ISD::TokenFactor, MVT::Other, getChain(Store1), + getChain(Store2)); + SDValue RetHi = DAG.getNode(ISD::TokenFactor, MVT::Other, getChain(Store3), + getChain(Store4)); + return DAG.getNode(ISD::TokenFactor, MVT::Other, RetLo, RetHi).getNode(); - if (N->getValueType(0) != MVT::i16) - return SDValue(); + } + else { + assert (0 && "value type not supported"); + } +} - SDValue toWorklist; - Outs[0] = DAG.getLoad(MVT::i8, Chain, Src, NULL, 0); - toWorklist = DAG.getNode(ISD::ADD, MVT::i16, Src, - DAG.getConstant(1, MVT::i16)); - Outs[1] = DAG.getLoad(MVT::i8, Chain, toWorklist, NULL, 0); - // FIXME: Add to worklist may not be needed. - // It is meant to merge sequences of add with constant into one. - DCI.AddToWorklist(toWorklist.getNode()); +// ExpandGlobalAddress - +SDNode *PIC16TargetLowering::ExpandGlobalAddress(SDNode *N, SelectionDAG &DAG) { + GlobalAddressSDNode *G = dyn_cast(SDValue(N, 0)); - // Create the tokenfactors and carry it on to the build_pair node - OutChains[0] = Outs[0].getValue(1); - OutChains[1] = Outs[1].getValue(1); - TF = DAG.getNode(ISD::TokenFactor, MVT::Other, &OutChains[0], 2); - - VTList = DAG.getVTList(MVT::i16, MVT::Flag); - retVal = DAG.getNode (PIC16ISD::Package, VTList, &Outs[0], 2); + SDValue TGA = DAG.getTargetGlobalAddress(G->getGlobal(), MVT::i8, + G->getOffset()); - DCI.CombineTo (N, retVal, TF); + SDValue Lo = DAG.getNode(PIC16ISD::Lo, MVT::i8, TGA); + SDValue Hi = DAG.getNode(PIC16ISD::Hi, MVT::i8, TGA); - return retVal; + SDValue BP = DAG.getNode(ISD::BUILD_PAIR, MVT::i16, Lo, Hi); + return BP.getNode(); } -SDValue -PIC16TargetLowering::LowerADDSUB(SDNode *N, SelectionDAG &DAG, - DAGCombinerInfo &DCI) const -{ - bool changed = false; - int i; - SDValue LoOps[3], HiOps[3]; - SDValue OutOps[3]; // [0]:left, [1]:right, [2]:carry - SDValue InOp[2]; - SDValue retVal; - SDValue as1,as2; - SDVTList VTList; - unsigned AS = 0, ASE = 0, ASC=0; +bool PIC16TargetLowering::isDirectAddress(const SDValue &Op) { + assert (Op.getNode() != NULL && "Can't operate on NULL SDNode!!"); - InOp[0] = N->getOperand(0); - InOp[1] = N->getOperand(1); + if (Op.getOpcode() == ISD::BUILD_PAIR) { + if (Op.getOperand(0).getOpcode() == PIC16ISD::Lo) + return true; + } + return false; +} - switch (N->getOpcode()) { - case ISD::ADD: - if (InOp[0].getOpcode() == ISD::Constant && - InOp[1].getOpcode() == ISD::Constant) { - ConstantSDNode *CST0 = dyn_cast(InOp[0]); - ConstantSDNode *CST1 = dyn_cast(InOp[1]); - return DAG.getConstant(CST0->getZExtValue() + CST1->getZExtValue(), - MVT::i16); - } - break; +// Return true if DirectAddress is in ROM_SPACE +bool PIC16TargetLowering::isRomAddress(const SDValue &Op) { - case ISD::ADDE: - case ISD::ADDC: - AS = ISD::ADD; - ASE = ISD::ADDE; - ASC = ISD::ADDC; - break; - - case ISD::SUB: - if (InOp[0].getOpcode() == ISD::Constant && - InOp[1].getOpcode() == ISD::Constant) { - ConstantSDNode *CST0 = dyn_cast(InOp[0]); - ConstantSDNode *CST1 = dyn_cast(InOp[1]); - return DAG.getConstant(CST0->getZExtValue() - CST1->getZExtValue(), - MVT::i16); - } - break; + // RomAddress is a GlobalAddress in ROM_SPACE_ + // If the Op is not a GlobalAddress return NULL without checking + // anything further. + if (!isDirectAddress(Op)) + return false; + + // Its a GlobalAddress. + // It is BUILD_PAIR((PIC16Lo TGA), (PIC16Hi TGA)) and Op is BUILD_PAIR + SDValue TGA = Op.getOperand(0).getOperand(0); + GlobalAddressSDNode *GSDN = dyn_cast(TGA); + const Type *ValueType = GSDN->getGlobal()->getType(); - case ISD::SUBE: - case ISD::SUBC: - AS = ISD::SUB; - ASE = ISD::SUBE; - ASC = ISD::SUBC; - break; - } // end switch. - - assert ((N->getValueType(0) == MVT::i16) - && "expecting an MVT::i16 node for lowering"); - assert ((N->getOperand(0).getValueType() == MVT::i16) - && (N->getOperand(1).getValueType() == MVT::i16) - && "both inputs to addx/subx:i16 must be i16"); - - for (i = 0; i < 2; i++) { - if (InOp[i].getOpcode() == ISD::GlobalAddress) { - // We don't want to lower subs/adds with global address yet. - return SDValue(); - } - else if (InOp[i].getOpcode() == ISD::Constant) { - changed = true; - ConstantSDNode *CST = dyn_cast(InOp[i]); - LoOps[i] = DAG.getConstant(CST->getZExtValue() & 0xFF, MVT::i8); - HiOps[i] = DAG.getConstant(CST->getZExtValue() >> 8, MVT::i8); - } - else if (InOp[i].getOpcode() == PIC16ISD::Package) { - LoOps[i] = InOp[i].getOperand(0); - HiOps[i] = InOp[i].getOperand(1); - } - else if (InOp[i].getOpcode() == ISD::LOAD) { - changed = true; - // LowerLOAD returns a Package node or it may combine and return - // anything else. - SDValue lowered = LowerLOAD(InOp[i].getNode(), DAG, DCI); - - // So If LowerLOAD returns something other than Package, - // then just call ADD again. - if (lowered.getOpcode() != PIC16ISD::Package) - return LowerADDSUB(N, DAG, DCI); - - LoOps[i] = lowered.getOperand(0); - HiOps[i] = lowered.getOperand(1); - } - else if ((InOp[i].getOpcode() == ISD::ADD) || - (InOp[i].getOpcode() == ISD::ADDE) || - (InOp[i].getOpcode() == ISD::ADDC) || - (InOp[i].getOpcode() == ISD::SUB) || - (InOp[i].getOpcode() == ISD::SUBE) || - (InOp[i].getOpcode() == ISD::SUBC)) { - changed = true; - // Must call LowerADDSUB recursively here, - // LowerADDSUB returns a Package node. - SDValue lowered = LowerADDSUB(InOp[i].getNode(), DAG, DCI); + if (!isa(ValueType)) { + assert(0 && "TGA must be of a PointerType"); + } - LoOps[i] = lowered.getOperand(0); - HiOps[i] = lowered.getOperand(1); - } - else if (InOp[i].getOpcode() == ISD::SIGN_EXTEND) { - // FIXME: I am just zero extending. for now. - changed = true; - LoOps[i] = InOp[i].getOperand(0); - HiOps[i] = DAG.getConstant(0, MVT::i8); - } - else { - DAG.setGraphColor(N, "blue"); - DAG.viewGraph(); - assert (0 && "not implemented yet"); - } - } // end for. + int AddrSpace = dyn_cast(ValueType)->getAddressSpace(); + if (AddrSpace == PIC16ISD::ROM_SPACE) + return true; + + // Any other address space return it false + return false; +} + +// To extract chain value from the SDValue Nodes +// This function will help to maintain the chain extracting +// code at one place. In case of any change in future it will +// help maintain the code. +SDValue PIC16TargetLowering::getChain(SDValue &Op) { + SDValue Chain = Op.getValue(Op.getNode()->getNumValues() - 1); + + // All nodes may not produce a chain. Therefore following assert + // verifies that the node is returning a chain only. + assert (Chain.getValueType() == MVT::Other && "Node does not have a chain"); + + return Chain; +} + +void PIC16TargetLowering::GetExpandedParts(SDValue Op, SelectionDAG &DAG, + SDValue &Lo, SDValue &Hi) { + SDNode *N = Op.getNode(); + unsigned NumValues = N->getNumValues(); + std::vector VTs; + MVT NewVT; + std::vector Opers; + + // EXTRACT_ELEMENT should have same number and type of values that the + // node replacing the EXTRACT_ELEMENT should have. (i.e. extracted element) + // Some nodes such as LOAD and PIC16Load have more than one values. In such + // cases EXTRACT_ELEMENT should have more than one values. Therefore creating + // vector of Values for EXTRACT_ELEMENT. This list will have same number of + // values as the extracted element will have. + + for (unsigned i=0;i < NumValues; ++i) { + NewVT = getTypeToTransformTo(N->getValueType(i)); + VTs.push_back(NewVT); + } - assert (changed && "nothing changed while lowering SUBx/ADDx"); + // extract the lo component + Opers.push_back(Op); + Opers.push_back(DAG.getConstant(0,MVT::i8)); + Lo = DAG.getNode(ISD::EXTRACT_ELEMENT,VTs,&Opers[0],Opers.size()); + + // extract the hi component + Opers.clear(); + Opers.push_back(Op); + Opers.push_back(DAG.getConstant(1,MVT::i8)); + Hi = DAG.getNode(ISD::EXTRACT_ELEMENT,VTs,&Opers[0],Opers.size()); +} + +// This function legalizes the PIC16 Addresses. If the Pointer is +// -- Direct address variable residing +// --> then a Banksel for that variable will be created. +// -- Rom variable +// --> then it will be treated as an indirect address. +// -- Indirect address +// --> then the address will be loaded into FSR +// -- ADD with constant operand +// --> then constant operand of ADD will be returned as Offset +// and non-constant operand of ADD will be treated as pointer. +// Returns the high and lo part of the address, and the offset(in case of ADD). + +void PIC16TargetLowering:: LegalizeAddress(SDValue Ptr, SelectionDAG &DAG, + SDValue &Lo, SDValue &Hi, + unsigned &Offset) { + + // Offset, by default, should be 0 + Offset = 0; + + // If the pointer is ADD with constant, + // return the constant value as the offset + if (Ptr.getOpcode() == ISD::ADD) { + SDValue OperLeft = Ptr.getOperand(0); + SDValue OperRight = Ptr.getOperand(1); + if (OperLeft.getOpcode() == ISD::Constant) { + Offset = dyn_cast(OperLeft)->getZExtValue(); + Ptr = OperRight; + } else { + Ptr = OperLeft; + Offset = dyn_cast(OperRight)->getZExtValue(); + } + } - VTList = DAG.getVTList(MVT::i8, MVT::Flag); - if (N->getOpcode() == ASE) { - // We must take in the existing carry - // if this node is part of an existing subx/addx sequence. - LoOps[2] = N->getOperand(2).getValue(1); - as1 = DAG.getNode (ASE, VTList, LoOps, 3); + if (isDirectAddress(Ptr) && !isRomAddress(Ptr)) { + // Direct addressing case for RAM variables. The Hi part is constant + // and the Lo part is the TGA itself. + Lo = Ptr.getOperand(0).getOperand(0); + + // For direct addresses Hi is a constant. Value 1 for the constant + // signifies that banksel needs to generated for it. Value 0 for + // the constant signifies that banksel does not need to be generated + // for it. Mark it as 1 now and optimize later. + Hi = DAG.getConstant(1, MVT::i8); + return; } - else { - as1 = DAG.getNode (ASC, VTList, LoOps, 2); + + // Indirect addresses. Get the hi and lo parts of ptr. + GetExpandedParts(Ptr, DAG, Lo, Hi); + + // Put the hi and lo parts into FSR. + Lo = DAG.getNode(PIC16ISD::MTLO, MVT::i8, Lo); + Hi = DAG.getNode(PIC16ISD::MTHI, MVT::i8, Hi); + + return; +} + +SDNode *PIC16TargetLowering::ExpandAdd(SDNode *N, SelectionDAG &DAG) { + SDValue OperLeft = N->getOperand(0); + SDValue OperRight = N->getOperand(1); + + if((OperLeft.getOpcode() == ISD::Constant) || + (OperRight.getOpcode() == ISD::Constant)) { + return NULL; } - HiOps[2] = as1.getValue(1); - as2 = DAG.getNode (ASE, VTList, HiOps, 3); - // We must build a pair that also provides the carry from sube/adde. - OutOps[0] = as1; - OutOps[1] = as2; - OutOps[2] = as2.getValue(1); - // Breaking an original i16, so lets make the Package also an i16. - if (N->getOpcode() == ASE) { - VTList = DAG.getVTList(MVT::i16, MVT::Flag); - retVal = DAG.getNode (PIC16ISD::Package, VTList, OutOps, 3); - DCI.CombineTo (N, retVal, OutOps[2]); + + // These case are yet to be handled + return NULL; +} + +SDNode *PIC16TargetLowering::ExpandLoad(SDNode *N, SelectionDAG &DAG) { + LoadSDNode *LD = dyn_cast(SDValue(N, 0)); + SDValue Chain = LD->getChain(); + SDValue Ptr = LD->getBasePtr(); + + SDValue Load, Offset; + SDVTList Tys; + MVT VT, NewVT; + SDValue PtrLo, PtrHi; + unsigned LoadOffset; + + // Legalize direct/indirect addresses. This will give the lo and hi parts + // of the address and the offset. + LegalizeAddress(Ptr, DAG, PtrLo, PtrHi, LoadOffset); + + // Load from the pointer (direct address or FSR) + VT = N->getValueType(0); + unsigned NumLoads = VT.getSizeInBits() / 8; + std::vector PICLoads; + unsigned iter; + MVT MemVT = LD->getMemoryVT(); + if(ISD::isNON_EXTLoad(N)) { + for (iter=0; itergetMemoryVT(); + unsigned MemBytes = MemVT.getSizeInBits() / 8; + unsigned ExtdBytes = VT.getSizeInBits() / 8; + Offset = DAG.getConstant(LoadOffset, MVT::i8); + + Tys = DAG.getVTList(MVT::i8, MVT::Other); + // For MemBytes generate PIC16Load with proper offset + for (iter=0; itergetOpcode() == ASC) { - VTList = DAG.getVTList(MVT::i16, MVT::Flag); - retVal = DAG.getNode (PIC16ISD::Package, VTList, OutOps, 2); - DCI.CombineTo (N, retVal, OutOps[2]); + SDValue BP; + + if (VT == MVT::i8) { + // Operand of Load is illegal -- Load itself is legal + return PICLoads[0].getNode(); } - else if (N->getOpcode() == AS) { - VTList = DAG.getVTList(MVT::i16); - retVal = DAG.getNode (PIC16ISD::Package, VTList, OutOps, 2); - DCI.CombineTo (N, retVal); + else if (VT == MVT::i16) { + BP = DAG.getNode(ISD::BUILD_PAIR, VT, PICLoads[0], PICLoads[1]); + if (MemVT == MVT::i8) + Chain = getChain(PICLoads[0]); + else + Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, getChain(PICLoads[0]), + getChain(PICLoads[1])); + } else if (VT == MVT::i32) { + SDValue BPs[2]; + BPs[0] = DAG.getNode(ISD::BUILD_PAIR, MVT::i16, PICLoads[0], PICLoads[1]); + BPs[1] = DAG.getNode(ISD::BUILD_PAIR, MVT::i16, PICLoads[2], PICLoads[3]); + BP = DAG.getNode(ISD::BUILD_PAIR, VT, BPs[0], BPs[1]); + if (MemVT == MVT::i8) + Chain = getChain(PICLoads[0]); + else if (MemVT == MVT::i16) + Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, getChain(PICLoads[0]), + getChain(PICLoads[1])); + else { + SDValue Chains[2]; + Chains[0] = DAG.getNode(ISD::TokenFactor, MVT::Other, + getChain(PICLoads[0]), getChain(PICLoads[1])); + Chains[1] = DAG.getNode(ISD::TokenFactor, MVT::Other, + getChain(PICLoads[2]), getChain(PICLoads[3])); + Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, Chains[0], Chains[1]); + } } + Tys = DAG.getVTList(VT, MVT::Other); + SDValue MergeV = DAG.getNode(ISD::MERGE_VALUES, Tys, BP, Chain); + return MergeV.getNode(); - return retVal; } +SDNode *PIC16TargetLowering::ExpandShift(SDNode *N, SelectionDAG &DAG) { + SDValue Value = N->getOperand(0); + SDValue Amt = N->getOperand(1); + SDValue BCF, BCFInput; + SDVTList Tys; + SDValue ShfCom; // Shift Component - Lo component should be shifted + SDValue RotCom; // Rotate Component- Hi component should be rotated + PIC16ISD::NodeType ShfNode, RotNode; + + // Currently handling Constant shift only + if (Amt.getOpcode() != ISD::Constant) + return NULL; -//===----------------------------------------------------------------------===// -// Calling Convention Implementation -//===----------------------------------------------------------------------===// + // Following code considers 16 bit left-shift only + if (N->getValueType(0) != MVT::i16) + return NULL; -#include "PIC16GenCallingConv.inc" + if (N->getOpcode() == ISD::SHL) { + ShfNode = PIC16ISD::LSLF; + RotNode = PIC16ISD::RLF; + } else if (N->getOpcode() == ISD::SRL) { + ShfNode = PIC16ISD::LRLF; + RotNode = PIC16ISD::RRF; + } + unsigned ShiftAmt = dyn_cast(Amt)->getZExtValue(); + SDValue StatusReg = DAG.getRegister(PIC16::STATUS, MVT::i8); + // 0th Bit in StatusReg is CarryBit + SDValue CarryBit= DAG.getConstant(0, MVT::i8); + + GetExpandedParts(Value, DAG, ShfCom, RotCom); + BCFInput = DAG.getNode(PIC16ISD::Dummy, MVT::Flag); + Tys = DAG.getVTList(MVT::i8, MVT::Flag); + + for (unsigned i=0;igetValueType(0), ShfCom, RotCom); + return BP.getNode(); +} -//===----------------------------------------------------------------------===// -// FORMAL_ARGUMENTS Calling Convention Implementation -//===----------------------------------------------------------------------===// -SDValue PIC16TargetLowering:: -LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG) -{ - SmallVector ArgValues; - SDValue Root = Op.getOperand(0); +SDValue PIC16TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { + switch (Op.getOpcode()) { + case ISD::FORMAL_ARGUMENTS: + return LowerFORMAL_ARGUMENTS(Op, DAG); + case ISD::ADDC: + return LowerADDC(Op, DAG); + case ISD::ADDE: + return LowerADDE(Op, DAG); + case ISD::SUBE: + return LowerSUBE(Op, DAG); + case ISD::SUBC: + return LowerSUBC(Op, DAG); + case ISD::LOAD: + return SDValue(ExpandLoad(Op.getNode(), DAG), Op.getResNo()); + case ISD::STORE: + return SDValue(ExpandStore(Op.getNode(), DAG), Op.getResNo()); + case ISD::SHL: + return SDValue(ExpandShift(Op.getNode(), DAG), Op.getResNo()); + } + return SDValue(); +} + +SDValue PIC16TargetLowering::ConvertToMemOperand(SDValue Op, + SelectionDAG &DAG) { + + assert (Op.getValueType() == MVT::i8 + && "illegal value type to store on stack."); - // Return the new list of results. - // FIXME: Just copy right now. - ArgValues.push_back(Root); + MachineFunction &MF = DAG.getMachineFunction(); + const Function *Func = MF.getFunction(); + const std::string FuncName = Func->getName(); + + char *tmpName = new char [strlen(FuncName.c_str()) + 6]; + + // Put the value on stack. + // Get a stack slot index and convert to es. + int FI = MF.getFrameInfo()->CreateStackObject(1, 1); + sprintf(tmpName, "%s.tmp", FuncName.c_str()); + SDValue ES = DAG.getTargetExternalSymbol(tmpName, MVT::i8); + + // Store the value to ES. + SDValue Store = DAG.getNode (PIC16ISD::PIC16Store, MVT::Other, + DAG.getEntryNode(), + Op, ES, + DAG.getConstant (1, MVT::i8), // Banksel. + DAG.getConstant (FI, MVT::i8)); + + // Load the value from ES. + SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Other); + SDValue Load = DAG.getNode(PIC16ISD::PIC16Load, Tys, Store, + ES, DAG.getConstant (1, MVT::i8), + DAG.getConstant (FI, MVT::i8)); + + return Load.getValue(0); +} + +SDValue PIC16TargetLowering:: LowerADDC(SDValue Op, SelectionDAG &DAG) { + // We should have handled larger operands in type legalizer itself. + assert (Op.getValueType() == MVT::i8 && "illegal addc to lower"); + + // Nothing to do if the one of the operands is already a load. + if (Op.getOperand(0).getOpcode() == PIC16ISD::PIC16Load + || Op.getOperand(1).getOpcode() == PIC16ISD::PIC16Load) + return SDValue(); - return DAG.getMergeValues(Op.getNode()->getVTList(), &ArgValues[0], - ArgValues.size()).getValue(Op.getResNo()); + // Put one value on stack. + SDValue NewVal = ConvertToMemOperand (Op.getOperand(1), DAG); + + SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Flag); + return DAG.getNode(ISD::ADDC, Tys, Op.getOperand(0), NewVal); } +SDValue PIC16TargetLowering:: LowerADDE(SDValue Op, SelectionDAG &DAG) { + // We should have handled larger operands in type legalizer itself. + assert (Op.getValueType() == MVT::i8 && "illegal adde to lower"); + + // Nothing to do if the one of the operands is already a load. + if (Op.getOperand(0).getOpcode() == PIC16ISD::PIC16Load + || Op.getOperand(1).getOpcode() == PIC16ISD::PIC16Load) + return SDValue(); -//===----------------------------------------------------------------------===// -// Return Value Calling Convention Implementation -//===----------------------------------------------------------------------===// + // Put one value on stack. + SDValue NewVal = ConvertToMemOperand (Op.getOperand(1), DAG); + + SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Flag); + return DAG.getNode(ISD::ADDE, Tys, Op.getOperand(0), NewVal, + Op.getOperand(2)); +} -//===----------------------------------------------------------------------===// -// PIC16 Inline Assembly Support -//===----------------------------------------------------------------------===// +SDValue PIC16TargetLowering:: LowerSUBC(SDValue Op, SelectionDAG &DAG) { + // We should have handled larger operands in type legalizer itself. + assert (Op.getValueType() == MVT::i8 && "illegal subc to lower"); -//===----------------------------------------------------------------------===// -// Target Optimization Hooks -//===----------------------------------------------------------------------===// + // Nothing to do if the first operand is already a load. + if (Op.getOperand(0).getOpcode() == PIC16ISD::PIC16Load) + return SDValue(); -SDValue PIC16TargetLowering::PerformDAGCombine(SDNode *N, - DAGCombinerInfo &DCI) const -{ - int i; - ConstantSDNode *CST; - SelectionDAG &DAG = DCI.DAG; + // Put first operand on stack. + SDValue NewVal = ConvertToMemOperand (Op.getOperand(0), DAG); - switch (N->getOpcode()) { - default: - break; + SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Flag); + return DAG.getNode(ISD::SUBC, Tys, NewVal, Op.getOperand(1)); +} - case PIC16ISD::Package: - DOUT << "==== combining PIC16ISD::Package\n"; - return SDValue(); +SDValue PIC16TargetLowering:: LowerSUBE(SDValue Op, SelectionDAG &DAG) { + // We should have handled larger operands in type legalizer itself. + assert (Op.getValueType() == MVT::i8 && "illegal sube to lower"); - case ISD::ADD: - case ISD::SUB: - if ((N->getOperand(0).getOpcode() == ISD::GlobalAddress) || - (N->getOperand(0).getOpcode() == ISD::FrameIndex)) { - // Do not touch pointer adds. - return SDValue (); - } - break; + // Nothing to do if the first operand is already a load. + if (Op.getOperand(0).getOpcode() == PIC16ISD::PIC16Load) + return SDValue(); - case ISD::ADDE : - case ISD::ADDC : - case ISD::SUBE : - case ISD::SUBC : - if (N->getValueType(0) == MVT::i16) { - SDValue retVal = LowerADDSUB(N, DAG,DCI); - // LowerADDSUB has already combined the result, - // so we just return nothing to avoid assertion failure from llvm - // if N has been deleted already. - return SDValue(); - } - else if (N->getValueType(0) == MVT::i8) { - // Sanity check .... - for (int i=0; i<2; i++) { - if (N->getOperand (i).getOpcode() == PIC16ISD::Package) { - assert (0 && - "don't want to have PIC16ISD::Package as intput to add:i8"); - } - } - } - break; + // Put first operand on stack. + SDValue NewVal = ConvertToMemOperand (Op.getOperand(0), DAG); - // FIXME: split this large chunk of code. - case ISD::STORE : - { - SDValue Chain = N->getOperand(0); - SDValue Src = N->getOperand(1); - SDValue Dest = N->getOperand(2); - unsigned int DstOff = 0; - int NUM_STORES = 0; - SDValue Stores[6]; - - // if source operand is expected to be extended to - // some higher type then - remove this extension - // SDNode and do the extension manually - if ((Src.getOpcode() == ISD::ANY_EXTEND) || - (Src.getOpcode() == ISD::SIGN_EXTEND) || - (Src.getOpcode() == ISD::ZERO_EXTEND)) { - Src = Src.getNode()->getOperand(0); - Stores[0] = DAG.getStore(Chain, Src, Dest, NULL,0); - return Stores[0]; - } + SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Flag); + return DAG.getNode(ISD::SUBE, Tys, NewVal, Op.getOperand(1), + Op.getOperand(2)); +} - switch(Src.getValueType().getSimpleVT()) { - default: - assert(false && "Invalid value type!"); - - case MVT::i8: - break; - - case MVT::i16: - NUM_STORES = 2; - break; - - case MVT::i32: - NUM_STORES = 4; - break; - - case MVT::i64: - NUM_STORES = 8; - break; - } +// LowerFORMAL_ARGUMENTS - In Lowering FORMAL ARGUMENTS - MERGE_VALUES nodes +// is returned. MERGE_VALUES nodes number of operands and number of values are +// equal. Therefore to construct MERGE_VALUE node, UNDEF nodes equal to the +// number of arguments of function have been created. - if (isa(Dest) && isa(Src) && - (Src.getValueType() != MVT::i8)) { - //create direct addressing a = b - Chain = Src.getOperand(0); - for (i=0; i(Dest) && isa(Src) - && (Src.getValueType() != MVT::i8)) { - //create direct addressing a = CONST - CST = dyn_cast(Src); - for (i = 0; i < NUM_STORES; i++) { - SDValue CNST = DAG.getConstant(CST->getZExtValue() >> i*8, MVT::i8); - SDValue ADN = DAG.getNode(ISD::ADD, MVT::i16, Dest, - DAG.getConstant(DstOff, MVT::i16)); - Stores[i] = DAG.getStore(Chain, CNST, ADN, NULL, 0); - Chain = Stores[i]; - DstOff += 1; - } - - Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, &Stores[0], i); - return Chain; - } - else if (isa(Dest) && isa(Src) - && (Src.getValueType() != MVT::i8)) { - // Create indirect addressing. - CST = dyn_cast(Src); - Chain = Dest.getOperand(0); - SDValue Load; - Load = DAG.getLoad(MVT::i16, Chain,Dest.getOperand(1), NULL, 0); - Chain = Load.getValue(1); - for (i=0; igetZExtValue() >> i*8, MVT::i8); - Stores[i] = DAG.getStore(Chain, CNST, Load, NULL, 0); - Chain = Stores[i]; - DstOff += 1; - } - - Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, &Stores[0], i); - return Chain; - } - else if (isa(Dest) && isa(Src)) { - // GlobalAddressSDNode *GAD = dyn_cast(Src); - return SDValue(); - } - else if (Src.getOpcode() == PIC16ISD::Package) { - StoreSDNode *st = dyn_cast(N); - SDValue toWorkList, retVal; - Chain = N->getOperand(0); - - if (st->isTruncatingStore()) { - retVal = DAG.getStore(Chain, Src.getOperand(0), Dest, NULL, 0); - } - else { - toWorkList = DAG.getNode(ISD::ADD, MVT::i16, Dest, - DAG.getConstant(1, MVT::i16)); - Stores[1] = DAG.getStore(Chain, Src.getOperand(0), Dest, NULL, 0); - Stores[0] = DAG.getStore(Chain, Src.getOperand(1), toWorkList, NULL, - 0); - - // We want to merge sequence of add with constant to one add and a - // constant, so add the ADD node to worklist to have llvm do that - // automatically. - DCI.AddToWorklist(toWorkList.getNode()); - - // We don't need the Package so add to worklist so llvm deletes it - DCI.AddToWorklist(Src.getNode()); - retVal = DAG.getNode(ISD::TokenFactor, MVT::Other, &Stores[0], 2); - } +SDValue PIC16TargetLowering:: LowerFORMAL_ARGUMENTS(SDValue Op, + SelectionDAG &DAG) { + SmallVector ArgValues; + unsigned NumArgs = Op.getNumOperands() - 3; - return retVal; - } - else if (Src.getOpcode() == ISD::TRUNCATE) { - } - else { - } - } // end ISD::STORE. - break; + // Creating UNDEF nodes to meet the requirement of MERGE_VALUES node. + for(unsigned i = 0 ; igetValueType(i)); + ArgValues.push_back(TempNode); + } - case ISD::LOAD : - { - SDValue Ptr = N->getOperand(1); - if (Ptr.getOpcode() == PIC16ISD::Package) { - assert (0 && "not implemented yet"); - } - } - break; - } // end switch. + ArgValues.push_back(Op.getOperand(0)); + return DAG.getNode(ISD::MERGE_VALUES, Op.getNode()->getVTList(), + &ArgValues[0], + ArgValues.size()).getValue(Op.getResNo()); +} +// Perform DAGCombine of PIC16Load +SDValue PIC16TargetLowering:: +PerformPIC16LoadCombine(SDNode *N, DAGCombinerInfo &DCI) const { + SelectionDAG &DAG = DCI.DAG; + SDValue Chain = N->getOperand(0); + if (N->hasNUsesOfValue(0, 0)) { + DAG.ReplaceAllUsesOfValueWith(SDValue(N,1), Chain); + } return SDValue(); } -//===----------------------------------------------------------------------===// -// Utility functions -//===----------------------------------------------------------------------===// -const SDValue *PIC16TargetLowering:: -findLoadi8(const SDValue &Src, SelectionDAG &DAG) const -{ - unsigned int i; - if ((Src.getOpcode() == ISD::LOAD) && (Src.getValueType() == MVT::i8)) - return &Src; - for (i=0; igetOpcode()) { + case PIC16ISD::PIC16Load: + return PerformPIC16LoadCombine(N, DCI); + } + return SDValue(); } Modified: llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.h?rev=59617&r1=59616&r2=59617&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.h (original) +++ llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.h Wed Nov 19 05:00:54 2008 @@ -26,66 +26,89 @@ // Start the numbering from where ISD NodeType finishes. FIRST_NUMBER = ISD::BUILTIN_OP_END, - // used for encapsulating the expanded nodes into one node. - Package, - - // Get the Higher 16 bits from a 32-bit immediate - Hi, - - // Get the Lower 16 bits from a 32-bit immediate - Lo, + Lo, // Low 8-bits of GlobalAddress. + Hi, // High 8-bits of GlobalAddress. + PIC16Load, + PIC16Store, + Banksel, + MTLO, + MTHI, + BCF, + LSLF, // PIC16 Logical shift left + LRLF, // PIC16 Logical shift right + RLF, // Rotate left through carry + RRF, // Rotate right through carry + Dummy + }; - Cmp, // PIC16 Generic Comparison instruction. - Branch, // PIC16 Generic Branch Instruction. - BTFSS, // PIC16 BitTest Instruction (Skip if set). - BTFSC, // PIC16 BitTest Instruction (Skip if clear). - - // PIC16 comparison to be converted to either XOR or SUB - // Following instructions cater to those convertions. - XORCC, - SUBCC, - - // Get the Global Address wrapped into a wrapper that also captures - // the bank or page. - Wrapper, - SetBank, - SetPage + // Keep track of different address spaces. + enum AddressSpace { + RAM_SPACE = 0, // RAM address space + ROM_SPACE = 1 // ROM address space number is 1 }; } //===--------------------------------------------------------------------===// // TargetLowering Implementation //===--------------------------------------------------------------------===// - class PIC16TargetLowering : public TargetLowering - { + class PIC16TargetLowering : public TargetLowering { public: - typedef std::map NodeMap_t; - explicit PIC16TargetLowering(PIC16TargetMachine &TM); - /// LowerOperation - Provide custom lowering hooks for some operations. - virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG); - - SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG); - SDValue LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG); - SDValue LowerRET(SDValue Op, SelectionDAG &DAG); - SDValue LowerFrameIndex(SDValue Op, SelectionDAG &DAG); - SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG); - - SDValue RemoveHiLo(SDNode *, SelectionDAG &DAG, - DAGCombinerInfo &DCI) const; - SDValue LowerADDSUB(SDNode *, SelectionDAG &DAG, - DAGCombinerInfo &DCI) const; - SDValue LowerLOAD(SDNode *, SelectionDAG &DAG, - DAGCombinerInfo &DCI) const; - - /// getTargetNodeName - This method returns the name of a target specific - // DAG node. + /// getTargetNodeName - This method returns the name of a target specific + /// DAG node. virtual const char *getTargetNodeName(unsigned Opcode) const; - virtual SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const; - - // utility function. - const SDValue *findLoadi8(const SDValue &Src, SelectionDAG &DAG) const; + SDValue LowerOperation(SDValue Op, SelectionDAG &DAG); + SDValue LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG); + SDValue LowerADDE(SDValue Op, SelectionDAG &DAG); + SDValue LowerADDC(SDValue Op, SelectionDAG &DAG); + SDValue LowerSUBE(SDValue Op, SelectionDAG &DAG); + SDValue LowerSUBC(SDValue Op, SelectionDAG &DAG); + + SDNode *ReplaceNodeResults(SDNode *N, SelectionDAG &DAG); + SDNode *ExpandStore(SDNode *N, SelectionDAG &DAG); + SDNode *ExpandLoad(SDNode *N, SelectionDAG &DAG); + SDNode *ExpandAdd(SDNode *N, SelectionDAG &DAG); + SDNode *ExpandGlobalAddress(SDNode *N, SelectionDAG &DAG); + SDNode *ExpandShift(SDNode *N, SelectionDAG &DAG); + + SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const; + SDValue PerformPIC16LoadCombine(SDNode *N, DAGCombinerInfo &DCI) const; + + private: + // If the Node is a BUILD_PAIR representing representing an Address + // then this function will return true + bool isDirectAddress(const SDValue &Op); + + // If the Node is a DirectAddress in ROM_SPACE then this + // function will return true + bool isRomAddress(const SDValue &Op); + + // To extract chain value from the SDValue Nodes + // This function will help to maintain the chain extracting + // code at one place. In case of any change in future it will + // help maintain the code + SDValue getChain(SDValue &Op); + + + // Extract the Lo and Hi component of Op. + void GetExpandedParts(SDValue Op, SelectionDAG &DAG, SDValue &Lo, + SDValue &Hi); + + + // Load pointer can be a direct or indirect address. In PIC16 direct + // addresses need Banksel and Indirect addresses need to be loaded to + // FSR first. Handle address specific cases here. + void LegalizeAddress(SDValue Ptr, SelectionDAG &DAG, SDValue &Chain, + SDValue &NewPtr, unsigned &Offset); + + // We can not have both operands of a binary operation in W. + // This function is used to put one operand on stack and generate a load. + SDValue ConvertToMemOperand(SDValue Op, SelectionDAG &DAG); + + /// Subtarget - Keep a pointer to the PIC16Subtarget around so that we can + /// make the right decision when generating code for different targets. + const PIC16Subtarget *Subtarget; }; } // namespace llvm Modified: llvm/trunk/lib/Target/PIC16/PIC16InstrFormats.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16InstrFormats.td?rev=59617&r1=59616&r2=59617&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16InstrFormats.td (original) +++ llvm/trunk/lib/Target/PIC16/PIC16InstrFormats.td Wed Nov 19 05:00:54 2008 @@ -1,4 +1,4 @@ -//===- PIC16RegisterInfo.td - PIC16 Register defs ------------*- tblgen -*-===// +//===- PIC16InstrFormats.td - PIC16 Instruction Formats-------*- tblgen -*-===// // // The LLVM Compiler Infrastructure // @@ -21,16 +21,17 @@ //===----------------------------------------------------------------------===// // Generic PIC16 Format +// PIC16 Instructions are 14-bit wide. + +// FIXME: Add Cooper Specific Formats if any. + class PIC16Inst pattern> - : Instruction -{ + : Instruction { field bits<14> Inst; let Namespace = "PIC16"; - dag OutOperandList = outs; dag InOperandList = ins; - let AsmString = asmstr; let Pattern = pattern; } @@ -38,16 +39,18 @@ //===----------------------------------------------------------------------===// // Byte Oriented instruction class in PIC16 : <|opcode|d|f|> +// opcode = 6 bits. +// d = direction = 1 bit. +// f = file register address = 7 bits. //===----------------------------------------------------------------------===// -class ByteFormat op, dag outs, dag ins, string asmstr, - list pattern> - :PIC16Inst -{ +class ByteFormat opcode, dag outs, dag ins, string asmstr, + list pattern> + :PIC16Inst { bits<1> d; bits<7> f; - let Inst{13-8} = op; + let Inst{13-8} = opcode; let Inst{7} = d; let Inst{6-0} = f; @@ -55,15 +58,18 @@ //===----------------------------------------------------------------------===// // Bit Oriented instruction class in PIC16 : <|opcode|b|f|> +// opcode = 4 bits. +// b = bit specifier = 3 bits. +// f = file register address = 7 bits. //===----------------------------------------------------------------------===// -class BitFormat op, dag outs, dag ins, string asmstr, list pattern> - : PIC16Inst -{ +class BitFormat opcode, dag outs, dag ins, string asmstr, + list pattern> + : PIC16Inst { bits<3> b; bits<7> f; - let Inst{13-10} = op; + let Inst{13-10} = opcode; let Inst{9-7} = b; let Inst{6-0} = f; @@ -71,32 +77,32 @@ //===----------------------------------------------------------------------===// // Literal Format instruction class in PIC16 : <|opcode|k|> +// opcode = 6 bits +// k = literal = 8 bits //===----------------------------------------------------------------------===// -class LiteralFormat op, dag outs, dag ins, string asmstr, +class LiteralFormat opcode, dag outs, dag ins, string asmstr, list pattern> - : PIC16Inst -{ + : PIC16Inst { bits<8> k; - - let Inst{13-8} = op; + let Inst{13-8} = opcode; let Inst{7-0} = k; } //===----------------------------------------------------------------------===// // Control Format instruction class in PIC16 : <|opcode|k|> +// opcode = 3 bits. +// k = jump address = 11 bits. //===----------------------------------------------------------------------===// -class ControlFormat op, dag outs, dag ins, string asmstr, +class ControlFormat opcode, dag outs, dag ins, string asmstr, list pattern> - :PIC16Inst -{ + : PIC16Inst { bits<11> k; - - let Inst{13-11} = op; + let Inst{13-11} = opcode; let Inst{10-0} = k; } @@ -105,8 +111,7 @@ // Pseudo instruction class in PIC16 //===----------------------------------------------------------------------===// -class Pseudo op, dag outs, dag ins, string asmstr, list pattern>: - PIC16Inst -{ - let Inst{13-6} = op; +class Pseudo pattern> + : PIC16Inst { + let Inst{13-6} = 0; } Modified: llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.cpp?rev=59617&r1=59616&r2=59617&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.cpp (original) +++ llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.cpp Wed Nov 19 05:00:54 2008 @@ -13,132 +13,131 @@ #include "PIC16.h" #include "PIC16InstrInfo.h" +#include "PIC16TargetMachine.h" +#include "PIC16GenInstrInfo.inc" #include "llvm/Function.h" #include "llvm/ADT/STLExtras.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstrBuilder.h" -#include "PIC16GenInstrInfo.inc" -#include +#include "llvm/CodeGen/MachineRegisterInfo.h" + using namespace llvm; // FIXME: Add the subtarget support on this constructor. PIC16InstrInfo::PIC16InstrInfo(PIC16TargetMachine &tm) : TargetInstrInfoImpl(PIC16Insts, array_lengthof(PIC16Insts)), - TM(tm), RI(*this) {} + TM(tm), + RegInfo(*this, *TM.getSubtargetImpl()) {} -static bool isZeroImm(const MachineOperand &op) { - return op.isImm() && op.getImm() == 0; -} - -/// isLoadFromStackSlot - If the specified machine instruction is a direct -/// load from a stack slot, return the virtual or physical register number of -/// the destination along with the FrameIndex of the loaded stack slot. If -/// not, return 0. This predicate must return 0 if the instruction has -/// any side effects other than loading from the stack slot. -unsigned PIC16InstrInfo:: -isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const -{ - if (MI->getOpcode() == PIC16::MOVF) { - if ((MI->getOperand(2).isFI()) && // is a stack slot - (MI->getOperand(1).isImm()) && // the imm is zero - (isZeroImm(MI->getOperand(1)))) { - FrameIndex = MI->getOperand(2).getIndex(); - return MI->getOperand(0).getReg(); - } +/// isStoreToStackSlot - If the specified machine instruction is a direct +/// store to a stack slot, return the virtual or physical register number of +/// the source reg along with the FrameIndex of the loaded stack slot. +/// If not, return 0. This predicate must return 0 if the instruction has +/// any side effects other than storing to the stack slot. +unsigned PIC16InstrInfo::isStoreToStackSlot(MachineInstr *MI, + int &FrameIndex) const { + if (MI->getOpcode() == PIC16::movwf + && MI->getOperand(0).isReg() + && MI->getOperand(1).isSymbol()) { + FrameIndex = MI->getOperand(1).getIndex(); + return MI->getOperand(0).getReg(); } - return 0; } -/// isStoreToStackSlot - If the specified machine instruction is a direct -/// store to a stack slot, return the virtual or physical register number of -/// the source reg along with the FrameIndex of the loaded stack slot. If -/// not, return 0. This predicate must return 0 if the instruction has +/// isLoadFromStackSlot - If the specified machine instruction is a direct +/// load from a stack slot, return the virtual or physical register number of +/// the dest reg along with the FrameIndex of the stack slot. +/// If not, return 0. This predicate must return 0 if the instruction has /// any side effects other than storing to the stack slot. -unsigned PIC16InstrInfo:: -isStoreToStackSlot(const MachineInstr *MI, int &FrameIndex) const -{ - if (MI->getOpcode() == PIC16::MOVWF) { - if ((MI->getOperand(0).isFI()) && // is a stack slot - (MI->getOperand(1).isImm()) && // the imm is zero - (isZeroImm(MI->getOperand(1)))) { - FrameIndex = MI->getOperand(0).getIndex(); - return MI->getOperand(2).getReg(); - } +unsigned PIC16InstrInfo::isLoadFromStackSlot(MachineInstr *MI, + int &FrameIndex) const { + if (MI->getOpcode() == PIC16::movf + && MI->getOperand(0).isReg() + && MI->getOperand(1).isSymbol()) { + FrameIndex = MI->getOperand(1).getIndex(); + return MI->getOperand(0).getReg(); } return 0; } -void PIC16InstrInfo:: -storeRegToStackSlot(MachineBasicBlock &MBB, - MachineBasicBlock::iterator I, - unsigned SrcReg, bool isKill, int FI, - const TargetRegisterClass *RC) const { + +void PIC16InstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, + MachineBasicBlock::iterator I, + unsigned SrcReg, bool isKill, int FI, + const TargetRegisterClass *RC) const { + const Function *Func = MBB.getParent()->getFunction(); const std::string FuncName = Func->getName(); char *tmpName = new char [strlen(FuncName.c_str()) + 6]; - sprintf(tmpName, "%s_tmp_%d",FuncName.c_str(),FI); + sprintf(tmpName, "%s.tmp", FuncName.c_str()); - if (RC == PIC16::CPURegsRegisterClass) { - //src is always WREG. - BuildMI(MBB, I, this->get(PIC16::MOVWF)) - .addReg(SrcReg,false,false,true,true) - .addExternalSymbol(tmpName) // the current printer expects 3 operands, - .addExternalSymbol(tmpName); // all we need is actually one, - // so we repeat. + // On the order of operands here: think "movwf SrcReg, tmp_slot, offset". + if (RC == PIC16::GPRRegisterClass) { + //MachineFunction &MF = *MBB.getParent(); + //MachineRegisterInfo &RI = MF.getRegInfo(); + BuildMI(MBB, I, get(PIC16::movwf)) + .addReg(SrcReg, false, false, isKill) + .addImm(FI) + .addExternalSymbol(tmpName) + .addImm(1); // Emit banksel for it. } + else if (RC == PIC16::FSR16RegisterClass) + assert(0 && "Don't know yet how to store a FSR16 to stack slot"); else assert(0 && "Can't store this register to stack slot"); } -void PIC16InstrInfo:: -loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, - unsigned DestReg, int FI, - const TargetRegisterClass *RC) const -{ +void PIC16InstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, + MachineBasicBlock::iterator I, + unsigned DestReg, int FI, + const TargetRegisterClass *RC) const { + const Function *Func = MBB.getParent()->getFunction(); const std::string FuncName = Func->getName(); char *tmpName = new char [strlen(FuncName.c_str()) + 6]; - sprintf(tmpName, "%s_tmp_%d",FuncName.c_str(),FI); + sprintf(tmpName, "%s.tmp", FuncName.c_str()); - if (RC == PIC16::CPURegsRegisterClass) - BuildMI(MBB, I, this->get(PIC16::MOVF), DestReg) - .addExternalSymbol(tmpName) // the current printer expects 3 operands, - .addExternalSymbol(tmpName); // all we need is actually one,so we repeat. + // On the order of operands here: think "movf FrameIndex, W". + if (RC == PIC16::GPRRegisterClass) { + //MachineFunction &MF = *MBB.getParent(); + //MachineRegisterInfo &RI = MF.getRegInfo(); + BuildMI(MBB, I, get(PIC16::movf), DestReg) + .addImm(FI) + .addExternalSymbol(tmpName) + .addImm(1); // Emit banksel for it. + } + else if (RC == PIC16::FSR16RegisterClass) + assert(0 && "Don't know yet how to load an FSR16 from stack slot"); else assert(0 && "Can't load this register from stack slot"); } -/// InsertBranch - Insert a branch into the end of the specified -/// MachineBasicBlock. This operands to this method are the same as those -/// returned by AnalyzeBranch. This is invoked in cases where AnalyzeBranch -/// returns success and when an unconditional branch (TBB is non-null, FBB is -/// null, Cond is empty) needs to be inserted. It returns the number of -/// instructions inserted. -unsigned PIC16InstrInfo:: -InsertBranch(MachineBasicBlock &MBB, - MachineBasicBlock *TBB, MachineBasicBlock *FBB, - const SmallVectorImpl &Cond) const -{ - // Shouldn't be a fall through. - assert(TBB && "InsertBranch must not be told to insert a fallthrough"); - - if (FBB == 0) { // One way branch. - if (Cond.empty()) { - // Unconditional branch? - BuildMI(&MBB, get(PIC16::GOTO)).addMBB(TBB); - } - return 1; - } - - // FIXME: If the there are some conditions specified then conditional branch - // should be generated. - // For the time being no instruction is being generated therefore - // returning NULL. - return 0; +bool PIC16InstrInfo::copyRegToReg (MachineBasicBlock &MBB, + MachineBasicBlock::iterator I, + unsigned DestReg, unsigned SrcReg, + const TargetRegisterClass *DestRC, + const TargetRegisterClass *SrcRC) const { + if (DestRC == PIC16::FSR16RegisterClass) { + BuildMI(MBB, I, get(PIC16::copy_fsr), DestReg).addReg(SrcReg); + } + + return true; +} + +bool PIC16InstrInfo::isMoveInstr(const MachineInstr &MI, + unsigned &SrcReg, + unsigned &DestReg) const { + + if (MI.getOpcode() == PIC16::copy_fsr) { + DestReg = MI.getOperand(0).getReg(); + SrcReg = MI.getOperand(1).getReg(); + return true; + } + return false; } Modified: llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.h?rev=59617&r1=59616&r2=59617&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.h (original) +++ llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.h Wed Nov 19 05:00:54 2008 @@ -24,54 +24,43 @@ class PIC16InstrInfo : public TargetInstrInfoImpl { PIC16TargetMachine &TM; - const PIC16RegisterInfo RI; + const PIC16RegisterInfo RegInfo; public: explicit PIC16InstrInfo(PIC16TargetMachine &TM); - /// getRegisterInfo - TargetInstrInfo is a superset of MRegister info. As - /// such, whenever a client has an instance of instruction info, it should - /// always be able to get register info as well (through this method). - /// - virtual const PIC16RegisterInfo &getRegisterInfo() const { return RI; } + virtual const PIC16RegisterInfo &getRegisterInfo() const { return RegInfo; } - /// isLoadFromStackSlot - If the specified machine instruction is a direct /// load from a stack slot, return the virtual or physical register number of /// the destination along with the FrameIndex of the loaded stack slot. If /// not, return 0. This predicate must return 0 if the instruction has /// any side effects other than loading from the stack slot. - virtual unsigned isLoadFromStackSlot(const MachineInstr *MI, - int &FrameIndex) const; - + virtual unsigned isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const; + /// isStoreToStackSlot - If the specified machine instruction is a direct /// store to a stack slot, return the virtual or physical register number of /// the source reg along with the FrameIndex of the loaded stack slot. If /// not, return 0. This predicate must return 0 if the instruction has /// any side effects other than storing to the stack slot. - virtual unsigned isStoreToStackSlot(const MachineInstr *MI, - int &FrameIndex) const; - - /// Used for spilling a register - void storeRegToStackSlot(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, - unsigned SrcReg, bool isKill, int FrameIndex, - const TargetRegisterClass *RC) const; - - - void loadRegFromStackSlot(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, - unsigned DestReg, int FrameIndex, - const TargetRegisterClass *RC) const; - - /// InsertBranch - Insert a branch into the end of the specified - /// MachineBasicBlock. This operands to this method are the same as those - /// returned by AnalyzeBranch. This is invoked in cases where AnalyzeBranch - /// returns success and when an unconditional branch (TBB is non-null, FBB is - /// null, Cond is empty) needs to be inserted. It returns the number of - /// instructions inserted. - virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, - MachineBasicBlock *FBB, - const SmallVectorImpl &Cond) const ; + virtual unsigned isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const; + + virtual void storeRegToStackSlot(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MBBI, + unsigned SrcReg, bool isKill, int FrameIndex, + const TargetRegisterClass *RC) const; + + virtual void loadRegFromStackSlot(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MBBI, + unsigned DestReg, int FrameIndex, + const TargetRegisterClass *RC) const; + virtual bool copyRegToReg(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MBBI, + unsigned DestReg, unsigned SrcReg, + const TargetRegisterClass *DestRC, + const TargetRegisterClass *SrcRC) const; + virtual bool isMoveInstr(const MachineInstr &MI, + unsigned &SrcReg, + unsigned &DestReg) const; }; Modified: llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.td?rev=59617&r1=59616&r2=59617&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.td (original) +++ llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.td Wed Nov 19 05:00:54 2008 @@ -1,4 +1,4 @@ -//===- PIC16InstrInfo.td - PIC16 Register defs ----------------*- tblgen-*-===// +//===- PIC16InstrInfo.td - PIC16 Instruction defs -------------*- tblgen-*-===// // // The LLVM Compiler Infrastructure // @@ -6,297 +6,302 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// - -//===----------------------------------------------------------------------===// -// Instruction format superclass +// +// This file describes the ARM instructions in TableGen format. +// //===----------------------------------------------------------------------===// -include "PIC16InstrFormats.td" - //===----------------------------------------------------------------------===// -// PIC16 profiles and nodes +// PIC16 Specific Type Constraints. //===----------------------------------------------------------------------===// +class SDTCisI8 : SDTCisVT; +class SDTCisI16 : SDTCisVT; //===----------------------------------------------------------------------===// -// PIC16 addressing mode. +// PIC16 Specific Type Profiles. //===----------------------------------------------------------------------===// -// It matches address of globals as well as the stack slots -// that are created for locals and temporaries. This addressing mode -// converts the GlobalAddress and FrameIndex nodes to TargetGlobalAddress -// and TargetFrameIndex nodes. -def diraddrmode : ComplexPattern; -def dirloadmode : ComplexPattern; -def indirloadmode : ComplexPattern; - - -// Address operand. -def mem : Operand { - let PrintMethod = "printAddrModeOperand"; - let MIOperandInfo = (ops i16imm, PTRRegs); -} - -// Instruction operand types -def simm8 : Operand; - - -// These are target-independent nodes, but have target-specific formats. -def SDT_PIC16CallSeq : SDTypeProfile<0, 1, [ SDTCisVT<0, i8> ]>; -def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_PIC16CallSeq, - [SDNPHasChain, SDNPOutFlag]>; -def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_PIC16CallSeq, - [SDNPHasChain, SDNPOutFlag]>; - -def PIC16Wrapper : SDNode<"PIC16ISD::Wrapper", SDTIntUnaryOp>; - -// so_imm_XFORM - Return a so_imm value packed into the format described for -// so_imm def below. -def so_imm_XFORM : SDNodeXFormgetTargetConstant((int8_t)N->getZExtValue(), MVT::i32); -}]>; - -def so_imm : Operand, - PatLeaf<(imm), [{}]> { - let PrintMethod = "printSOImmOperand"; -} - - - -// PIC16 Address Mode! SDNode frameindex could possibily be a match -// since load and store instructions from stack used it. -def addr : Operand; - -// Arithmetic 2 register operands -class ArithI op, string instr_asm, SDNode OpNode, - Operand Od> : - LiteralFormat< op, - (outs CPURegs:$dst), - (ins CPURegs:$b, Od:$c), - !strconcat(instr_asm, " $c"), - [(set CPURegs:$dst, (OpNode CPURegs:$b, Od:$c))]>; - -// Memory Load/Store. -class LoadDirect op, string instr_asm, PatFrag OpNode>: - ByteFormat< op, - (outs CPURegs:$dst), - (ins mem:$addr), - !strconcat(instr_asm, " $addr"), - [(set CPURegs:$dst, (OpNode diraddrmode:$addr))]>; - -class LoadInDirect op, string instr_asm, PatFrag OpNode>: - ByteFormat< op, - (outs PTRRegs:$dst), - (ins mem:$addr), - !strconcat(instr_asm, " $addr, $dst"), - [(set PTRRegs:$dst, (OpNode indirloadmode:$addr))]>; - -class StoreDirect op, string instr_asm, PatFrag OpNode>: - ByteFormat< op, - (outs), - (ins CPURegs:$src, mem:$addr), - !strconcat(instr_asm, " $addr"), - [(OpNode CPURegs:$src, diraddrmode:$addr)]>; - -class StoreInDirect op, string instr_asm, PatFrag OpNode>: - ByteFormat< op, - (outs), - (ins CPURegs:$src, PTRRegs:$fsr), - !strconcat(instr_asm, " $fsr"), - [(OpNode CPURegs:$src, PTRRegs:$fsr)]>; - -// Move. -class MovLit op, string instr_asm>: - LiteralFormat< op, - (outs CPURegs:$dst), - (ins i8imm:$src), - !strconcat(instr_asm, " $src"), - [(set CPURegs:$dst, imm:$src)]>; - - -// Arithmetic with memory store. -// Arithmetic instrunctions involving W and memory location. -// Since W is implicit, we only print the memory operand. -class Arith1M op, string instr_asm, SDNode OpNode>: - ByteFormat< op, - (outs), - (ins CPURegs:$b, mem:$dst), - !strconcat(instr_asm, " $dst"), - [(store (OpNode (load diraddrmode:$dst), CPURegs:$b), diraddrmode:$dst), - (store (OpNode CPURegs:$b, (load diraddrmode:$dst)), diraddrmode:$dst)]>; - -// Arithmetic with memory load. -// Arithmetic instrunctions involving W and memory location. -// Since W is implicit, we only print the memory operand. -class Arith1R op, string instr_asm, SDNode OpNode>: - ByteFormat< op, - (outs CPURegs:$dst), - (ins mem:$src1, CPURegs:$src2), - !strconcat(instr_asm, " $src1"), - [(set CPURegs:$dst, (OpNode (load diraddrmode:$src1), CPURegs:$src2))]>; - -// Arithmetic with memory load. -// Arithmetic instrunctions involving W and memory location. -// Since W is implicit, we only print the memory operand. -class Arith2R op, string instr_asm, SDNode OpNode>: - ByteFormat< op, - (outs CPURegs:$dst), - (ins mem:$src1, CPURegs:$src2), - !strconcat(instr_asm, " $src1"), - [(set CPURegs:$dst, (OpNode CPURegs:$src2, (load diraddrmode:$src1)))]>; - -//===----------------------------------------------------------------------===// -// Instruction definition -//===----------------------------------------------------------------------===// - -//===----------------------------------------------------------------------===// -// PIC16I Instructions -//===----------------------------------------------------------------------===// - -// Arithmetic - -// ADDiu just accept 16-bit immediates but we handle this on Pat's. -// immZExt32 is used here so it can match GlobalAddress immediates. -// def ADDLW : ArithI<0x09, "addlw", add, so_imm>; - -let isReMaterializable = 1 in { -def MOVLW : MovLit<0x24, "movlw">; -} - -// Load/Store -def LFSR1 : LoadInDirect <0x4, "lfsr", load>; - -let isReMaterializable = 1 in { -def MOVF : LoadDirect <0x23, "movf", load>; -} - -def MOVWF : StoreDirect <0x2b, "movwf", store>; - -def MOVFSRINC : StoreInDirect <0x5, "movfsrinc", store>; - -def RETURN : ControlFormat<0x03, (outs), (ins), "return", []>; - -def ADDWF : Arith1M<0x01, "addwf", add>; -def ADDFW : Arith1R<0x02, "addfw", add>; - -def ADDWFE : Arith1M<0x03, "addwfe", adde>; -def ADDFWE : Arith1R<0x04, "addfwe", adde>; -def ADDWFC : Arith1M<0x05, "addwfc", addc>; -def ADDFWC : Arith1R<0x06, "addfwc", addc>; +// Generic type profiles for i8/i16 unary/binary operations. +// Taking one i8 or i16 and producing void. +def SDTI8VoidOp : SDTypeProfile<0, 1, [SDTCisI8<0>]>; +def SDTI16VoidOp : SDTypeProfile<0, 1, [SDTCisI16<0>]>; -def SUBWF : Arith1M<0x07, "subwf", sub>; -def SUBFW : Arith1R<0x08, "subfw", sub>; +// Taking one value and producing an output of same type. +def SDTI8UnaryOp : SDTypeProfile<1, 1, [SDTCisI8<0>, SDTCisI8<1>]>; +def SDTI16UnaryOp : SDTypeProfile<1, 1, [SDTCisI16<0>, SDTCisI16<1>]>; -def SUBWFE : Arith1M<0x09, "subwfe", sube>; -def SUBFWE : Arith1R<0x0a, "subfwe", sube>; +// Taking two values and producing an output of same type. +def SDTI8BinOp : SDTypeProfile<1, 2, [SDTCisI8<0>, SDTCisI8<1>, SDTCisI8<2>]>; +def SDTI16BinOp : SDTypeProfile<1, 2, [SDTCisI16<0>, SDTCisI16<1>, + SDTCisI16<2>]>; -def SUBWFC : Arith1M<0x0b, "subwfc", subc>; -def SUBFWC : Arith1R<0x0d, "subfwc", subc>; +// Node specific type profiles. +def SDT_PIC16Load : SDTypeProfile<1, 3, [SDTCisI8<0>, SDTCisI8<1>, + SDTCisI8<2>, SDTCisI8<3>]>; +def SDT_PIC16Store : SDTypeProfile<0, 4, [SDTCisI8<0>, SDTCisI8<1>, + SDTCisI8<2>, SDTCisI8<3>]>; -def SUBRFW : Arith2R<0x08, "subfw", sub>; - -def SUBRFWE : Arith2R<0x0a, "subfwe", sube>; - -def SUBRFWC : Arith2R<0x0d, "subfwc", subc>; - -def brtarget : Operand; - -class UncondJump< bits<4> op, string instr_asm>: - BitFormat< op, - (outs), - (ins brtarget:$target), - !strconcat(instr_asm, " $target"), - [(br bb:$target)]>; - -def GOTO : UncondJump<0x1, "goto">; - -class LogicM op, string instr_asm, SDNode OpNode> : - ByteFormat< op, - (outs), - (ins CPURegs:$b, mem:$dst), - !strconcat(instr_asm, " $dst"), - [(store (OpNode (load diraddrmode:$dst), CPURegs:$b), diraddrmode:$dst)]>; - -class LogicR op, string instr_asm, SDNode OpNode> : - ByteFormat< op, - (outs CPURegs:$dst), - (ins CPURegs:$b, mem:$c), - !strconcat(instr_asm, " $c"), - [(set CPURegs:$dst, (OpNode (load diraddrmode:$c), CPURegs:$b))]>; - -class LogicI op, string instr_asm, SDNode OpNode, Operand Od> : - LiteralFormat< op, - (outs CPURegs:$dst), - (ins CPURegs:$b, Od:$c), - !strconcat(instr_asm, " $c"), - [(set CPURegs:$dst, (OpNode CPURegs:$b, Od:$c ))]>; - -def XORWF : LogicM<0x1,"xorwf",xor>; -def XORFW : LogicR<0x1,"xorfw",xor>; -def XORLW : LogicI<0x1,"xorlw",xor, so_imm>; - -def ANDWF : LogicM<0x1,"andwf",and>; -def ANDFW : LogicR<0x1,"andfw",and>; -def ANDLW : LogicI<0x1,"andlw",and, so_imm>; - -def IORWF : LogicM<0x1,"iorwf",or>; -def IORFW : LogicR<0x1,"iorfw",or>; -def IORLW : LogicI<0x1,"iorlw",or, so_imm>; - - -/* For comparison before branch */ -def SDT_PIC16Cmp : SDTypeProfile<1, 3, [SDTCisSameAs<0,1>]>; -def SDTIntBinOpPIC16 : SDTypeProfile<1, 2, [SDTCisSameAs<0,1>, - SDTCisSameAs<1,2>, SDTCisInt<1>]>; +//===----------------------------------------------------------------------===// +// PIC16 addressing modes matching via DAG. +//===----------------------------------------------------------------------===// +def diraddr : ComplexPattern; -def PIC16Cmp : SDNode<"PIC16ISD::Cmp",SDTIntBinOpPIC16, [SDNPOutFlag]>; -def PIC16XORCC : SDNode<"PIC16ISD::XORCC",SDTIntBinOpPIC16, [SDNPOutFlag]>; -def PIC16SUBCC : SDNode<"PIC16ISD::SUBCC",SDTIntBinOpPIC16, [SDNPOutFlag]>; +//===----------------------------------------------------------------------===// +// PIC16 Specific Node Definitions. +//===----------------------------------------------------------------------===// +def PIC16callseq_start : SDNode<"ISD::CALLSEQ_START", SDTI8VoidOp, + [SDNPHasChain, SDNPOutFlag]>; +def PIC16callseq_end : SDNode<"ISD::CALLSEQ_END", SDTI8VoidOp, + [SDNPHasChain, SDNPOutFlag]>; -def XORFWCC : LogicR<0x1,"xorfw",PIC16XORCC>; -def XORLWCC : LogicI<0x1,"xorlw",PIC16XORCC, so_imm>; -def SUBFWCC : Arith1R<0x1,"subfw",PIC16SUBCC>; -def SUBLWCC : ArithI<0x1,"sublw",PIC16SUBCC, so_imm>; +// Low 8-bits of GlobalAddress. +def PIC16Lo : SDNode<"PIC16ISD::Lo", SDTI8UnaryOp>; +// High 8-bits of GlobalAddress. +def PIC16Hi : SDNode<"PIC16ISD::Hi", SDTI8UnaryOp>; -/* For branch conditions */ -def SDT_PIC16Branch : SDTypeProfile<0, 3, [SDTCisVT<0, OtherVT>, - SDTCisVT<1,i8>, SDTCisVT<2,i8>]>; +// The MTHI and MTLO nodes are used only to match them in the incoming +// DAG for replacement by corresponding set_fsrhi, set_fsrlo insntructions. +// These nodes are not used for defining any instructions. +def MTLO : SDNode<"PIC16ISD::MTLO", SDTI8UnaryOp>; +def MTHI : SDNode<"PIC16ISD::MTHI", SDTI8UnaryOp>; -def PIC16Branch : SDNode<"PIC16ISD::Branch",SDT_PIC16Branch, - [SDNPHasChain, SDNPInFlag]>; +// Node to generate Bank Select for a GlobalAddress. +def Banksel : SDNode<"PIC16ISD::Banksel", SDTI8UnaryOp>; -def PIC16BTFSS : SDNode<"PIC16ISD::BTFSS",SDT_PIC16Branch, - [SDNPHasChain, SDNPInFlag]>; +// Node to match a direct store operation. +def PIC16Store : SDNode<"PIC16ISD::PIC16Store", SDT_PIC16Store, [SDNPHasChain]>; -def PIC16BTFSC : SDNode<"PIC16ISD::BTFSC",SDT_PIC16Branch, - [SDNPHasChain, SDNPInFlag]>; +// Node to match a direct load operation. +def PIC16Load : SDNode<"PIC16ISD::PIC16Load", SDT_PIC16Load, [SDNPHasChain]>; -class InstrBitTestCC op, string instr_asm,SDNode OpNode>: - BitFormat< op, - (outs), - (ins brtarget:$target ,so_imm:$i, STATUSRegs:$s ), - !strconcat(instr_asm, " $s, $i, $target"), - [(OpNode bb:$target, so_imm:$i, STATUSRegs:$s )]>; +//===----------------------------------------------------------------------===// +// PIC16 Operand Definitions. +//===----------------------------------------------------------------------===// +def i8mem : Operand; -def BTFSS : InstrBitTestCC<0x1,"btfss",PIC16BTFSS>; -def BTFSC : InstrBitTestCC<0x1,"btfsc",PIC16BTFSC>; //===----------------------------------------------------------------------===// -// Pseudo instructions +// PIC16 Instructions. //===----------------------------------------------------------------------===// +include "PIC16InstrFormats.td" -let Defs = [STKPTR], Uses = [STKPTR] in { -def ADJCALLSTACKDOWN : Pseudo<255, (outs), (ins i8imm:$amt), - "!ADJCALLSTACKDOWN $amt", - [(callseq_start imm:$amt)]>; -def ADJCALLSTACKUP : Pseudo<254, (outs), (ins i8imm:$amt), - "!ADJCALLSTACKUP $amt", - [(callseq_end imm:$amt)]>; +// Pseudo-instructions. +def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i8imm:$amt), + "!ADJCALLSTACKDOWN $amt", + [(PIC16callseq_start imm:$amt)]>; + +def ADJCALLSTACKUP : Pseudo<(outs), (ins i8imm:$amt), + "!ADJCALLSTACKUP $amt", + [(PIC16callseq_end imm:$amt)]>; + +//----------------------------------- +// Vaious movlw insn patterns. +//----------------------------------- +let isReMaterializable = 1 in { +// Move 8-bit literal to W. +def movlw : BitFormat<12, (outs GPR:$dst), (ins i8imm:$src), + "movlw $src", + [(set GPR:$dst, (i8 imm:$src))]>; + +// Move a Lo(TGA) to W. +def movlw_lo : BitFormat<12, (outs GPR:$dst), (ins i8imm:$src), + "movlw LOW(${src})", + [(set GPR:$dst, (PIC16Lo tglobaladdr:$src))]>; + +// Move a Hi(TGA) to W. +def movlw_hi : BitFormat<12, (outs GPR:$dst), (ins i8imm:$src), + "movlw HIGH(${src})", + [(set GPR:$dst, (PIC16Hi tglobaladdr:$src))]>; } +//------------------- +// FSR setting insns. +//------------------- +// These insns are matched via a DAG replacement pattern. +def set_fsrlo: + ByteFormat<0, (outs FSR16:$fsr), + (ins GPR:$val), + "movwf ${fsr}L", + []>; + +let isTwoAddress = 1 in +def set_fsrhi: + ByteFormat<0, (outs FSR16:$dst), + (ins FSR16:$src, GPR:$val), + "movwf ${dst}H", + []>; + +def copy_fsr: + Pseudo<(outs FSR16:$dst), (ins FSR16:$src), "copy_fsr $dst, $src", []>; + +//-------------------------- +// Store to memory +//------------------------- +// Direct store. +def movwf : + ByteFormat<0, (outs), + (ins GPR:$val, i8imm:$offset, i8mem:$ptrlo, i8imm:$ptrhi), + "movwf ${ptrlo} + ${offset}", + [(PIC16Store GPR:$val, tglobaladdr:$ptrlo, (i8 imm:$ptrhi), + (i8 imm:$offset))]>; + +def movwf_1 : + ByteFormat<0, (outs), + (ins GPR:$val, i8mem:$ptrlo, i8imm:$ptrhi, i8imm:$offset), + "movwf ${ptrlo} + ${offset}", + [(PIC16Store GPR:$val, texternalsym:$ptrlo, (i8 imm:$ptrhi), + (i8 imm:$offset))]>; + +// Indirect store. Matched via a DAG replacement pattern. +def store_indirect : + ByteFormat<0, (outs), + (ins GPR:$val, FSR16:$fsr, i8imm:$offset), + "movwi $offset[$fsr]", + []>; + +//---------------------------- +// Load from memory +//---------------------------- +// Direct load. +def movf : + ByteFormat<0, (outs GPR:$dst), + (ins i8imm:$offset, i8mem:$ptrlo, i8imm:$ptrhi), + "movf ${ptrlo} + ${offset}, W", + [(set GPR:$dst, + (PIC16Load tglobaladdr:$ptrlo, (i8 imm:$ptrhi), + (i8 imm:$offset)))]>; + +def movf_1 : + ByteFormat<0, (outs GPR:$dst), + (ins i8mem:$ptrlo, i8imm:$ptrhi, i8imm:$offset), + "movf ${ptrlo} + ${offset}, W", + [(set GPR:$dst, + (PIC16Load texternalsym:$ptrlo, (i8 imm:$ptrhi), + (i8 imm:$offset)))]>; + +// Indirect load. Matched via a DAG replacement pattern. +def load_indirect : + ByteFormat<0, (outs GPR:$dst), + (ins FSR16:$fsr, i8imm:$offset), + "moviw $offset[$fsr]", + []>; + +//------------------------- +// Various add/sub patterns. +//------------------------- +// W += [F] ; load from F and add the value to W. +class ADDFW OpCode, string OpcStr, SDNode OpNode>: + ByteFormat; +// let isTwoAddress = 1 in { +def addfw_1: ADDFW<0, "addwf", add>; +def addfw_2: ADDFW<0, "addwf", addc>; +def addfwc: ADDFW<0, "addwfc", adde>; // With Carry. +// } + +// [F] += W ; add the value of W to [F]. +class ADDWF OpCode, string OpcStr, SDNode OpNode>: + ByteFormat; +def addwf_1: ADDWF<0, "addwf", add>; +def addwf_2: ADDWF<0, "addwf", addc>; +def addwfc: ADDWF<0, "addwfc", adde>; // With Carry. + +// W -= [F] ; load from F and sub the value from W. +class SUBFW OpCode, string OpcStr, SDNode OpNode>: + ByteFormat; +//let isTwoAddress = 1 in { +def subfw_1: SUBFW<0, "subwf", sub>; +def subfw_2: SUBFW<0, "subwf", subc>; +def subfwb: SUBFW<0, "subwfb", sube>; // With Borrow. +//} + +// [F] -= W ; +class SUBWF OpCode, string OpcStr, SDNode OpNode>: + ByteFormat; + +def subwf_1: SUBWF<0, "subwf", sub>; +def subwf_2: SUBWF<0, "subwf", subc>; +def subwfb: SUBWF<0, "subwfb", sube>; // With Borrow. + +// addlw +// W += C ; add literal to W. (Without carry). May Produce a carry. +class ADDLW opcode, string OpcStr, SDNode OpNode> : + LiteralFormat; + +// let isTwoAddress = 1 in { +def addlw_1 : ADDLW<0, "addlw", add>; +def addlw_2 : ADDLW<0, "addlw", addc>; +def addlwc : ADDLW<0, "addlwc", adde>; // With Carry. (Assembler macro). +//} + +// sublw +// W = C - W ; sub W from literal. (Without borrow). +class SUBLW opcode, SDNode OpNode> : + LiteralFormat; + +//let isTwoAddress = 1 in { +def sublw_1 : SUBLW<0, sub>; +def sublw_2 : SUBLW<0, subc>; +//} + +// Banksel. +let isReMaterializable = 1 in { +def banksel : + Pseudo<(outs BSR:$dst), + (ins i8mem:$ptr), + "banksel $ptr", + [(set BSR:$dst, (Banksel tglobaladdr:$ptr))]>; +} + +// Return insn. +def Return : + ControlFormat<0, (outs), (ins), "return", [(ret)]>; + +//===----------------------------------------------------------------------===// +// PIC16 Replacment Patterns. +//===----------------------------------------------------------------------===// + +// Identify an indirect store and select insns for it. +def : Pat<(PIC16Store GPR:$val, (MTLO GPR:$loaddr), (MTHI GPR:$hiaddr), + imm:$offset), + (store_indirect GPR:$val, + (set_fsrhi (set_fsrlo GPR:$loaddr), GPR:$hiaddr), + imm:$offset)>; + +// Identify an indirect load and select insns for it. +def : Pat<(PIC16Load (MTLO GPR:$loaddr), (MTHI GPR:$hiaddr), + imm:$offset), + (load_indirect (set_fsrhi (set_fsrlo GPR:$loaddr), GPR:$hiaddr), + imm:$offset)>; -//===----------------------------------------------------------------------===// -// Arbitrary patterns that map to one or more instructions -//===----------------------------------------------------------------------===// -def : Pat<(ret), (RETURN)>; Modified: llvm/trunk/lib/Target/PIC16/PIC16RegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16RegisterInfo.cpp?rev=59617&r1=59616&r2=59617&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16RegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/PIC16/PIC16RegisterInfo.cpp Wed Nov 19 05:00:54 2008 @@ -15,206 +15,68 @@ #include "PIC16.h" #include "PIC16RegisterInfo.h" -#include "llvm/Constants.h" -#include "llvm/Function.h" -#include "llvm/Type.h" #include "llvm/ADT/BitVector.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/CodeGen/MachineFrameInfo.h" -#include "llvm/CodeGen/MachineFunction.h" -#include "llvm/CodeGen/MachineInstrBuilder.h" -#include "llvm/CodeGen/MachineLocation.h" -#include "llvm/CodeGen/ValueTypes.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/Debug.h" -#include "llvm/Target/TargetFrameInfo.h" -#include "llvm/Target/TargetInstrInfo.h" -#include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetOptions.h" + using namespace llvm; -// FIXME: add subtarget support. -PIC16RegisterInfo::PIC16RegisterInfo(const TargetInstrInfo &tii) +PIC16RegisterInfo::PIC16RegisterInfo(const TargetInstrInfo &tii, + const PIC16Subtarget &st) : PIC16GenRegisterInfo(PIC16::ADJCALLSTACKDOWN, PIC16::ADJCALLSTACKUP), - TII(tii) {} - -/// getRegisterNumbering - Given the enum value for some register, e.g. -/// PIC16::RA, return the number that it corresponds to (e.g. 31). -unsigned PIC16RegisterInfo:: -getRegisterNumbering(unsigned RegEnum) -{ - assert (RegEnum <= 31 && "Unknown register number!"); - return RegEnum; -} + TII(tii), + ST(st) {} -void PIC16RegisterInfo:: -copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, - unsigned DestReg, unsigned SrcReg, - const TargetRegisterClass *RC) const -{ - return; -} - -void PIC16RegisterInfo::reMaterialize(MachineBasicBlock &MBB, - MachineBasicBlock::iterator I, - unsigned DestReg, - const MachineInstr *Orig) const -{ - MachineInstr *MI = MBB.getParent()->CloneMachineInstr(Orig); - MI->getOperand(0).setReg(DestReg); - MBB.insert(I, MI); -} - -MachineInstr *PIC16RegisterInfo:: -foldMemoryOperand(MachineInstr* MI, unsigned OpNum, int FI) const -{ - MachineInstr *NewMI = NULL; - return NewMI; -} - -//===----------------------------------------------------------------------===// -// -// Callee Saved Registers methods -// -//===----------------------------------------------------------------------===// +#include "PIC16GenRegisterInfo.inc" /// PIC16 Callee Saved Registers const unsigned* PIC16RegisterInfo:: -getCalleeSavedRegs(const MachineFunction *MF) const -{ - // PIC16 calle-save register range is $16-$26(s0-s7) +getCalleeSavedRegs(const MachineFunction *MF) const { static const unsigned CalleeSavedRegs[] = { 0 }; return CalleeSavedRegs; } -/// PIC16 Callee Saved Register Classes -const TargetRegisterClass* const* -PIC16RegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const -{ +// PIC16 Callee Saved Reg Classes +const TargetRegisterClass* const* +PIC16RegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const { static const TargetRegisterClass * const CalleeSavedRegClasses[] = { 0 }; return CalleeSavedRegClasses; } -BitVector PIC16RegisterInfo:: -getReservedRegs(const MachineFunction &MF) const -{ +BitVector PIC16RegisterInfo::getReservedRegs(const MachineFunction &MF) const { BitVector Reserved(getNumRegs()); return Reserved; } -//===----------------------------------------------------------------------===// -// -// Stack Frame Processing methods -// +----------------------------+ -// -// FIXME: Add stack layout description here. -// -// -//===----------------------------------------------------------------------===// - -// hasFP - Return true if the specified function should have a dedicated frame -// pointer register. This is true if the function has variable sized allocas or -// if frame pointer elimination is disabled. -bool PIC16RegisterInfo:: -hasFP(const MachineFunction &MF) const { +bool PIC16RegisterInfo::hasFP(const MachineFunction &MF) const { return false; } -// This function eliminate ADJCALLSTACKDOWN, -// ADJCALLSTACKUP pseudo instructions -void PIC16RegisterInfo:: -eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, - MachineBasicBlock::iterator I) const { - // Simply discard ADJCALLSTACKDOWN, ADJCALLSTACKUP instructions. - MBB.erase(I); -} - -// FrameIndex represent objects inside a abstract stack. -// We must replace FrameIndex with an stack/frame pointer -// direct reference. void PIC16RegisterInfo:: -eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj, - RegScavenger *RS) const -{ - MachineInstr &MI = *II; - MachineFunction &MF = *MI.getParent()->getParent(); - - unsigned i = 0; - while (!MI.getOperand(i).isFI()) { - ++i; - assert(i < MI.getNumOperands() && - "Instr doesn't have FrameIndex operand!"); - } - - int FrameIndex = MI.getOperand(i).getIndex(); - int stackSize = MF.getFrameInfo()->getStackSize(); - int spOffset = MF.getFrameInfo()->getObjectOffset(FrameIndex); - - DOUT << "\nFunction : " << MF.getFunction()->getName() << "\n"; - DOUT << "<--------->\n"; -#ifndef NDEBUG - MI.print(DOUT); -#endif - DOUT << "FrameIndex : " << FrameIndex << "\n"; - DOUT << "spOffset : " << spOffset << "\n"; - DOUT << "stackSize : " << stackSize << "\n"; - - // As explained on LowerFORMAL_ARGUMENTS, detect negative offsets - // and adjust SPOffsets considering the final stack size. - int Offset = ((spOffset < 0) ? (stackSize + (-(spOffset+4))) : (spOffset)); +eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj, + RegScavenger *RS) const +{ /* NOT YET IMPLEMENTED */ } - DOUT << "Offset : " << Offset << "\n"; - DOUT << "<--------->\n"; - - // MI.getOperand(i+1).ChangeToImmediate(Offset); - MI.getOperand(i).ChangeToRegister(getFrameRegister(MF), false); -} - -void PIC16RegisterInfo:: -emitPrologue(MachineFunction &MF) const -{ -} - -void PIC16RegisterInfo:: -emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const -{ -} +void PIC16RegisterInfo::emitPrologue(MachineFunction &MF) const +{ /* NOT YET IMPLEMENTED */ } void PIC16RegisterInfo:: -processFunctionBeforeFrameFinalized(MachineFunction &MF) const -{ -} - -unsigned PIC16RegisterInfo:: -getRARegister() const { - assert(0 && "What is the return address register"); - return 0; -} +emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const +{ /* NOT YET IMPLEMENTED */ } -unsigned PIC16RegisterInfo:: -getFrameRegister(MachineFunction &MF) const { - return PIC16::STKPTR; +int PIC16RegisterInfo:: +getDwarfRegNum(unsigned RegNum, bool isEH) const { + assert(0 && "Not keeping track of debug information yet!!"); + return -1; } -unsigned PIC16RegisterInfo:: -getEHExceptionRegister() const { - assert(0 && "What is the exception register"); +unsigned PIC16RegisterInfo::getFrameRegister(MachineFunction &MF) const { + assert(0 && "PIC16 Does not have any frame register"); return 0; } -unsigned PIC16RegisterInfo:: -getEHHandlerRegister() const { - assert(0 && "What is the exception handler register"); +unsigned PIC16RegisterInfo::getRARegister() const { + assert(0 && "PIC16 Does not have any return address register"); return 0; } -int PIC16RegisterInfo:: -getDwarfRegNum(unsigned RegNum, bool isEH) const { - assert(0 && "What is the dwarf register number"); - return -1; -} - - -#include "PIC16GenRegisterInfo.inc" Modified: llvm/trunk/lib/Target/PIC16/PIC16RegisterInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16RegisterInfo.h?rev=59617&r1=59616&r2=59617&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16RegisterInfo.h (original) +++ llvm/trunk/lib/Target/PIC16/PIC16RegisterInfo.h Wed Nov 19 05:00:54 2008 @@ -20,65 +20,43 @@ namespace llvm { // Forward Declarations. -class TargetInstrInfo; -class Type; + class PIC16Subtarget; + class TargetInstrInfo; -struct PIC16RegisterInfo : public PIC16GenRegisterInfo { - const TargetInstrInfo &TII; +class PIC16RegisterInfo : public PIC16GenRegisterInfo { + private: + const TargetInstrInfo &TII; + const PIC16Subtarget &ST; - explicit PIC16RegisterInfo(const TargetInstrInfo &tii); + public: + PIC16RegisterInfo(const TargetInstrInfo &tii, + const PIC16Subtarget &st); + + + //------------------------------------------------------ + // Pure virtual functions from TargetRegisterInfo + //------------------------------------------------------ + + // PIC16 callee saved registers + virtual const unsigned* + getCalleeSavedRegs(const MachineFunction *MF = 0) const; + + // PIC16 callee saved register classes + virtual const TargetRegisterClass* const * + getCalleeSavedRegClasses(const MachineFunction *MF) const; + + virtual BitVector getReservedRegs(const MachineFunction &MF) const; + virtual bool hasFP(const MachineFunction &MF) const; + + virtual void eliminateFrameIndex(MachineBasicBlock::iterator MI, + int SPAdj, RegScavenger *RS=NULL) const; + + virtual void emitPrologue(MachineFunction &MF) const; + virtual void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const; + virtual int getDwarfRegNum(unsigned RegNum, bool isEH) const; + virtual unsigned getFrameRegister(MachineFunction &MF) const; + virtual unsigned getRARegister() const; - /// getRegisterNumbering - Given the enum value for some register, e.g. - /// PIC16::RA, return the number that it corresponds to (e.g. 31). - static unsigned getRegisterNumbering(unsigned RegEnum); - - void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - unsigned DestReg, const MachineInstr *Orig) const; - - MachineInstr* foldMemoryOperand(MachineInstr* MI, unsigned OpNum, - int FrameIndex) const; - - MachineInstr* foldMemoryOperand(MachineInstr* MI, unsigned OpNum, - MachineInstr* LoadMI) const { - return 0; - } - - void copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, - unsigned DestReg, unsigned SrcReg, - const TargetRegisterClass *RC) const; - - - const unsigned *getCalleeSavedRegs(const MachineFunction* MF = 0) const; - - const TargetRegisterClass* const* - getCalleeSavedRegClasses(const MachineFunction* MF = 0) const; - - BitVector getReservedRegs(const MachineFunction &MF) const; - - bool hasFP(const MachineFunction &MF) const; - - void eliminateCallFramePseudoInstr(MachineFunction &MF, - MachineBasicBlock &MBB, - MachineBasicBlock::iterator I) const; - - /// Stack Frame Processing Methods. - void eliminateFrameIndex(MachineBasicBlock::iterator II, - int SPAdj, RegScavenger *RS = NULL) const; - - void processFunctionBeforeFrameFinalized(MachineFunction &MF) const; - - void emitPrologue(MachineFunction &MF) const; - void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const; - - /// Debug information queries. - unsigned getRARegister() const; - unsigned getFrameRegister(MachineFunction &MF) const; - - /// Exception handling queries. - unsigned getEHExceptionRegister() const; - unsigned getEHHandlerRegister() const; - - int getDwarfRegNum(unsigned RegNum, bool isEH) const; }; } // end namespace llvm Modified: llvm/trunk/lib/Target/PIC16/PIC16RegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16RegisterInfo.td?rev=59617&r1=59616&r2=59617&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16RegisterInfo.td (original) +++ llvm/trunk/lib/Target/PIC16/PIC16RegisterInfo.td Wed Nov 19 05:00:54 2008 @@ -11,74 +11,22 @@ // Declarations that describe the PIC16 register file //===----------------------------------------------------------------------===// -// We have banks of 32 registers each. class PIC16Reg : Register { - field bits<5> Num; let Namespace = "PIC16"; } -// PIC16 CPU Registers -class PIC16GPRReg num, string n> : PIC16Reg { - let Num = num; -} - -// CPU GPR Registers -def FSR0 : PIC16GPRReg< 0, "FSR0">, DwarfRegNum<[0]>; -def FSR1 : PIC16GPRReg< 1, "FSR1">, DwarfRegNum<[1]>; - -// CPU Registers Class -def PTRRegs : RegisterClass<"PIC16", [i16], 8, - [FSR0, FSR1]> -{ - let MethodProtos = [{ - iterator allocation_order_end(const MachineFunction &MF) const; - }]; - let MethodBodies = [{ - PTRRegsClass::iterator - PTRRegsClass::allocation_order_end(const MachineFunction &MF) const { - return end(); - } - }]; -} +// PIC16 Registers. +def W : PIC16Reg<"W">; +def FSR0 : PIC16Reg<"FSR0">; +def FSR1 : PIC16Reg<"FSR1">; +def BS : PIC16Reg<"BS">; + +def STATUS : PIC16Reg<"STATUS">; + +// PIC16 Register classes. +def GPR : RegisterClass<"PIC16", [i8], 8, [W]>; +def FSR16 : RegisterClass<"PIC16", [i16], 8, [FSR0, FSR1]>; +def BSR : RegisterClass<"PIC16", [i8], 8, [BS]>; -def WREG : PIC16GPRReg< 0, "WREG">, DwarfRegNum<[0]>; +def STATUSR: RegisterClass<"PIC16", [i8], 8, [STATUS]>; -// CPU Registers Class -def CPURegs : RegisterClass<"PIC16", [i8], 8, - [WREG]> -{ - let MethodProtos = [{ - iterator allocation_order_end(const MachineFunction &MF) const; - }]; - let MethodBodies = [{ - CPURegsClass::iterator - CPURegsClass::allocation_order_end(const MachineFunction &MF) const { - return end(); - } - }]; -} - -def STATUSREG : PIC16GPRReg<2, "STATUS">, DwarfRegNum<[0]>; - -// STATUS Registers Class -def STATUSRegs : RegisterClass<"PIC16", [i8], 8, - [STATUSREG]>; - - -// Dummy stack pointer. -def STKPTR : PIC16GPRReg< 0, "SP">, DwarfRegNum<[0]>; - -// CPU Registers Class -def STKRegs : RegisterClass<"PIC16", [i8], 8, - [STKPTR]> -{ - let MethodProtos = [{ - iterator allocation_order_end(const MachineFunction &MF) const; - }]; - let MethodBodies = [{ - STKRegsClass::iterator - STKRegsClass::allocation_order_end(const MachineFunction &MF) const { - return end(); - } - }]; -} Modified: llvm/trunk/lib/Target/PIC16/PIC16Subtarget.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16Subtarget.cpp?rev=59617&r1=59616&r2=59617&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16Subtarget.cpp (original) +++ llvm/trunk/lib/Target/PIC16/PIC16Subtarget.cpp Wed Nov 19 05:00:54 2008 @@ -11,14 +11,14 @@ // //===----------------------------------------------------------------------===// -#include "PIC16.h" #include "PIC16Subtarget.h" #include "PIC16GenSubtarget.inc" + using namespace llvm; -PIC16Subtarget::PIC16Subtarget(const TargetMachine &TM, const Module &M, - const std::string &FS) - :IsPIC16Old(false) +PIC16Subtarget::PIC16Subtarget(const Module &M, const std::string &FS, + bool Cooper) + :IsCooper(Cooper) { std::string CPU = "generic"; Modified: llvm/trunk/lib/Target/PIC16/PIC16Subtarget.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16Subtarget.h?rev=59617&r1=59616&r2=59617&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16Subtarget.h (original) +++ llvm/trunk/lib/Target/PIC16/PIC16Subtarget.h Wed Nov 19 05:00:54 2008 @@ -14,7 +14,6 @@ #ifndef PIC16SUBTARGET_H #define PIC16SUBTARGET_H -#include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetSubtarget.h" #include @@ -23,19 +22,23 @@ class Module; class PIC16Subtarget : public TargetSubtarget { - bool IsPIC16Old; + + // IsCooper - Target ISA is Cooper. + bool IsCooper; public: /// This constructor initializes the data members to match that /// of the specified module. /// - PIC16Subtarget(const TargetMachine &TM, const Module &M, - const std::string &FS); + PIC16Subtarget(const Module &M, const std::string &FS, bool Cooper); + /// isCooper - Returns true if the target ISA is Cooper. + bool isCooper() const { return IsCooper; } + /// ParseSubtargetFeatures - Parses features string setting specified /// subtarget options. Definition of function is auto generated by tblgen. void ParseSubtargetFeatures(const std::string &FS, const std::string &CPU); }; } // End llvm namespace -#endif +#endif // PIC16SUBTARGET_H Modified: llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.cpp?rev=59617&r1=59616&r2=59617&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.cpp (original) +++ llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.cpp Wed Nov 19 05:00:54 2008 @@ -17,11 +17,15 @@ using namespace llvm; PIC16TargetAsmInfo:: -PIC16TargetAsmInfo(const PIC16TargetMachine &TM) +PIC16TargetAsmInfo(const PIC16TargetMachine &TM) : TargetAsmInfo(TM) { - Data16bitsDirective = "\t.half\t"; - Data32bitsDirective = "\t.word\t"; CommentString = ";"; - COMMDirective = "\t"; - COMMDirectiveTakesAlignment = 0; + Data8bitsDirective = " db "; + Data16bitsDirective = " db "; + Data32bitsDirective = " db "; + DataSectionStartSuffix = " IDATA "; + UDataSectionStartSuffix = " UDATA "; + TextSectionStartSuffix = " CODE "; + RomDataSectionStartSuffix = " ROMDATA "; + ZeroDirective = NULL; } Modified: llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.h?rev=59617&r1=59616&r2=59617&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.h (original) +++ llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.h Wed Nov 19 05:00:54 2008 @@ -23,6 +23,17 @@ struct PIC16TargetAsmInfo : public TargetAsmInfo { PIC16TargetAsmInfo(const PIC16TargetMachine &TM); + const char *UDataSectionStartSuffix; + const char *RomDataSectionStartSuffix; + public : + const char *getUDataSectionStartSuffix() const { + return UDataSectionStartSuffix; + } + const char *getRomDataSectionStartSuffix() const { + return RomDataSectionStartSuffix; + } + + }; } // namespace llvm Modified: llvm/trunk/lib/Target/PIC16/PIC16TargetMachine.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16TargetMachine.cpp?rev=59617&r1=59616&r2=59617&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16TargetMachine.cpp (original) +++ llvm/trunk/lib/Target/PIC16/PIC16TargetMachine.cpp Wed Nov 19 05:00:54 2008 @@ -16,6 +16,7 @@ #include "PIC16TargetMachine.h" #include "llvm/Module.h" #include "llvm/PassManager.h" +#include "llvm/CodeGen/Passes.h" #include "llvm/Target/TargetAsmInfo.h" #include "llvm/Target/TargetMachineRegistry.h" @@ -29,50 +30,42 @@ extern "C" int PIC16TargetMachineModule; int PIC16TargetMachineModule = 0; -namespace { - // Register the targets - RegisterTarget X("pic16", "PIC16 14-bit [experimental]"); -} -PIC16TargetMachine:: -PIC16TargetMachine(const Module &M, const std::string &FS) : - Subtarget(*this, M, FS), DataLayout("e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8"), +// Register the targets +static RegisterTarget +X("pic16", "PIC16 14-bit (experimental)."); +static RegisterTarget +Y("cooper", "PIC16 Cooper (experimental)."); + +// PIC16TargetMachine - Traditional PIC16 Machine. +PIC16TargetMachine::PIC16TargetMachine(const Module &M, const std::string &FS, + bool Cooper) +: Subtarget(M, FS, Cooper), + DataLayout("e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8"), InstrInfo(*this), TLInfo(*this), FrameInfo(TargetFrameInfo::StackGrowsUp, 8, 0) { } +// CooperTargetMachine - Uses the same PIC16TargetMachine, but makes IsCooper +// as true. +CooperTargetMachine::CooperTargetMachine(const Module &M, const std::string &FS) + : PIC16TargetMachine(M, FS, true) {} + -const TargetAsmInfo *PIC16TargetMachine::createTargetAsmInfo() const -{ +const TargetAsmInfo *PIC16TargetMachine::createTargetAsmInfo() const { return new PIC16TargetAsmInfo(*this); } -//===----------------------------------------------------------------------===// -// Pass Pipeline Configuration -//===----------------------------------------------------------------------===// - -bool PIC16TargetMachine::addInstSelector(PassManagerBase &PM, bool Fast) -{ +bool PIC16TargetMachine::addInstSelector(PassManagerBase &PM, bool Fast) { // Install an instruction selector. PM.add(createPIC16ISelDag(*this)); return false; } bool PIC16TargetMachine:: -addPrologEpilogInserter(PassManagerBase &PM, bool Fast) -{ - return false; -} - -bool PIC16TargetMachine::addPreEmitPass(PassManagerBase &PM, bool Fast) -{ - return true; -} - -bool PIC16TargetMachine:: -addAssemblyEmitter(PassManagerBase &PM, bool Fast, raw_ostream &Out) -{ +addAssemblyEmitter(PassManagerBase &PM, bool Fast, raw_ostream &Out) { // Output assembly language. PM.add(createPIC16CodePrinterPass(Out, *this)); return false; } + Modified: llvm/trunk/lib/Target/PIC16/PIC16TargetMachine.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16TargetMachine.h?rev=59617&r1=59616&r2=59617&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16TargetMachine.h (original) +++ llvm/trunk/lib/Target/PIC16/PIC16TargetMachine.h Wed Nov 19 05:00:54 2008 @@ -17,6 +17,7 @@ #include "PIC16InstrInfo.h" #include "PIC16ISelLowering.h" +#include "PIC16RegisterInfo.h" #include "PIC16Subtarget.h" #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetFrameInfo.h" @@ -31,31 +32,42 @@ const TargetData DataLayout; // Calculates type size & alignment PIC16InstrInfo InstrInfo; PIC16TargetLowering TLInfo; + + // PIC16 does not have any call stack frame, therefore not having + // any PIC16 specific FrameInfo class. TargetFrameInfo FrameInfo; protected: virtual const TargetAsmInfo *createTargetAsmInfo() const; - + public: - PIC16TargetMachine(const Module &M, const std::string &FS); + PIC16TargetMachine(const Module &M, const std::string &FS, + bool Cooper = false); + + virtual const TargetFrameInfo *getFrameInfo() const { return &FrameInfo; } + virtual const PIC16InstrInfo *getInstrInfo() const { return &InstrInfo; } + virtual const TargetData *getTargetData() const { return &DataLayout;} + virtual const PIC16Subtarget *getSubtargetImpl() const { return &Subtarget; } + + virtual const PIC16RegisterInfo *getRegisterInfo() const { + return &(InstrInfo.getRegisterInfo()); + } + + virtual PIC16TargetLowering *getTargetLowering() const { + return const_cast(&TLInfo); + } - virtual const TargetFrameInfo *getFrameInfo() const - { return &FrameInfo; } - virtual const PIC16InstrInfo *getInstrInfo() const - { return &InstrInfo; } - virtual const TargetData *getTargetData() const - { return &DataLayout; } - virtual PIC16TargetLowering *getTargetLowering() const - { return const_cast(&TLInfo); } - virtual const PIC16RegisterInfo *getRegisterInfo() const - { return &InstrInfo.getRegisterInfo(); } - virtual bool addInstSelector(PassManagerBase &PM, bool Fast); - virtual bool addPrologEpilogInserter(PassManagerBase &PM, bool Fast); - virtual bool addPreEmitPass(PassManagerBase &PM, bool Fast); - virtual bool addAssemblyEmitter(PassManagerBase &PM, bool Fast, + virtual bool addAssemblyEmitter(PassManagerBase &PM, bool Fast, raw_ostream &Out); -}; +}; // PIC16TargetMachine. + +/// CooperTargetMachine +class CooperTargetMachine : public PIC16TargetMachine { +public: + CooperTargetMachine(const Module &M, const std::string &FS); +}; // CooperTargetMachine. + } // end namespace llvm #endif From sanjiv.gupta at microchip.com Wed Nov 19 05:11:09 2008 From: sanjiv.gupta at microchip.com (sanjiv gupta) Date: Wed, 19 Nov 2008 16:41:09 +0530 Subject: [llvm-commits] Patch to allow custom lowering of ADDC/ADDE/SUBC/SUBE in legal types. Message-ID: <1227093070.4357.7.camel@idc-lt-i00171.microchip.com> Let me know if it is ok to commit. Thanks, - Sanjiv -------------- next part -------------- A non-text attachment was scrubbed... Name: patch-LegalizeDAG.cpp Type: text/x-patch Size: 2443 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20081119/2946d6da/attachment.bin From sanjiv.gupta at microchip.com Wed Nov 19 05:28:00 2008 From: sanjiv.gupta at microchip.com (Sanjiv Gupta) Date: Wed, 19 Nov 2008 11:28:00 -0000 Subject: [llvm-commits] [llvm] r59621 - in /llvm/trunk/lib/Target/PIC16: PIC16InstrInfo.cpp PIC16InstrInfo.h Message-ID: <200811191128.mAJBS0vv027923@zion.cs.uiuc.edu> Author: sgupta Date: Wed Nov 19 05:27:59 2008 New Revision: 59621 URL: http://llvm.org/viewvc/llvm-project?rev=59621&view=rev Log: Fixed build warnings. Modified: llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.cpp llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.h Modified: llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.cpp?rev=59621&r1=59620&r2=59621&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.cpp (original) +++ llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.cpp Wed Nov 19 05:27:59 2008 @@ -36,7 +36,7 @@ /// the source reg along with the FrameIndex of the loaded stack slot. /// If not, return 0. This predicate must return 0 if the instruction has /// any side effects other than storing to the stack slot. -unsigned PIC16InstrInfo::isStoreToStackSlot(MachineInstr *MI, +unsigned PIC16InstrInfo::isStoreToStackSlot(const MachineInstr *MI, int &FrameIndex) const { if (MI->getOpcode() == PIC16::movwf && MI->getOperand(0).isReg() @@ -52,7 +52,7 @@ /// the dest reg along with the FrameIndex of the stack slot. /// If not, return 0. This predicate must return 0 if the instruction has /// any side effects other than storing to the stack slot. -unsigned PIC16InstrInfo::isLoadFromStackSlot(MachineInstr *MI, +unsigned PIC16InstrInfo::isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const { if (MI->getOpcode() == PIC16::movf && MI->getOperand(0).isReg() Modified: llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.h?rev=59621&r1=59620&r2=59621&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.h (original) +++ llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.h Wed Nov 19 05:27:59 2008 @@ -35,14 +35,16 @@ /// the destination along with the FrameIndex of the loaded stack slot. If /// not, return 0. This predicate must return 0 if the instruction has /// any side effects other than loading from the stack slot. - virtual unsigned isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const; + virtual unsigned isLoadFromStackSlot(const MachineInstr *MI, + int &FrameIndex) const; /// isStoreToStackSlot - If the specified machine instruction is a direct /// store to a stack slot, return the virtual or physical register number of /// the source reg along with the FrameIndex of the loaded stack slot. If /// not, return 0. This predicate must return 0 if the instruction has /// any side effects other than storing to the stack slot. - virtual unsigned isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const; + virtual unsigned isStoreToStackSlot(const MachineInstr *MI, + int &FrameIndex) const; virtual void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, From sanjiv.gupta at microchip.com Wed Nov 19 06:12:50 2008 From: sanjiv.gupta at microchip.com (Sanjiv Gupta) Date: Wed, 19 Nov 2008 12:12:50 -0000 Subject: [llvm-commits] [llvm] r59623 - /llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.h Message-ID: <200811191212.mAJCCoNn030145@zion.cs.uiuc.edu> Author: sgupta Date: Wed Nov 19 06:12:49 2008 New Revision: 59623 URL: http://llvm.org/viewvc/llvm-project?rev=59623&view=rev Log: Forgot to add this in the previous commit. Added: llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.h Added: llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.h?rev=59623&view=auto ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.h (added) +++ llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.h Wed Nov 19 06:12:49 2008 @@ -0,0 +1,62 @@ +//===-- PIC16AsmPrinter.h - PIC16 LLVM assembly writer ------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains a printer that converts from our internal representation +// of machine-dependent LLVM code to PIC16 assembly language. +// +//===----------------------------------------------------------------------===// + +#ifndef PIC16ASMPRINTER_H +#define PIC16ASMPRINTER_H + +#include "PIC16.h" +#include "PIC16TargetMachine.h" +#include "llvm/CodeGen/AsmPrinter.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Target/TargetAsmInfo.h" +#include "llvm/Target/TargetMachine.h" + +namespace llvm { + struct VISIBILITY_HIDDEN PIC16AsmPrinter : public AsmPrinter { + PIC16AsmPrinter(raw_ostream &O, TargetMachine &TM, const TargetAsmInfo *T) + : AsmPrinter(O, TM, T) { + CurrentBankselLabelInBasicBlock = ""; + IsRomData = false; + } + private : + virtual const char *getPassName() const { + return "PIC16 Assembly Printer"; + } + + bool runOnMachineFunction(MachineFunction &F); + void printOperand(const MachineInstr *MI, int opNum); + void SwitchToUDataSection(const char *NewSection, + const GlobalValue *GV = NULL); + void SwitchToRomDataSection(const char *NewSection, + const GlobalValue *GV = NULL); + bool printInstruction(const MachineInstr *MI); // definition autogenerated. + bool printMachineInstruction(const MachineInstr *MI); + void EmitInitData (Module &M); + void EmitUnInitData (Module &M); + void EmitRomData (Module &M); + virtual void EmitConstantValueOnly(const Constant *CV); + void emitFunctionData(MachineFunction &MF); + void emitFunctionTempData(MachineFunction &MF); + + protected: + bool doInitialization(Module &M); + bool doFinalization(Module &M); + + private: + std::string CurrentBankselLabelInBasicBlock; + bool IsRomData; + }; +} // end of namespace + +#endif From akyrtzi at gmail.com Wed Nov 19 06:56:21 2008 From: akyrtzi at gmail.com (Argiris Kirtzidis) Date: Wed, 19 Nov 2008 12:56:21 -0000 Subject: [llvm-commits] [llvm] r59629 - /llvm/trunk/lib/CodeGen/RegAllocPBQP.cpp Message-ID: <200811191256.mAJCuM8o031723@zion.cs.uiuc.edu> Author: akirtzidis Date: Wed Nov 19 06:56:21 2008 New Revision: 59629 URL: http://llvm.org/viewvc/llvm-project?rev=59629&view=rev Log: Fix compilation error on MSVC. Modified: llvm/trunk/lib/CodeGen/RegAllocPBQP.cpp Modified: llvm/trunk/lib/CodeGen/RegAllocPBQP.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocPBQP.cpp?rev=59629&r1=59628&r2=59629&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/RegAllocPBQP.cpp (original) +++ llvm/trunk/lib/CodeGen/RegAllocPBQP.cpp Wed Nov 19 06:56:21 2008 @@ -731,7 +731,7 @@ typedef LiveInterval::Ranges::const_iterator LRIterator; // First allocate registers for the empty intervals. - for (LiveIntervalSet::iterator + for (LiveIntervalSet::const_iterator itr = emptyVRegIntervals.begin(), end = emptyVRegIntervals.end(); itr != end; ++itr) { LiveInterval *li = *itr; From scottm at aero.org Wed Nov 19 09:24:17 2008 From: scottm at aero.org (Scott Michel) Date: Wed, 19 Nov 2008 15:24:17 -0000 Subject: [llvm-commits] [llvm] r59637 - /llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp Message-ID: <200811191524.mAJFOHTD004992@zion.cs.uiuc.edu> Author: pingbak Date: Wed Nov 19 09:24:16 2008 New Revision: 59637 URL: http://llvm.org/viewvc/llvm-project?rev=59637&view=rev Log: Temporary check-in for Duncan to demonstrate CellSPU store problem. Modified: llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp Modified: llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp?rev=59637&r1=59636&r2=59637&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp (original) +++ llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp Wed Nov 19 09:24:16 2008 @@ -131,6 +131,7 @@ addRegisterClass(MVT::i128, SPU::GPRCRegisterClass); // SPU has no sign or zero extended loads for i1, i8, i16: +#if 0 setLoadExtAction(ISD::EXTLOAD, MVT::i1, Promote); setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote); setLoadExtAction(ISD::ZEXTLOAD, MVT::i1, Promote); @@ -139,6 +140,11 @@ setTruncStoreAction(MVT::i32, MVT::i1, Custom); setTruncStoreAction(MVT::i64, MVT::i1, Custom); setTruncStoreAction(MVT::i128, MVT::i1, Custom); +#else + setLoadExtAction(ISD::EXTLOAD, MVT::i1, Promote); + setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote); + setTruncStoreAction(MVT::i8, MVT::i1, Promote); +#endif setLoadExtAction(ISD::EXTLOAD, MVT::i8, Custom); setLoadExtAction(ISD::SEXTLOAD, MVT::i8, Custom); @@ -702,11 +708,12 @@ // The vector type we really want to load from the 16-byte chunk, except // in the case of MVT::i1, which has to be v16i8. - MVT vecVT, stVecVT = MVT::v16i8; + MVT vecVT = MVT::v16i8, stVecVT = MVT::v16i8; - if (StVT != MVT::i1) + if (StVT != MVT::i1) { stVecVT = MVT::getVectorVT(StVT, (128 / StVT.getSizeInBits())); - vecVT = MVT::getVectorVT(VT, (128 / VT.getSizeInBits())); + vecVT = MVT::getVectorVT(VT, (128 / VT.getSizeInBits())); + } SDValue alignLoadVec = AlignedLoad(Op, DAG, ST, SN, alignment, @@ -733,7 +740,6 @@ SDValue insertEltOffs = DAG.getConstant(chunk_offset, PtrVT); SDValue insertEltPtr; - SDValue insertEltOp; // If the base pointer is already a D-form address, then just create // a new D-form address with a slot offset and the orignal base pointer. @@ -751,16 +757,43 @@ insertEltPtr = DAG.getNode(ISD::ADD, PtrVT, basePtr, insertEltOffs); } - insertEltOp = DAG.getNode(SPUISD::INSERT_MASK, stVecVT, insertEltPtr); - result = DAG.getNode(SPUISD::SHUFB, vecVT, - DAG.getNode(ISD::SCALAR_TO_VECTOR, vecVT, theValue), - alignLoadVec, + SDValue insertEltOp = + DAG.getNode(SPUISD::INSERT_MASK, stVecVT, insertEltPtr); + SDValue vectorizeOp; + +#if 0 + if (VT == MVT::i1 || StVT != VT) { + MVT toVT = (VT != MVT::i1) ? VT : MVT::i8; + if (toVT.bitsGT(VT)) { + vectorizeOp = DAG.getNode(ISD::ANY_EXTEND, toVT, theValue); + } else if (StVT.bitsLT(VT)) { + vectorizeOp = DAG.getNode(ISD::TRUNCATE, toVT, theValue); + } + + vectorizeOp = DAG.getNode(ISD::SCALAR_TO_VECTOR, vecVT, vectorizeOp); + } else +#endif + vectorizeOp = DAG.getNode(ISD::SCALAR_TO_VECTOR, vecVT, theValue); + + result = DAG.getNode(SPUISD::SHUFB, vecVT, vectorizeOp, alignLoadVec, DAG.getNode(ISD::BIT_CONVERT, vecVT, insertEltOp)); result = DAG.getStore(the_chain, result, basePtr, LN->getSrcValue(), LN->getSrcValueOffset(), LN->isVolatile(), LN->getAlignment()); +#ifndef NDEBUG + if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) { + const SDValue ¤tRoot = DAG.getRoot(); + + DAG.setRoot(result); + cerr << "------- CellSPU:LowerStore result:\n"; + DAG.dump(); + cerr << "-------\n"; + DAG.setRoot(currentRoot); + } +#endif + return result; /*UNREACHED*/ } From baldrick at free.fr Wed Nov 19 09:39:18 2008 From: baldrick at free.fr (Duncan Sands) Date: Wed, 19 Nov 2008 16:39:18 +0100 Subject: [llvm-commits] [llvm] r59637 - /llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp In-Reply-To: <200811191524.mAJFOHTD004992@zion.cs.uiuc.edu> References: <200811191524.mAJFOHTD004992@zion.cs.uiuc.edu> Message-ID: <200811191639.18549.baldrick@free.fr> Hi Scott, > Temporary check-in for Duncan to demonstrate CellSPU store problem. with the SPU patch I just sent in, everything seems to work fine both with and without this change you committed. Ciao, Duncan. From anton at korobeynikov.info Wed Nov 19 09:51:32 2008 From: anton at korobeynikov.info (Anton Korobeynikov) Date: Wed, 19 Nov 2008 18:51:32 +0300 Subject: [llvm-commits] [llvm] r59617 - in /llvm/trunk/lib/Target/PIC16: PIC16.h PIC16.td PIC16AsmPrinter.cpp PIC16CallingConv.td PIC16ConstantPoolValue.cpp PIC16ConstantPoolValue.h PIC16ISelDAGToDAG.cpp PIC16ISelDAGToDAG.h PIC16ISelLowering.cpp PIC16ISelLowering.h PIC16InstrFormats.td PIC16InstrInfo.cpp PIC16InstrInfo.h PIC16InstrInfo.td PIC16RegisterInfo.cpp PIC16RegisterInfo.h PIC16RegisterInfo.td PIC16Subtarget.cpp PIC16Subtarget.h PIC16TargetAsmInfo.cpp PIC16TargetAsmInfo.h PIC16TargetMachine.cpp PIC16TargetMachine.h In-Reply-To: <200811191100.mAJB0xC0026723@zion.cs.uiuc.edu> References: <200811191100.mAJB0xC0026723@zion.cs.uiuc.edu> Message-ID: <1227109892.15024.258.camel@aslstation.lan> Hello, Sanjiv > + SwitchToTextSection (codeSection.c_str(),F); This really looks like a step back.... And I think we even talked about the issue. In fact SwitchTo{Text,Data}Section routines are obsolete and will be removed, when I will have time to work on asmprinters again. And PIC backend is the only backend, which uses them currently... In practice we don't have pure 'data' or 'text' sections, we usually tend to separate different flavours of code and data and use different sections for them. It's really inefficient to have separate printing routine for each new kind of section, even more - when the difference between them is only 1 suffix. There are at least two pretty straightforward ways to handle PIC section printing problem: 1. Handle suffixes as section flags. Look, how ELFTagetAsmInfo handles this stuff. 2. Make a step upper and introduce a generic "section printing" function, which will know how to print sections of different kinds for specific target and use this as a fallback solution for PIC. -- With best regards, Anton Korobeynikov. Faculty of Mathematics & Mechanics, Saint Petersburg State University. From gohman at apple.com Wed Nov 19 10:02:22 2008 From: gohman at apple.com (Dan Gohman) Date: Wed, 19 Nov 2008 16:02:22 -0000 Subject: [llvm-commits] [llvm] r59640 - /llvm/trunk/test/CodeGen/Generic/2008-07-29-EHLabel.ll Message-ID: <200811191602.mAJG2MbV006716@zion.cs.uiuc.edu> Author: djg Date: Wed Nov 19 10:02:14 2008 New Revision: 59640 URL: http://llvm.org/viewvc/llvm-project?rev=59640&view=rev Log: Use %llvmgcc -xassembler instead of invoking as directly. This avoids problems for example when LLVM is built with --with-extra-options=-m64 and as defaults to x86-32 mode. Modified: llvm/trunk/test/CodeGen/Generic/2008-07-29-EHLabel.ll Modified: llvm/trunk/test/CodeGen/Generic/2008-07-29-EHLabel.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Generic/2008-07-29-EHLabel.ll?rev=59640&r1=59639&r2=59640&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/Generic/2008-07-29-EHLabel.ll (original) +++ llvm/trunk/test/CodeGen/Generic/2008-07-29-EHLabel.ll Wed Nov 19 10:02:14 2008 @@ -1,4 +1,4 @@ -; RUN: llvm-as < %s | llc -o - | as -o /dev/null +; RUN: llvm-as < %s | llc -o - | %llvmgcc -xassembler -c -o /dev/null - ; PR2609 %struct..0._11 = type { i32 } %struct..1__pthread_mutex_s = type { i32, i32, i32, i32, i32, %struct..0._11 } From gohman at apple.com Wed Nov 19 10:24:47 2008 From: gohman at apple.com (Dan Gohman) Date: Wed, 19 Nov 2008 16:24:47 -0000 Subject: [llvm-commits] [llvm] r59641 - /llvm/trunk/test/CodeGen/Generic/2008-07-29-EHLabel.ll Message-ID: <200811191624.mAJGOmAX007795@zion.cs.uiuc.edu> Author: djg Date: Wed Nov 19 10:24:37 2008 New Revision: 59641 URL: http://llvm.org/viewvc/llvm-project?rev=59641&view=rev Log: Revert r59640. It broke this test for builds that aren't configured with llvm-gcc. Modified: llvm/trunk/test/CodeGen/Generic/2008-07-29-EHLabel.ll Modified: llvm/trunk/test/CodeGen/Generic/2008-07-29-EHLabel.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Generic/2008-07-29-EHLabel.ll?rev=59641&r1=59640&r2=59641&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/Generic/2008-07-29-EHLabel.ll (original) +++ llvm/trunk/test/CodeGen/Generic/2008-07-29-EHLabel.ll Wed Nov 19 10:24:37 2008 @@ -1,4 +1,4 @@ -; RUN: llvm-as < %s | llc -o - | %llvmgcc -xassembler -c -o /dev/null - +; RUN: llvm-as < %s | llc -o - | as -o /dev/null ; PR2609 %struct..0._11 = type { i32 } %struct..1__pthread_mutex_s = type { i32, i32, i32, i32, i32, %struct..0._11 } From alenhar2 at cs.uiuc.edu Wed Nov 19 11:00:09 2008 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Wed, 19 Nov 2008 17:00:09 -0000 Subject: [llvm-commits] [llvm] r59642 - /llvm/trunk/tools/llvm-ld/llvm-ld.cpp Message-ID: <200811191700.mAJH09hf009289@zion.cs.uiuc.edu> Author: alenhar2 Date: Wed Nov 19 11:00:08 2008 New Revision: 59642 URL: http://llvm.org/viewvc/llvm-project?rev=59642&view=rev Log: ignore the -m elf_i386 directive used in the linux kernel Modified: llvm/trunk/tools/llvm-ld/llvm-ld.cpp Modified: llvm/trunk/tools/llvm-ld/llvm-ld.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-ld/llvm-ld.cpp?rev=59642&r1=59641&r2=59642&view=diff ============================================================================== --- llvm/trunk/tools/llvm-ld/llvm-ld.cpp (original) +++ llvm/trunk/tools/llvm-ld/llvm-ld.cpp Wed Nov 19 11:00:08 2008 @@ -108,6 +108,9 @@ static cl::opt CO8("end-group", cl::Hidden, cl::desc("Compatibility option: ignored")); +static cl::opt CO9("m", cl::Hidden, + cl::desc("Compatibility option: ignored")); + /// This is just for convenience so it doesn't have to be passed around /// everywhere. static std::string progname; From stuart at apple.com Wed Nov 19 11:19:35 2008 From: stuart at apple.com (Stuart Hastings) Date: Wed, 19 Nov 2008 17:19:35 -0000 Subject: [llvm-commits] [llvm] r59644 - /llvm/trunk/lib/Target/X86/X86RegisterInfo.td Message-ID: <200811191719.mAJHJZw8009948@zion.cs.uiuc.edu> Author: stuart Date: Wed Nov 19 11:19:35 2008 New Revision: 59644 URL: http://llvm.org/viewvc/llvm-project?rev=59644&view=rev Log: Discourage (allocate last) use of x86_64 R12 and R13 due to their longer instruction encodings. Modified: llvm/trunk/lib/Target/X86/X86RegisterInfo.td Modified: llvm/trunk/lib/Target/X86/X86RegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86RegisterInfo.td?rev=59644&r1=59643&r2=59644&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86RegisterInfo.td (original) +++ llvm/trunk/lib/Target/X86/X86RegisterInfo.td Wed Nov 19 11:19:35 2008 @@ -226,10 +226,12 @@ // R12, R13, R14, and R15 for X86-64) are callee-save registers. // In 64-mode, there are 12 additional i8 registers, SIL, DIL, BPL, SPL, and // R8B, ... R15B. +// Allocate R12 and R13 last, as these require an extra byte when +// encoded in x86_64 instructions. // FIXME: Allow AH, CH, DH, BH in 64-mode for non-REX instructions, def GR8 : RegisterClass<"X86", [i8], 8, [AL, CL, DL, BL, AH, CH, DH, BH, SIL, DIL, BPL, SPL, - R8B, R9B, R10B, R11B, R12B, R13B, R14B, R15B]> { + R8B, R9B, R10B, R11B, R14B, R15B, R12B, R13B]> { let MethodProtos = [{ iterator allocation_order_begin(const MachineFunction &MF) const; iterator allocation_order_end(const MachineFunction &MF) const; @@ -240,12 +242,12 @@ static const unsigned X86_GR8_AO_64_fp[] = {X86::AL, X86::CL, X86::DL, X86::SIL, X86::DIL, X86::R8B, X86::R9B, X86::R10B, X86::R11B, - X86::BL, X86::R12B, X86::R13B, X86::R14B, X86::R15B}; + X86::BL, X86::R14B, X86::R15B, X86::R12B, X86::R13B}; // If not, just don't allocate SPL. static const unsigned X86_GR8_AO_64[] = {X86::AL, X86::CL, X86::DL, X86::SIL, X86::DIL, X86::R8B, X86::R9B, X86::R10B, X86::R11B, - X86::BL, X86::R12B, X86::R13B, X86::R14B, X86::R15B, X86::BPL}; + X86::BL, X86::R14B, X86::R15B, X86::R12B, X86::R13B, X86::BPL}; // In 32-mode, none of the 8-bit registers aliases EBP or ESP. static const unsigned X86_GR8_AO_32[] = {X86::AL, X86::CL, X86::DL, X86::AH, X86::CH, X86::DH, X86::BL, X86::BH}; @@ -281,7 +283,7 @@ def GR16 : RegisterClass<"X86", [i16], 16, [AX, CX, DX, SI, DI, BX, BP, SP, - R8W, R9W, R10W, R11W, R12W, R13W, R14W, R15W]> { + R8W, R9W, R10W, R11W, R14W, R15W, R12W, R13W]> { let SubRegClassList = [GR8]; let MethodProtos = [{ iterator allocation_order_begin(const MachineFunction &MF) const; @@ -293,14 +295,14 @@ static const unsigned X86_GR16_AO_64_fp[] = {X86::AX, X86::CX, X86::DX, X86::SI, X86::DI, X86::R8W, X86::R9W, X86::R10W, X86::R11W, - X86::BX, X86::R12W, X86::R13W, X86::R14W, X86::R15W}; + X86::BX, X86::R14W, X86::R15W, X86::R12W, X86::R13W}; static const unsigned X86_GR16_AO_32_fp[] = {X86::AX, X86::CX, X86::DX, X86::SI, X86::DI, X86::BX}; // If not, just don't allocate SPL. static const unsigned X86_GR16_AO_64[] = {X86::AX, X86::CX, X86::DX, X86::SI, X86::DI, X86::R8W, X86::R9W, X86::R10W, X86::R11W, - X86::BX, X86::R12W, X86::R13W, X86::R14W, X86::R15W, X86::BP}; + X86::BX, X86::R14W, X86::R15W, X86::R12W, X86::R13W, X86::BP}; static const unsigned X86_GR16_AO_32[] = {X86::AX, X86::CX, X86::DX, X86::SI, X86::DI, X86::BX, X86::BP}; @@ -345,7 +347,7 @@ def GR32 : RegisterClass<"X86", [i32], 32, [EAX, ECX, EDX, ESI, EDI, EBX, EBP, ESP, - R8D, R9D, R10D, R11D, R12D, R13D, R14D, R15D]> { + R8D, R9D, R10D, R11D, R14D, R15D, R12D, R13D]> { let SubRegClassList = [GR8, GR16]; let MethodProtos = [{ iterator allocation_order_begin(const MachineFunction &MF) const; @@ -357,14 +359,14 @@ static const unsigned X86_GR32_AO_64_fp[] = {X86::EAX, X86::ECX, X86::EDX, X86::ESI, X86::EDI, X86::R8D, X86::R9D, X86::R10D, X86::R11D, - X86::EBX, X86::R12D, X86::R13D, X86::R14D, X86::R15D}; + X86::EBX, X86::R14D, X86::R15D, X86::R12D, X86::R13D}; static const unsigned X86_GR32_AO_32_fp[] = {X86::EAX, X86::ECX, X86::EDX, X86::ESI, X86::EDI, X86::EBX}; // If not, just don't allocate SPL. static const unsigned X86_GR32_AO_64[] = {X86::EAX, X86::ECX, X86::EDX, X86::ESI, X86::EDI, X86::R8D, X86::R9D, X86::R10D, X86::R11D, - X86::EBX, X86::R12D, X86::R13D, X86::R14D, X86::R15D, X86::EBP}; + X86::EBX, X86::R14D, X86::R15D, X86::R12D, X86::R13D, X86::EBP}; static const unsigned X86_GR32_AO_32[] = {X86::EAX, X86::ECX, X86::EDX, X86::ESI, X86::EDI, X86::EBX, X86::EBP}; @@ -409,7 +411,7 @@ def GR64 : RegisterClass<"X86", [i64], 64, [RAX, RCX, RDX, RSI, RDI, R8, R9, R10, R11, - RBX, R12, R13, R14, R15, RBP, RSP]> { + RBX, R14, R15, R12, R13, RBP, RSP]> { let SubRegClassList = [GR8, GR16, GR32]; let MethodProtos = [{ iterator allocation_order_end(const MachineFunction &MF) const; From evan.cheng at apple.com Wed Nov 19 11:44:04 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 19 Nov 2008 09:44:04 -0800 Subject: [llvm-commits] [llvm] r59528 - in /llvm/trunk: lib/Analysis/ScalarEvolution.cpp test/Analysis/ScalarEvolution/2008-11-18-LessThanOrEqual.ll test/Analysis/ScalarEvolution/2008-11-18-Stride1.ll test/Analysis/ScalarEvolution/2008-11-18-Stride2.ll In-Reply-To: <49238A20.3010803@mxc.ca> References: <200811181510.mAIFAtVS001882@zion.cs.uiuc.edu> <4C90C36A-77D6-4006-9F3F-19002F2E561A@apple.com> <49238A20.3010803@mxc.ca> Message-ID: <520D57A2-6CB1-48F1-B5DB-9523121F3058@apple.com> On Nov 18, 2008, at 7:38 PM, Nick Lewycky wrote: > Evan Cheng wrote: >> Hi Nicholas, >> >> What does "trueWhenEqual" mean? Should it default to true / false? > > Like isSigned, it defines whether the comparison is true when equal, > ie., it's an SLT/ULT vs. SLE/ULE. There is no default, but the old > version only knew how to handle trueWhenEqual=false (ie., SLT/ULT). Can you make the default false? That way old code that use it (which may not be part of the tree) won't have to change. Thanks, Evan > > > Nick > >> Thanks, >> >> Evan >> >> On Nov 18, 2008, at 7:10 AM, Nick Lewycky wrote: >> >>> Author: nicholas >>> Date: Tue Nov 18 09:10:54 2008 >>> New Revision: 59528 >>> >>> URL: http://llvm.org/viewvc/llvm-project?rev=59528&view=rev >>> Log: >>> Add a utility function that detects whether a loop is guaranteed to >>> be finite. >>> >>> Use it to safely handle less-than-or-equals-to exit conditions in >>> loops. These >>> also occur when the loop exit branch is exit on true because SCEV >>> inverses the >>> icmp predicate. >>> >>> Use it again to handle non-zero strides, but only with an unsigned >>> comparison >>> in the exit condition. >>> >>> Added: >>> llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18- >>> LessThanOrEqual.ll >>> llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride1.ll >>> llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride2.ll >>> Modified: >>> llvm/trunk/lib/Analysis/ScalarEvolution.cpp >>> >>> Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp >>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=59528&r1=59527&r2=59528&view=diff >>> >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> ==================================================================== >>> --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original) >>> +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Tue Nov 18 09:10:54 >>> 2008 >>> @@ -1477,7 +1477,7 @@ >>> /// specified less-than comparison will execute. If not >>> computable, return >>> /// UnknownValue. isSigned specifies whether the less-than is >>> signed. >>> SCEVHandle HowManyLessThans(SCEV *LHS, SCEV *RHS, const Loop *L, >>> - bool isSigned); >>> + bool isSigned, bool trueWhenEqual); >>> >>> /// getPredecessorWithUniqueSuccessorForBB - Return a >>> predecessor of BB >>> /// (which may not be an immediate predecessor) which has >>> exactly one >>> @@ -1487,7 +1487,13 @@ >>> >>> /// executesAtLeastOnce - Test whether entry to the loop is >>> protected by >>> /// a conditional between LHS and RHS. >>> - bool executesAtLeastOnce(const Loop *L, bool isSigned, SCEV >>> *LHS, SCEV *RHS); >>> + bool executesAtLeastOnce(const Loop *L, bool isSigned, bool >>> trueWhenEqual, >>> + SCEV *LHS, SCEV *RHS); >>> + >>> + /// potentialInfiniteLoop - Test whether the loop might jump >>> over the exit value >>> + /// due to wrapping. >>> + bool potentialInfiniteLoop(SCEV *Stride, SCEV *RHS, bool >>> isSigned, >>> + bool trueWhenEqual); >>> >>> /// getConstantEvolutionLoopExitValue - If we know that the >>> specified Phi is >>> /// in the header of its containing loop, we know the loop >>> executes a >>> @@ -2025,24 +2031,46 @@ >>> break; >>> } >>> case ICmpInst::ICMP_SLT: { >>> - SCEVHandle TC = HowManyLessThans(LHS, RHS, L, true); >>> + SCEVHandle TC = HowManyLessThans(LHS, RHS, L, true, false); >>> if (!isa(TC)) return TC; >>> break; >>> } >>> case ICmpInst::ICMP_SGT: { >>> SCEVHandle TC = HowManyLessThans(SE.getNotSCEV(LHS), >>> - SE.getNotSCEV(RHS), L, true); >>> + SE.getNotSCEV(RHS), L, true, >>> false); >>> if (!isa(TC)) return TC; >>> break; >>> } >>> case ICmpInst::ICMP_ULT: { >>> - SCEVHandle TC = HowManyLessThans(LHS, RHS, L, false); >>> + SCEVHandle TC = HowManyLessThans(LHS, RHS, L, false, false); >>> if (!isa(TC)) return TC; >>> break; >>> } >>> case ICmpInst::ICMP_UGT: { >>> SCEVHandle TC = HowManyLessThans(SE.getNotSCEV(LHS), >>> - SE.getNotSCEV(RHS), L, false); >>> + SE.getNotSCEV(RHS), L, false, >>> false); >>> + if (!isa(TC)) return TC; >>> + break; >>> + } >>> + case ICmpInst::ICMP_SLE: { >>> + SCEVHandle TC = HowManyLessThans(LHS, RHS, L, true, true); >>> + if (!isa(TC)) return TC; >>> + break; >>> + } >>> + case ICmpInst::ICMP_SGE: { >>> + SCEVHandle TC = HowManyLessThans(SE.getNotSCEV(LHS), >>> + SE.getNotSCEV(RHS), L, true, >>> true); >>> + if (!isa(TC)) return TC; >>> + break; >>> + } >>> + case ICmpInst::ICMP_ULE: { >>> + SCEVHandle TC = HowManyLessThans(LHS, RHS, L, false, true); >>> + if (!isa(TC)) return TC; >>> + break; >>> + } >>> + case ICmpInst::ICMP_UGE: { >>> + SCEVHandle TC = HowManyLessThans(SE.getNotSCEV(LHS), >>> + SE.getNotSCEV(RHS), L, false, >>> true); >>> if (!isa(TC)) return TC; >>> break; >>> } >>> @@ -2738,6 +2766,7 @@ >>> /// executesAtLeastOnce - Test whether entry to the loop is >>> protected by >>> /// a conditional between LHS and RHS. >>> bool ScalarEvolutionsImpl::executesAtLeastOnce(const Loop *L, bool >>> isSigned, >>> + bool trueWhenEqual, >>> SCEV *LHS, SCEV >>> *RHS) { >>> BasicBlock *Preheader = L->getLoopPreheader(); >>> BasicBlock *PreheaderDest = L->getHeader(); >>> @@ -2770,20 +2799,36 @@ >>> >>> switch (Cond) { >>> case ICmpInst::ICMP_UGT: >>> - if (isSigned) continue; >>> + if (isSigned || trueWhenEqual) continue; >>> std::swap(PreCondLHS, PreCondRHS); >>> Cond = ICmpInst::ICMP_ULT; >>> break; >>> case ICmpInst::ICMP_SGT: >>> - if (!isSigned) continue; >>> + if (!isSigned || trueWhenEqual) continue; >>> std::swap(PreCondLHS, PreCondRHS); >>> Cond = ICmpInst::ICMP_SLT; >>> break; >>> case ICmpInst::ICMP_ULT: >>> - if (isSigned) continue; >>> + if (isSigned || trueWhenEqual) continue; >>> break; >>> case ICmpInst::ICMP_SLT: >>> - if (!isSigned) continue; >>> + if (!isSigned || trueWhenEqual) continue; >>> + break; >>> + case ICmpInst::ICMP_UGE: >>> + if (isSigned || !trueWhenEqual) continue; >>> + std::swap(PreCondLHS, PreCondRHS); >>> + Cond = ICmpInst::ICMP_ULE; >>> + break; >>> + case ICmpInst::ICMP_SGE: >>> + if (!isSigned || !trueWhenEqual) continue; >>> + std::swap(PreCondLHS, PreCondRHS); >>> + Cond = ICmpInst::ICMP_SLE; >>> + break; >>> + case ICmpInst::ICMP_ULE: >>> + if (isSigned || !trueWhenEqual) continue; >>> + break; >>> + case ICmpInst::ICMP_SLE: >>> + if (!isSigned || !trueWhenEqual) continue; >>> break; >>> default: >>> continue; >>> @@ -2802,11 +2847,46 @@ >>> return false; >>> } >>> >>> +/// potentialInfiniteLoop - Test whether the loop might jump over >>> the exit value >>> +/// due to wrapping around 2^n. >>> +bool ScalarEvolutionsImpl::potentialInfiniteLoop(SCEV *Stride, SCEV >>> *RHS, >>> + bool isSigned, >>> bool trueWhenEqual) { >>> + // Return true when the distance from RHS to maxint > Stride. >>> + >>> + if (!isa(Stride)) >>> + return true; >>> + SCEVConstant *SC = cast(Stride); >>> + >>> + if (SC->getValue()->isZero()) >>> + return true; >>> + if (!trueWhenEqual && SC->getValue()->isOne()) >>> + return false; >>> + >>> + if (!isa(RHS)) >>> + return true; >>> + SCEVConstant *R = cast(RHS); >>> + >>> + if (isSigned) >>> + return true; // XXX: because we don't have an sdiv scev. >>> + >>> + // If negative, it wraps around every iteration, but we don't >>> care about that. >>> + APInt S = SC->getValue()->getValue().abs(); >>> + >>> + APInt Dist = APInt::getMaxValue(R->getValue()->getBitWidth()) - >>> + R->getValue()->getValue(); >>> + >>> + if (trueWhenEqual) >>> + return !S.ult(Dist); >>> + else >>> + return !S.ule(Dist); >>> +} >>> + >>> /// HowManyLessThans - Return the number of times a backedge >>> containing the >>> /// specified less-than comparison will execute. If not computable, >>> return >>> /// UnknownValue. >>> SCEVHandle ScalarEvolutionsImpl:: >>> -HowManyLessThans(SCEV *LHS, SCEV *RHS, const Loop *L, bool >>> isSigned) { >>> +HowManyLessThans(SCEV *LHS, SCEV *RHS, const Loop *L, >>> + bool isSigned, bool trueWhenEqual) { >>> // Only handle: "ADDREC < LoopInvariant". >>> if (!RHS->isLoopInvariant(L)) return UnknownValue; >>> >>> @@ -2815,34 +2895,50 @@ >>> return UnknownValue; >>> >>> if (AddRec->isAffine()) { >>> - // FORNOW: We only support unit strides. >>> - SCEVHandle One = SE.getIntegerSCEV(1, RHS->getType()); >>> - if (AddRec->getOperand(1) != One) >>> + SCEVHandle Stride = AddRec->getOperand(1); >>> + if (potentialInfiniteLoop(Stride, RHS, isSigned, >>> trueWhenEqual)) >>> return UnknownValue; >>> >>> - // We know the LHS is of the form {n,+,1} and the RHS is some >>> loop-invariant >>> - // m. So, we count the number of iterations in which {n,+,1} < >>> m is true. >>> - // Note that we cannot simply return max(m-n,0) because it's >>> not safe to >>> + // We know the LHS is of the form {n,+,s} and the RHS is some >>> loop-invariant >>> + // m. So, we count the number of iterations in which {n,+,s} < >>> m is true. >>> + // Note that we cannot simply return max(m-n,0)/s because it's >>> not safe to >>> // treat m-n as signed nor unsigned due to overflow possibility. >>> >>> // First, we get the value of the LHS in the first iteration: n >>> SCEVHandle Start = AddRec->getOperand(0); >>> >>> - if (executesAtLeastOnce(L, isSigned, >>> - SE.getMinusSCEV(AddRec->getOperand(0), >>> One), RHS)) { >>> - // Since we know that the condition is true in order to enter >>> the loop, >>> - // we know that it will run exactly m-n times. >>> - return SE.getMinusSCEV(RHS, Start); >>> - } else { >>> - // Then, we get the value of the LHS in the first iteration >>> in which the >>> - // above condition doesn't hold. This equals to max(m,n). >>> - SCEVHandle End = isSigned ? SE.getSMaxExpr(RHS, Start) >>> - : SE.getUMaxExpr(RHS, Start); >>> - >>> - // Finally, we subtract these two values to get the number of >>> times the >>> - // backedge is executed: max(m,n)-n. >>> - return SE.getMinusSCEV(End, Start); >>> + SCEVHandle One = SE.getIntegerSCEV(1, RHS->getType()); >>> + >>> + // Assuming that the loop will run at least once, we know that >>> it will >>> + // run (m-n)/s times. >>> + SCEVHandle End = RHS; >>> + >>> + if (!executesAtLeastOnce(L, isSigned, trueWhenEqual, >>> + SE.getMinusSCEV(Start, One), RHS)) { >>> + // If not, we get the value of the LHS in the first iteration >>> in which >>> + // the above condition doesn't hold. This equals to >>> max(m,n). >>> + End = isSigned ? SE.getSMaxExpr(RHS, Start) >>> + : SE.getUMaxExpr(RHS, Start); >>> } >>> + >>> + // If the expression is less-than-or-equal to, we need to >>> extend the >>> + // loop by one iteration. >>> + // >>> + // The loop won't actually run (m-n)/s times because the loop >>> iterations >>> + // won't divide evenly. For example, if you have {2,+,5} u< 10 >>> the >>> + // division would equal one, but the loop runs twice putting >>> the >>> + // induction variable at 12. >>> + >>> + if (!trueWhenEqual) >>> + // (Stride - 1) is correct only because we know it's >>> unsigned. >>> + // What we really want is to decrease the magnitude of Stride >>> by one. >>> + Start = SE.getMinusSCEV(Start, SE.getMinusSCEV(Stride, One)); >>> + else >>> + Start = SE.getMinusSCEV(Start, Stride); >>> + >>> + // Finally, we subtract these two values to get the number of >>> times the >>> + // backedge is executed: max(m,n)-n. >>> + return SE.getUDivExpr(SE.getMinusSCEV(End, Start), Stride); >>> } >>> >>> return UnknownValue; >>> >>> Added: llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18- >>> LessThanOrEqual.ll >>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-LessThanOrEqual.ll?rev=59528&view=auto >>> >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> ==================================================================== >>> --- llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18- >>> LessThanOrEqual.ll (added) >>> +++ llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18- >>> LessThanOrEqual.ll Tue Nov 18 09:10:54 2008 >>> @@ -0,0 +1,31 @@ >>> +; RUN: llvm-as < %s | opt -analyze -scalar-evolution |& \ >>> +; RUN: grep {Loop bb: (7 + (-1 \\* %argc)) iterations!} >>> + >>> +define i32 @main(i32 %argc, i8** %argv) nounwind { >>> +entry: >>> + %0 = icmp ugt i32 %argc, 7 ; [#uses=1] >>> + br i1 %0, label %bb2, label %bb.nph >>> + >>> +bb.nph: ; preds = %entry >>> + br label %bb >>> + >>> +bb: ; preds = %bb.nph, %bb1 >>> + %indvar = phi i32 [ 0, %bb.nph ], [ %indvar.next, %bb1 ] ; >>> [#uses=2] >>> + %argc_addr.04 = add i32 %indvar, %argc ; [#uses=1] >>> + tail call void (...)* @Test() nounwind >>> + %1 = add i32 %argc_addr.04, 1 ; [#uses=1] >>> + br label %bb1 >>> + >>> +bb1: ; preds = %bb >>> + %phitmp = icmp ugt i32 %1, 7 ; [#uses=1] >>> + %indvar.next = add i32 %indvar, 1 ; [#uses=1] >>> + br i1 %phitmp, label %bb1.bb2_crit_edge, label %bb >>> + >>> +bb1.bb2_crit_edge: ; preds = %bb1 >>> + br label %bb2 >>> + >>> +bb2: ; preds = %bb1.bb2_crit_edge, %entry >>> + ret i32 0 >>> +} >>> + >>> +declare void @Test(...) >>> >>> Added: llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18- >>> Stride1.ll >>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride1.ll?rev=59528&view=auto >>> >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> ==================================================================== >>> --- llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride1.ll >>> (added) >>> +++ llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride1.ll >>> Tue Nov 18 09:10:54 2008 >>> @@ -0,0 +1,30 @@ >>> +; RUN: llvm-as < %s | opt -analyze -scalar-evolution |& grep {/u 3} >>> + >>> +define i32 @f(i32 %x) nounwind readnone { >>> +entry: >>> + %0 = icmp ugt i32 %x, 4 ; [#uses=1] >>> + br i1 %0, label %bb.nph, label %bb2 >>> + >>> +bb.nph: ; preds = %entry >>> + br label %bb >>> + >>> +bb: ; preds = %bb.nph, %bb1 >>> + %indvar = phi i32 [ 0, %bb.nph ], [ %indvar.next, %bb1 ] ; >>> [#uses=2] >>> + %tmp = mul i32 %indvar, -3 ; [#uses=1] >>> + %x_addr.04 = add i32 %tmp, %x ; [#uses=1] >>> + %1 = add i32 %x_addr.04, -3 ; [#uses=2] >>> + br label %bb1 >>> + >>> +bb1: ; preds = %bb >>> + %2 = icmp ugt i32 %1, 4 ; [#uses=1] >>> + %indvar.next = add i32 %indvar, 1 ; [#uses=1] >>> + br i1 %2, label %bb, label %bb1.bb2_crit_edge >>> + >>> +bb1.bb2_crit_edge: ; preds = %bb1 >>> + %.lcssa = phi i32 [ %1, %bb1 ] ; [#uses=1] >>> + br label %bb2 >>> + >>> +bb2: ; preds = %bb1.bb2_crit_edge, %entry >>> + %x_addr.0.lcssa = phi i32 [ %.lcssa, %bb1.bb2_crit_edge ], [ %x, >>> %entry ] ; [#uses=1] >>> + ret i32 %x_addr.0.lcssa >>> +} >>> >>> Added: llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18- >>> Stride2.ll >>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride2.ll?rev=59528&view=auto >>> >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> ==================================================================== >>> --- llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride2.ll >>> (added) >>> +++ llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride2.ll >>> Tue Nov 18 09:10:54 2008 >>> @@ -0,0 +1,30 @@ >>> +; RUN: llvm-as < %s | opt -analyze -scalar-evolution |& grep {/u 3} >>> + >>> +define i32 @f(i32 %x) nounwind readnone { >>> +entry: >>> + %0 = icmp ugt i32 %x, 999 ; [#uses=1] >>> + br i1 %0, label %bb2, label %bb.nph >>> + >>> +bb.nph: ; preds = %entry >>> + br label %bb >>> + >>> +bb: ; preds = %bb.nph, %bb1 >>> + %indvar = phi i32 [ 0, %bb.nph ], [ %indvar.next, %bb1 ] ; >>> [#uses=2] >>> + %tmp = mul i32 %indvar, 3 ; [#uses=1] >>> + %x_addr.04 = add i32 %tmp, %x ; [#uses=1] >>> + %1 = add i32 %x_addr.04, 3 ; [#uses=2] >>> + br label %bb1 >>> + >>> +bb1: ; preds = %bb >>> + %2 = icmp ugt i32 %1, 999 ; [#uses=1] >>> + %indvar.next = add i32 %indvar, 1 ; [#uses=1] >>> + br i1 %2, label %bb1.bb2_crit_edge, label %bb >>> + >>> +bb1.bb2_crit_edge: ; preds = %bb1 >>> + %.lcssa = phi i32 [ %1, %bb1 ] ; [#uses=1] >>> + br label %bb2 >>> + >>> +bb2: ; preds = %bb1.bb2_crit_edge, %entry >>> + %x_addr.0.lcssa = phi i32 [ %.lcssa, %bb1.bb2_crit_edge ], [ %x, >>> %entry ] ; [#uses=1] >>> + ret i32 %x_addr.0.lcssa >>> +} >>> >>> >>> _______________________________________________ >>> llvm-commits mailing list >>> llvm-commits at cs.uiuc.edu >>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits >> > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From scottm at aero.org Wed Nov 19 11:45:08 2008 From: scottm at aero.org (Scott Michel) Date: Wed, 19 Nov 2008 17:45:08 -0000 Subject: [llvm-commits] [llvm] r59648 - /llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp Message-ID: <200811191745.mAJHj80C010882@zion.cs.uiuc.edu> Author: pingbak Date: Wed Nov 19 11:45:08 2008 New Revision: 59648 URL: http://llvm.org/viewvc/llvm-project?rev=59648&view=rev Log: CellSPU: Do not custom lower i1 stores, rely on type legalization to do the right thing and promote the store to i8. Modified: llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp Modified: llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp?rev=59648&r1=59647&r2=59648&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp (original) +++ llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp Wed Nov 19 11:45:08 2008 @@ -131,20 +131,14 @@ addRegisterClass(MVT::i128, SPU::GPRCRegisterClass); // SPU has no sign or zero extended loads for i1, i8, i16: -#if 0 setLoadExtAction(ISD::EXTLOAD, MVT::i1, Promote); setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote); setLoadExtAction(ISD::ZEXTLOAD, MVT::i1, Promote); - setTruncStoreAction(MVT::i8, MVT::i1, Custom); - setTruncStoreAction(MVT::i16, MVT::i1, Custom); - setTruncStoreAction(MVT::i32, MVT::i1, Custom); - setTruncStoreAction(MVT::i64, MVT::i1, Custom); - setTruncStoreAction(MVT::i128, MVT::i1, Custom); -#else - setLoadExtAction(ISD::EXTLOAD, MVT::i1, Promote); - setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote); - setTruncStoreAction(MVT::i8, MVT::i1, Promote); -#endif + setTruncStoreAction(MVT::i8, MVT::i1, Promote); + setTruncStoreAction(MVT::i16 , MVT::i1, Custom); + setTruncStoreAction(MVT::i32 , MVT::i1, Custom); + setTruncStoreAction(MVT::i64 , MVT::i1, Custom); + setTruncStoreAction(MVT::i128, MVT::i1, Custom); setLoadExtAction(ISD::EXTLOAD, MVT::i8, Custom); setLoadExtAction(ISD::SEXTLOAD, MVT::i8, Custom); @@ -165,7 +159,7 @@ setOperationAction(ISD::ConstantFP, MVT::f64, Custom); // SPU's loads and stores have to be custom lowered: - for (unsigned sctype = (unsigned) MVT::i1; sctype < (unsigned) MVT::f128; + for (unsigned sctype = (unsigned) MVT::i8; sctype < (unsigned) MVT::f128; ++sctype) { MVT VT = (MVT::SimpleValueType)sctype; @@ -708,12 +702,8 @@ // The vector type we really want to load from the 16-byte chunk, except // in the case of MVT::i1, which has to be v16i8. - MVT vecVT = MVT::v16i8, stVecVT = MVT::v16i8; - - if (StVT != MVT::i1) { - stVecVT = MVT::getVectorVT(StVT, (128 / StVT.getSizeInBits())); - vecVT = MVT::getVectorVT(VT, (128 / VT.getSizeInBits())); - } + MVT vecVT = MVT::getVectorVT(VT, (128 / VT.getSizeInBits())), + stVecVT = MVT::getVectorVT(StVT, (128 / StVT.getSizeInBits())); SDValue alignLoadVec = AlignedLoad(Op, DAG, ST, SN, alignment, @@ -759,21 +749,8 @@ SDValue insertEltOp = DAG.getNode(SPUISD::INSERT_MASK, stVecVT, insertEltPtr); - SDValue vectorizeOp; - -#if 0 - if (VT == MVT::i1 || StVT != VT) { - MVT toVT = (VT != MVT::i1) ? VT : MVT::i8; - if (toVT.bitsGT(VT)) { - vectorizeOp = DAG.getNode(ISD::ANY_EXTEND, toVT, theValue); - } else if (StVT.bitsLT(VT)) { - vectorizeOp = DAG.getNode(ISD::TRUNCATE, toVT, theValue); - } - - vectorizeOp = DAG.getNode(ISD::SCALAR_TO_VECTOR, vecVT, vectorizeOp); - } else -#endif - vectorizeOp = DAG.getNode(ISD::SCALAR_TO_VECTOR, vecVT, theValue); + SDValue vectorizeOp = + DAG.getNode(ISD::SCALAR_TO_VECTOR, vecVT, theValue); result = DAG.getNode(SPUISD::SHUFB, vecVT, vectorizeOp, alignLoadVec, DAG.getNode(ISD::BIT_CONVERT, vecVT, insertEltOp)); @@ -782,7 +759,7 @@ LN->getSrcValue(), LN->getSrcValueOffset(), LN->isVolatile(), LN->getAlignment()); -#ifndef NDEBUG +#if 0 && defined(NDEBUG) if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) { const SDValue ¤tRoot = DAG.getRoot(); From dalej at apple.com Wed Nov 19 11:48:40 2008 From: dalej at apple.com (Dale Johannesen) Date: Wed, 19 Nov 2008 17:48:40 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r59649 - /llvm-gcc-4.2/trunk/gcc/config/rs6000/rs6000.c Message-ID: <200811191748.mAJHme9P011139@zion.cs.uiuc.edu> Author: johannes Date: Wed Nov 19 11:48:39 2008 New Revision: 59649 URL: http://llvm.org/viewvc/llvm-project?rev=59649&view=rev Log: Remove nonstandard noncommented text after #endif. Modified: llvm-gcc-4.2/trunk/gcc/config/rs6000/rs6000.c Modified: llvm-gcc-4.2/trunk/gcc/config/rs6000/rs6000.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/rs6000/rs6000.c?rev=59649&r1=59648&r2=59649&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/config/rs6000/rs6000.c (original) +++ llvm-gcc-4.2/trunk/gcc/config/rs6000/rs6000.c Wed Nov 19 11:48:39 2008 @@ -20023,7 +20023,7 @@ } /* LLVM LOCAL - Disable scheduler. */ -#endif ENABLE_LLVM +#endif /* ENABLE_LLVM */ /* Length in units of the trampoline for entering a nested function. */ From clattner at apple.com Wed Nov 19 11:52:05 2008 From: clattner at apple.com (Chris Lattner) Date: Wed, 19 Nov 2008 09:52:05 -0800 Subject: [llvm-commits] [llvm] r59612 - /llvm/trunk/include/llvm/Intrinsics.td In-Reply-To: <200811190850.mAJ8oJY4015533@zion.cs.uiuc.edu> References: <200811190850.mAJ8oJY4015533@zion.cs.uiuc.edu> Message-ID: <6DCEFC35-FD82-4F89-B1AB-6434042D1B10@apple.com> On Nov 19, 2008, at 12:50 AM, Sanjiv Gupta wrote: > Author: sgupta > Date: Wed Nov 19 02:50:17 2008 > New Revision: 59612 > > URL: http://llvm.org/viewvc/llvm-project?rev=59612&view=rev > Log: > Int type for PIC16 is i16. Added i16 intrinsics for memmove, memcpy > and memset. hi Sangiv, The alignment argument should always be an i32. Note that the i64 version uses an i32 for the alignment. It would also be better to just go ahead and make these intrisnsics type generic on the size argument, like the ctpop intrinsics etc are. That would allow memcpy with a size of i42 if someone wanted it :) -Chris > > > Modified: > llvm/trunk/include/llvm/Intrinsics.td > > Modified: llvm/trunk/include/llvm/Intrinsics.td > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Intrinsics.td?rev=59612&r1=59611&r2=59612&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/include/llvm/Intrinsics.td (original) > +++ llvm/trunk/include/llvm/Intrinsics.td Wed Nov 19 02:50:17 2008 > @@ -190,18 +190,27 @@ > // > > let Properties = [IntrWriteArgMem] in { > + def int_memcpy_i16 : Intrinsic<[llvm_void_ty], > + [llvm_ptr_ty, llvm_ptr_ty, > + llvm_i16_ty, llvm_i16_ty]>; > def int_memcpy_i32 : Intrinsic<[llvm_void_ty], > [llvm_ptr_ty, llvm_ptr_ty, > llvm_i32_ty, llvm_i32_ty]>; > def int_memcpy_i64 : Intrinsic<[llvm_void_ty], > [llvm_ptr_ty, llvm_ptr_ty, > llvm_i64_ty, llvm_i32_ty]>; > + def int_memmove_i16 : Intrinsic<[llvm_void_ty], > + [llvm_ptr_ty, llvm_ptr_ty, > + llvm_i16_ty, llvm_i16_ty]>; > def int_memmove_i32 : Intrinsic<[llvm_void_ty], > [llvm_ptr_ty, llvm_ptr_ty, > llvm_i32_ty, llvm_i32_ty]>; > def int_memmove_i64 : Intrinsic<[llvm_void_ty], > [llvm_ptr_ty, llvm_ptr_ty, > llvm_i64_ty, llvm_i32_ty]>; > + def int_memset_i16 : Intrinsic<[llvm_void_ty], > + [llvm_ptr_ty, llvm_i8_ty, > + llvm_i16_ty, llvm_i16_ty]>; > def int_memset_i32 : Intrinsic<[llvm_void_ty], > [llvm_ptr_ty, llvm_i8_ty, > llvm_i32_ty, llvm_i32_ty]>; > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From ofv at wanadoo.es Wed Nov 19 13:32:19 2008 From: ofv at wanadoo.es (Oscar Fuentes) Date: Wed, 19 Nov 2008 19:32:19 -0000 Subject: [llvm-commits] [llvm] r59662 - /llvm/trunk/lib/Transforms/Utils/CMakeLists.txt Message-ID: <200811191932.mAJJWJkY015740@zion.cs.uiuc.edu> Author: ofv Date: Wed Nov 19 13:32:19 2008 New Revision: 59662 URL: http://llvm.org/viewvc/llvm-project?rev=59662&view=rev Log: CMake: Removed source file. Modified: llvm/trunk/lib/Transforms/Utils/CMakeLists.txt Modified: llvm/trunk/lib/Transforms/Utils/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/CMakeLists.txt?rev=59662&r1=59661&r2=59662&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/CMakeLists.txt (original) +++ llvm/trunk/lib/Transforms/Utils/CMakeLists.txt Wed Nov 19 13:32:19 2008 @@ -7,7 +7,6 @@ CloneModule.cpp CloneTrace.cpp CodeExtractor.cpp - DbgInfoUtils.cpp DemoteRegToStack.cpp InlineCost.cpp InlineFunction.cpp From gohman at apple.com Wed Nov 19 15:32:05 2008 From: gohman at apple.com (Dan Gohman) Date: Wed, 19 Nov 2008 21:32:05 -0000 Subject: [llvm-commits] [llvm] r59665 - in /llvm/trunk: include/llvm/CodeGen/ScheduleDAG.h lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Message-ID: <200811192132.mAJLW56m020608@zion.cs.uiuc.edu> Author: djg Date: Wed Nov 19 15:32:03 2008 New Revision: 59665 URL: http://llvm.org/viewvc/llvm-project?rev=59665&view=rev Log: Convert SUnit's dump method into a print method and implement dump in terms of it. Modified: llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Modified: llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h?rev=59665&r1=59664&r2=59665&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h (original) +++ llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h Wed Nov 19 15:32:03 2008 @@ -242,6 +242,7 @@ void dump(const ScheduleDAG *G) const; void dumpAll(const ScheduleDAG *G) const; + void print(raw_ostream &O, const ScheduleDAG *G) const; }; //===--------------------------------------------------------------------===// Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp?rev=59665&r1=59664&r2=59665&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Wed Nov 19 15:32:03 2008 @@ -18,6 +18,7 @@ #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/raw_ostream.h" using namespace llvm; ScheduleDAG::ScheduleDAG(SelectionDAG *dag, MachineBasicBlock *bb, @@ -459,22 +460,25 @@ /// SUnit - Scheduling unit. It's an wrapper around either a single SDNode or /// a group of nodes flagged together. -void SUnit::dump(const ScheduleDAG *G) const { - cerr << "SU(" << NodeNum << "): "; +void SUnit::print(raw_ostream &O, const ScheduleDAG *G) const { + O << "SU(" << NodeNum << "): "; if (getNode()) { SmallVector FlaggedNodes; for (SDNode *N = getNode(); N; N = N->getFlaggedNode()) FlaggedNodes.push_back(N); while (!FlaggedNodes.empty()) { - cerr << " "; + O << " "; FlaggedNodes.back()->dump(G->DAG); - cerr << "\n"; + O << "\n"; FlaggedNodes.pop_back(); } } else { - cerr << "CROSS RC COPY "; + O << "CROSS RC COPY\n"; } - cerr << "\n"; +} + +void SUnit::dump(const ScheduleDAG *G) const { + print(errs(), G); } void SUnit::dumpAll(const ScheduleDAG *G) const { From gohman at apple.com Wed Nov 19 16:09:46 2008 From: gohman at apple.com (Dan Gohman) Date: Wed, 19 Nov 2008 22:09:46 -0000 Subject: [llvm-commits] [llvm] r59667 - in /llvm/trunk: include/llvm/CodeGen/ScheduleDAG.h lib/CodeGen/SelectionDAG/ScheduleDAG.cpp lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp Message-ID: <200811192209.mAJM9l6H021990@zion.cs.uiuc.edu> Author: djg Date: Wed Nov 19 16:09:45 2008 New Revision: 59667 URL: http://llvm.org/viewvc/llvm-project?rev=59667&view=rev Log: Move the code for printing a graph node label for an SUnit into a virtual method of SelectionDAG. Modified: llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp Modified: llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h?rev=59667&r1=59666&r2=59667&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h (original) +++ llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h Wed Nov 19 16:09:45 2008 @@ -396,6 +396,10 @@ /// virtual void Schedule() = 0; + /// getGraphpNodeLabel - Return a label for an SUnit node in a Graphviz or similar + /// graph visualization. + virtual std::string getGraphNodeLabel(const SUnit *SU) const; + private: /// EmitSubregNode - Generate machine code for subreg nodes. /// Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp?rev=59667&r1=59666&r2=59667&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Wed Nov 19 16:09:45 2008 @@ -468,7 +468,7 @@ FlaggedNodes.push_back(N); while (!FlaggedNodes.empty()) { O << " "; - FlaggedNodes.back()->dump(G->DAG); + FlaggedNodes.back()->print(O, G->DAG); O << "\n"; FlaggedNodes.pop_back(); } Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp?rev=59667&r1=59666&r2=59667&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp Wed Nov 19 16:09:45 2008 @@ -444,32 +444,29 @@ std::string DOTGraphTraits::getNodeLabel(const SUnit *SU, const ScheduleDAG *G) { - std::string Op; + return G->getGraphNodeLabel(SU); +} - if (G->DAG) { - if (!SU->getNode()) - Op = ""; - else { - SmallVector FlaggedNodes; - for (SDNode *N = SU->getNode(); N; N = N->getFlaggedNode()) - FlaggedNodes.push_back(N); - while (!FlaggedNodes.empty()) { - Op += DOTGraphTraits::getNodeLabel(FlaggedNodes.back(), - G->DAG) + "\n"; - FlaggedNodes.pop_back(); - } +std::string ScheduleDAG::getGraphNodeLabel(const SUnit *SU) const { + std::string s; + raw_string_ostream O(s); + O << "SU(" << SU->NodeNum << "): "; + if (SU->getNode()) { + SmallVector FlaggedNodes; + for (SDNode *N = SU->getNode(); N; N = N->getFlaggedNode()) + FlaggedNodes.push_back(N); + while (!FlaggedNodes.empty()) { + O << DOTGraphTraits::getNodeLabel(FlaggedNodes.back(), DAG); + FlaggedNodes.pop_back(); + if (!FlaggedNodes.empty()) + O << "\n "; } } else { - std::string s; - raw_string_ostream oss(s); - SU->getInstr()->print(oss); - Op += oss.str(); + O << "CROSS RC COPY"; } - - return Op; + return O.str(); } - /// viewGraph - Pop up a ghostview window with the reachable parts of the DAG /// rendered using 'dot'. /// From gohman at apple.com Wed Nov 19 17:19:03 2008 From: gohman at apple.com (Dan Gohman) Date: Wed, 19 Nov 2008 23:19:03 -0000 Subject: [llvm-commits] [llvm] r59676 - in /llvm/trunk: include/llvm/CodeGen/ lib/CodeGen/ lib/CodeGen/SelectionDAG/ lib/Target/CellSPU/ lib/Target/PowerPC/ Message-ID: <200811192319.mAJNJ4eL024458@zion.cs.uiuc.edu> Author: djg Date: Wed Nov 19 17:18:57 2008 New Revision: 59676 URL: http://llvm.org/viewvc/llvm-project?rev=59676&view=rev Log: Experimental post-pass scheduling support. Post-pass scheduling is currently off by default, and can be enabled with -disable-post-RA-scheduler=false. This doesn't have a significant impact on most code yet because it doesn't yet do anything to address anti-dependencies and it doesn't attempt to disambiguate memory references. Also, several popular targets don't have pipeline descriptions yet. The majority of the changes here are splitting the SelectionDAG-specific code out of ScheduleDAG, so that ScheduleDAG can be moved to libLLVMCodeGen.a. The interface between ScheduleDAG-using code and the rest of the scheduling code is somewhat rough and will evolve. Added: llvm/trunk/include/llvm/CodeGen/LatencyPriorityQueue.h - copied unchanged from r59477, llvm/trunk/lib/CodeGen/SelectionDAG/LatencyPriorityQueue.h llvm/trunk/include/llvm/CodeGen/ScheduleDAGInstrs.h - copied, changed from r59324, llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h llvm/trunk/include/llvm/CodeGen/ScheduleDAGSDNodes.h - copied, changed from r59324, llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h llvm/trunk/lib/CodeGen/LatencyPriorityQueue.cpp - copied, changed from r59477, llvm/trunk/lib/CodeGen/SelectionDAG/LatencyPriorityQueue.cpp llvm/trunk/lib/CodeGen/ScheduleDAG.cpp - copied, changed from r59324, llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp llvm/trunk/lib/CodeGen/ScheduleDAGEmit.cpp - copied, changed from r59282, llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGEmit.cpp llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp - copied, changed from r59324, llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp llvm/trunk/lib/CodeGen/ScheduleDAGPrinter.cpp - copied, changed from r59660, llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp - copied, changed from r59324, llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp - copied, changed from r59282, llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGEmit.cpp Removed: llvm/trunk/lib/CodeGen/SelectionDAG/LatencyPriorityQueue.cpp llvm/trunk/lib/CodeGen/SelectionDAG/LatencyPriorityQueue.h llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGEmit.cpp Modified: llvm/trunk/include/llvm/CodeGen/LinkAllCodegenComponents.h llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h llvm/trunk/lib/CodeGen/CMakeLists.txt llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp llvm/trunk/lib/CodeGen/SelectionDAG/CMakeLists.txt llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp llvm/trunk/lib/Target/CellSPU/SPUHazardRecognizers.h llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.h Modified: llvm/trunk/include/llvm/CodeGen/LinkAllCodegenComponents.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/LinkAllCodegenComponents.h?rev=59676&r1=59675&r2=59676&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/LinkAllCodegenComponents.h (original) +++ llvm/trunk/include/llvm/CodeGen/LinkAllCodegenComponents.h Wed Nov 19 17:18:57 2008 @@ -16,7 +16,7 @@ #define LLVM_CODEGEN_LINKALLCODEGENCOMPONENTS_H #include "llvm/CodeGen/Passes.h" -#include "llvm/CodeGen/ScheduleDAG.h" +#include "llvm/CodeGen/ScheduleDAGSDNodes.h" #include "llvm/CodeGen/GCs.h" namespace { Modified: llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h?rev=59676&r1=59675&r2=59676&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h (original) +++ llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h Wed Nov 19 17:18:57 2008 @@ -8,7 +8,7 @@ //===----------------------------------------------------------------------===// // // This file implements the ScheduleDAG class, which is used as the common -// base class for SelectionDAG-based instruction scheduler. +// base class for instruction schedulers. // //===----------------------------------------------------------------------===// @@ -16,10 +16,9 @@ #define LLVM_CODEGEN_SCHEDULEDAG_H #include "llvm/CodeGen/MachineBasicBlock.h" -#include "llvm/CodeGen/SelectionDAG.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/GraphTraits.h" -#include "llvm/ADT/SmallSet.h" +#include "llvm/ADT/SmallVector.h" namespace llvm { struct SUnit; @@ -31,51 +30,13 @@ class TargetRegisterInfo; class ScheduleDAG; class SelectionDAG; - class SelectionDAGISel; + class SDNode; class TargetInstrInfo; class TargetInstrDesc; class TargetLowering; class TargetMachine; class TargetRegisterClass; - - /// HazardRecognizer - This determines whether or not an instruction can be - /// issued this cycle, and whether or not a noop needs to be inserted to handle - /// the hazard. - class HazardRecognizer { - public: - virtual ~HazardRecognizer(); - - enum HazardType { - NoHazard, // This instruction can be emitted at this cycle. - Hazard, // This instruction can't be emitted at this cycle. - NoopHazard // This instruction can't be emitted, and needs noops. - }; - - /// getHazardType - Return the hazard type of emitting this node. There are - /// three possible results. Either: - /// * NoHazard: it is legal to issue this instruction on this cycle. - /// * Hazard: issuing this instruction would stall the machine. If some - /// other instruction is available, issue it first. - /// * NoopHazard: issuing this instruction would break the program. If - /// some other instruction can be issued, do so, otherwise issue a noop. - virtual HazardType getHazardType(SDNode *) { - return NoHazard; - } - - /// EmitInstruction - This callback is invoked when an instruction is - /// emitted, to advance the hazard state. - virtual void EmitInstruction(SDNode *) {} - - /// AdvanceCycle - This callback is invoked when no instructions can be - /// issued on this cycle without a hazard. This should increment the - /// internal state of the hazard recognizer so that previously "Hazard" - /// instructions will now not be hazards. - virtual void AdvanceCycle() {} - - /// EmitNoop - This callback is invoked when a noop was added to the - /// instruction stream. - virtual void EmitNoop() {} - }; + template class GraphWriter; /// SDep - Scheduling dependency. It keeps track of dependent nodes, /// cost of the depdenency, etc. @@ -89,8 +50,7 @@ : Dep(d), Reg(r), Cost(t), isCtrl(c), isSpecial(s) {} }; - /// SUnit - Scheduling unit. It's an wrapper around either a single SDNode or - /// a group of nodes flagged together. + /// SUnit - Scheduling unit. This is a node in the scheduling DAG. struct SUnit { private: SDNode *Node; // Representative node. @@ -294,12 +254,11 @@ std::vector Sequence; // The schedule. Null SUnit*'s // represent noop instructions. std::vector SUnits; // The scheduling units. - SmallSet CommuteSet; // Nodes that should be commuted. ScheduleDAG(SelectionDAG *dag, MachineBasicBlock *bb, const TargetMachine &tm); - virtual ~ScheduleDAG() {} + virtual ~ScheduleDAG(); /// viewGraph - Pop up a GraphViz/gv window with the ScheduleDAG rendered /// using 'dot'. @@ -310,84 +269,27 @@ /// void Run(); - /// isPassiveNode - Return true if the node is a non-scheduled leaf. + /// BuildSchedUnits - Build SUnits and set up their Preds and Succs + /// to form the scheduling dependency graph. /// - static bool isPassiveNode(SDNode *Node) { - if (isa(Node)) return true; - if (isa(Node)) return true; - if (isa(Node)) return true; - if (isa(Node)) return true; - if (isa(Node)) return true; - if (isa(Node)) return true; - if (isa(Node)) return true; - if (isa(Node)) return true; - if (isa(Node)) return true; - if (isa(Node)) return true; - if (Node->getOpcode() == ISD::EntryToken) return true; - return false; - } - - /// NewSUnit - Creates a new SUnit and return a ptr to it. - /// - SUnit *NewSUnit(SDNode *N) { - SUnits.push_back(SUnit(N, (unsigned)SUnits.size())); - SUnits.back().OrigNode = &SUnits.back(); - return &SUnits.back(); - } - - /// NewSUnit - Creates a new SUnit and return a ptr to it. - /// - SUnit *NewSUnit(MachineInstr *MI) { - SUnits.push_back(SUnit(MI, (unsigned)SUnits.size())); - SUnits.back().OrigNode = &SUnits.back(); - return &SUnits.back(); - } - - /// Clone - Creates a clone of the specified SUnit. It does not copy the - /// predecessors / successors info nor the temporary scheduling states. - SUnit *Clone(SUnit *N); - - /// BuildSchedUnits - Build SUnits from the selection dag that we are input. - /// This SUnit graph is similar to the SelectionDAG, but represents flagged - /// together nodes with a single SUnit. - void BuildSchedUnits(); + virtual void BuildSchedUnits() = 0; /// ComputeLatency - Compute node latency. /// - void ComputeLatency(SUnit *SU); + virtual void ComputeLatency(SUnit *SU) { SU->Latency = 1; } /// CalculateDepths, CalculateHeights - Calculate node depth / height. /// void CalculateDepths(); void CalculateHeights(); - /// CountResults - The results of target nodes have register or immediate - /// operands first, then an optional chain, and optional flag operands - /// (which do not go into the machine instrs.) - static unsigned CountResults(SDNode *Node); - - /// CountOperands - The inputs to target nodes have any actual inputs first, - /// followed by special operands that describe memory references, then an - /// optional chain operand, then flag operands. Compute the number of - /// actual operands that will go into the resulting MachineInstr. - static unsigned CountOperands(SDNode *Node); - - /// ComputeMemOperandsEnd - Find the index one past the last - /// MemOperandSDNode operand - static unsigned ComputeMemOperandsEnd(SDNode *Node); - - /// EmitNode - Generate machine code for an node and needed dependencies. - /// VRBaseMap contains, for each already emitted node, the first virtual - /// register number for the results of the node. - /// - void EmitNode(SDNode *Node, bool IsClone, - DenseMap &VRBaseMap); - + protected: /// EmitNoop - Emit a noop instruction. /// void EmitNoop(); - MachineBasicBlock *EmitSchedule(); + public: + virtual MachineBasicBlock *EmitSchedule() = 0; void dumpSchedule() const; @@ -396,41 +298,22 @@ /// virtual void Schedule() = 0; - /// getGraphpNodeLabel - Return a label for an SUnit node in a Graphviz or similar - /// graph visualization. - virtual std::string getGraphNodeLabel(const SUnit *SU) const; + virtual void dumpNode(const SUnit *SU) const = 0; - private: - /// EmitSubregNode - Generate machine code for subreg nodes. - /// - void EmitSubregNode(SDNode *Node, - DenseMap &VRBaseMap); + /// getGraphNodeLabel - Return a label for an SUnit node in a visualization + /// of the ScheduleDAG. + virtual std::string getGraphNodeLabel(const SUnit *SU) const = 0; - /// getVR - Return the virtual register corresponding to the specified result - /// of the specified node. - unsigned getVR(SDValue Op, DenseMap &VRBaseMap); - - /// getDstOfCopyToRegUse - If the only use of the specified result number of - /// node is a CopyToReg, return its destination register. Return 0 otherwise. - unsigned getDstOfOnlyCopyToRegUse(SDNode *Node, unsigned ResNo) const; - - void AddOperand(MachineInstr *MI, SDValue Op, unsigned IIOpNum, - const TargetInstrDesc *II, - DenseMap &VRBaseMap); + /// addCustomGraphFeatures - Add custom features for a visualization of + /// the ScheduleDAG. + virtual void addCustomGraphFeatures(GraphWriter &GW) const {} + + protected: void AddMemOperand(MachineInstr *MI, const MachineMemOperand &MO); void EmitCrossRCCopy(SUnit *SU, DenseMap &VRBaseMap); - /// EmitCopyFromReg - Generate machine code for an CopyFromReg node or an - /// implicit physical register output. - void EmitCopyFromReg(SDNode *Node, unsigned ResNo, bool IsClone, - unsigned SrcReg, - DenseMap &VRBaseMap); - - void CreateVirtualRegisters(SDNode *Node, MachineInstr *MI, - const TargetInstrDesc &II, - DenseMap &VRBaseMap); - + private: /// EmitLiveInCopy - Emit a copy for a live in physical register. If the /// physical register has only a single copy use, then coalesced the copy /// if possible. @@ -444,53 +327,8 @@ /// and if it has live ins that need to be copied into vregs, emit the /// copies into the top of the block. void EmitLiveInCopies(MachineBasicBlock *MBB); - - /// BuildSchedUnitsFromMBB - Build SUnits from the MachineBasicBlock. - /// This SUnit graph is similar to the pre-regalloc SUnit graph, but represents - /// MachineInstrs directly instead of SDNodes. - void BuildSchedUnitsFromMBB(); }; - /// createBURRListDAGScheduler - This creates a bottom up register usage - /// reduction list scheduler. - ScheduleDAG* createBURRListDAGScheduler(SelectionDAGISel *IS, - SelectionDAG *DAG, - const TargetMachine *TM, - MachineBasicBlock *BB, - bool Fast); - - /// createTDRRListDAGScheduler - This creates a top down register usage - /// reduction list scheduler. - ScheduleDAG* createTDRRListDAGScheduler(SelectionDAGISel *IS, - SelectionDAG *DAG, - const TargetMachine *TM, - MachineBasicBlock *BB, - bool Fast); - - /// createTDListDAGScheduler - This creates a top-down list scheduler with - /// a hazard recognizer. - ScheduleDAG* createTDListDAGScheduler(SelectionDAGISel *IS, - SelectionDAG *DAG, - const TargetMachine *TM, - MachineBasicBlock *BB, - bool Fast); - - /// createFastDAGScheduler - This creates a "fast" scheduler. - /// - ScheduleDAG *createFastDAGScheduler(SelectionDAGISel *IS, - SelectionDAG *DAG, - const TargetMachine *TM, - MachineBasicBlock *BB, - bool Fast); - - /// createDefaultScheduler - This creates an instruction scheduler appropriate - /// for the target. - ScheduleDAG* createDefaultScheduler(SelectionDAGISel *IS, - SelectionDAG *DAG, - const TargetMachine *TM, - MachineBasicBlock *BB, - bool Fast); - class SUnitIterator : public forward_iterator { SUnit *Node; unsigned Operand; Copied: llvm/trunk/include/llvm/CodeGen/ScheduleDAGInstrs.h (from r59324, llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h) URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ScheduleDAGInstrs.h?p2=llvm/trunk/include/llvm/CodeGen/ScheduleDAGInstrs.h&p1=llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h&r1=59324&r2=59676&rev=59676&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h (original) +++ llvm/trunk/include/llvm/CodeGen/ScheduleDAGInstrs.h Wed Nov 19 17:18:57 2008 @@ -1,4 +1,4 @@ -//===------- llvm/CodeGen/ScheduleDAG.h - Common Base Class------*- C++ -*-===// +//==- llvm/CodeGen/ScheduleDAGInstrs.h - MachineInstr Scheduling -*- C++ -*-==// // // The LLVM Compiler Infrastructure // @@ -7,22 +7,17 @@ // //===----------------------------------------------------------------------===// // -// This file implements the ScheduleDAG class, which is used as the common -// base class for SelectionDAG-based instruction scheduler. +// This file implements the ScheduleDAGInstrs class, which implements +// scheduling for a MachineInstr-based dependency graph. // //===----------------------------------------------------------------------===// -#ifndef LLVM_CODEGEN_SCHEDULEDAG_H -#define LLVM_CODEGEN_SCHEDULEDAG_H +#ifndef LLVM_CODEGEN_SCHEDULEDAGINSTRS_H +#define LLVM_CODEGEN_SCHEDULEDAGINSTRS_H -#include "llvm/CodeGen/MachineBasicBlock.h" -#include "llvm/CodeGen/SelectionDAG.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/GraphTraits.h" -#include "llvm/ADT/SmallSet.h" +#include "llvm/CodeGen/ScheduleDAG.h" namespace llvm { - struct InstrStage; struct SUnit; class MachineConstantPool; class MachineFunction; @@ -30,6 +25,7 @@ class MachineRegisterInfo; class MachineInstr; class TargetRegisterInfo; + class ScheduleDAG; class SelectionDAG; class SelectionDAGISel; class TargetInstrInfo; @@ -38,301 +34,12 @@ class TargetMachine; class TargetRegisterClass; - /// HazardRecognizer - This determines whether or not an instruction can be - /// issued this cycle, and whether or not a noop needs to be inserted to handle - /// the hazard. - class HazardRecognizer { + class ScheduleDAGInstrs : public ScheduleDAG { public: - virtual ~HazardRecognizer(); - - enum HazardType { - NoHazard, // This instruction can be emitted at this cycle. - Hazard, // This instruction can't be emitted at this cycle. - NoopHazard // This instruction can't be emitted, and needs noops. - }; - - /// getHazardType - Return the hazard type of emitting this node. There are - /// three possible results. Either: - /// * NoHazard: it is legal to issue this instruction on this cycle. - /// * Hazard: issuing this instruction would stall the machine. If some - /// other instruction is available, issue it first. - /// * NoopHazard: issuing this instruction would break the program. If - /// some other instruction can be issued, do so, otherwise issue a noop. - virtual HazardType getHazardType(SDNode *) { - return NoHazard; - } - - /// EmitInstruction - This callback is invoked when an instruction is - /// emitted, to advance the hazard state. - virtual void EmitInstruction(SDNode *) {} - - /// AdvanceCycle - This callback is invoked when no instructions can be - /// issued on this cycle without a hazard. This should increment the - /// internal state of the hazard recognizer so that previously "Hazard" - /// instructions will now not be hazards. - virtual void AdvanceCycle() {} - - /// EmitNoop - This callback is invoked when a noop was added to the - /// instruction stream. - virtual void EmitNoop() {} - }; - - /// SDep - Scheduling dependency. It keeps track of dependent nodes, - /// cost of the depdenency, etc. - struct SDep { - SUnit *Dep; // Dependent - either a predecessor or a successor. - unsigned Reg; // If non-zero, this dep is a phy register dependency. - int Cost; // Cost of the dependency. - bool isCtrl : 1; // True iff it's a control dependency. - bool isSpecial : 1; // True iff it's a special ctrl dep added during sched. - SDep(SUnit *d, unsigned r, int t, bool c, bool s) - : Dep(d), Reg(r), Cost(t), isCtrl(c), isSpecial(s) {} - }; - - /// SUnit - Scheduling unit. It's an wrapper around either a single SDNode or - /// a group of nodes flagged together. - struct SUnit { - private: - SDNode *Node; // Representative node. - MachineInstr *Instr; // Alternatively, a MachineInstr. - public: - SUnit *OrigNode; // If not this, the node from which - // this node was cloned. - - // Preds/Succs - The SUnits before/after us in the graph. The boolean value - // is true if the edge is a token chain edge, false if it is a value edge. - SmallVector Preds; // All sunit predecessors. - SmallVector Succs; // All sunit successors. - - typedef SmallVector::iterator pred_iterator; - typedef SmallVector::iterator succ_iterator; - typedef SmallVector::const_iterator const_pred_iterator; - typedef SmallVector::const_iterator const_succ_iterator; - - unsigned NodeNum; // Entry # of node in the node vector. - unsigned NodeQueueId; // Queue id of node. - unsigned short Latency; // Node latency. - short NumPreds; // # of non-control preds. - short NumSuccs; // # of non-control sucss. - short NumPredsLeft; // # of preds not scheduled. - short NumSuccsLeft; // # of succs not scheduled. - bool isTwoAddress : 1; // Is a two-address instruction. - bool isCommutable : 1; // Is a commutable instruction. - bool hasPhysRegDefs : 1; // Has physreg defs that are being used. - bool isPending : 1; // True once pending. - bool isAvailable : 1; // True once available. - bool isScheduled : 1; // True once scheduled. - unsigned CycleBound; // Upper/lower cycle to be scheduled at. - unsigned Cycle; // Once scheduled, the cycle of the op. - unsigned Depth; // Node depth; - unsigned Height; // Node height; - const TargetRegisterClass *CopyDstRC; // Is a special copy node if not null. - const TargetRegisterClass *CopySrcRC; - - /// SUnit - Construct an SUnit for pre-regalloc scheduling to represent - /// an SDNode and any nodes flagged to it. - SUnit(SDNode *node, unsigned nodenum) - : Node(node), Instr(0), OrigNode(0), NodeNum(nodenum), NodeQueueId(0), - Latency(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0), NumSuccsLeft(0), - isTwoAddress(false), isCommutable(false), hasPhysRegDefs(false), - isPending(false), isAvailable(false), isScheduled(false), - CycleBound(0), Cycle(0), Depth(0), Height(0), - CopyDstRC(NULL), CopySrcRC(NULL) {} - - /// SUnit - Construct an SUnit for post-regalloc scheduling to represent - /// a MachineInstr. - SUnit(MachineInstr *instr, unsigned nodenum) - : Node(0), Instr(instr), OrigNode(0), NodeNum(nodenum), NodeQueueId(0), - Latency(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0), NumSuccsLeft(0), - isTwoAddress(false), isCommutable(false), hasPhysRegDefs(false), - isPending(false), isAvailable(false), isScheduled(false), - CycleBound(0), Cycle(0), Depth(0), Height(0), - CopyDstRC(NULL), CopySrcRC(NULL) {} - - /// setNode - Assign the representative SDNode for this SUnit. - /// This may be used during pre-regalloc scheduling. - void setNode(SDNode *N) { - assert(!Instr && "Setting SDNode of SUnit with MachineInstr!"); - Node = N; - } + ScheduleDAGInstrs(MachineBasicBlock *bb, + const TargetMachine &tm); - /// getNode - Return the representative SDNode for this SUnit. - /// This may be used during pre-regalloc scheduling. - SDNode *getNode() const { - assert(!Instr && "Reading SDNode of SUnit with MachineInstr!"); - return Node; - } - - /// setInstr - Assign the instruction for the SUnit. - /// This may be used during post-regalloc scheduling. - void setInstr(MachineInstr *MI) { - assert(!Node && "Setting MachineInstr of SUnit with SDNode!"); - Instr = MI; - } - - /// getInstr - Return the representative MachineInstr for this SUnit. - /// This may be used during post-regalloc scheduling. - MachineInstr *getInstr() const { - assert(!Node && "Reading MachineInstr of SUnit with SDNode!"); - return Instr; - } - - /// addPred - This adds the specified node as a pred of the current node if - /// not already. This returns true if this is a new pred. - bool addPred(SUnit *N, bool isCtrl, bool isSpecial, - unsigned PhyReg = 0, int Cost = 1) { - for (unsigned i = 0, e = (unsigned)Preds.size(); i != e; ++i) - if (Preds[i].Dep == N && - Preds[i].isCtrl == isCtrl && Preds[i].isSpecial == isSpecial) - return false; - Preds.push_back(SDep(N, PhyReg, Cost, isCtrl, isSpecial)); - N->Succs.push_back(SDep(this, PhyReg, Cost, isCtrl, isSpecial)); - if (!isCtrl) { - ++NumPreds; - ++N->NumSuccs; - } - if (!N->isScheduled) - ++NumPredsLeft; - if (!isScheduled) - ++N->NumSuccsLeft; - return true; - } - - bool removePred(SUnit *N, bool isCtrl, bool isSpecial) { - for (SmallVector::iterator I = Preds.begin(), E = Preds.end(); - I != E; ++I) - if (I->Dep == N && I->isCtrl == isCtrl && I->isSpecial == isSpecial) { - bool FoundSucc = false; - for (SmallVector::iterator II = N->Succs.begin(), - EE = N->Succs.end(); II != EE; ++II) - if (II->Dep == this && - II->isCtrl == isCtrl && II->isSpecial == isSpecial) { - FoundSucc = true; - N->Succs.erase(II); - break; - } - assert(FoundSucc && "Mismatching preds / succs lists!"); - Preds.erase(I); - if (!isCtrl) { - --NumPreds; - --N->NumSuccs; - } - if (!N->isScheduled) - --NumPredsLeft; - if (!isScheduled) - --N->NumSuccsLeft; - return true; - } - return false; - } - - bool isPred(SUnit *N) { - for (unsigned i = 0, e = (unsigned)Preds.size(); i != e; ++i) - if (Preds[i].Dep == N) - return true; - return false; - } - - bool isSucc(SUnit *N) { - for (unsigned i = 0, e = (unsigned)Succs.size(); i != e; ++i) - if (Succs[i].Dep == N) - return true; - return false; - } - - void dump(const SelectionDAG *G) const; - void dumpAll(const SelectionDAG *G) const; - }; - - //===--------------------------------------------------------------------===// - /// SchedulingPriorityQueue - This interface is used to plug different - /// priorities computation algorithms into the list scheduler. It implements - /// the interface of a standard priority queue, where nodes are inserted in - /// arbitrary order and returned in priority order. The computation of the - /// priority and the representation of the queue are totally up to the - /// implementation to decide. - /// - class SchedulingPriorityQueue { - public: - virtual ~SchedulingPriorityQueue() {} - - virtual void initNodes(std::vector &SUnits) = 0; - virtual void addNode(const SUnit *SU) = 0; - virtual void updateNode(const SUnit *SU) = 0; - virtual void releaseState() = 0; - - virtual unsigned size() const = 0; - virtual bool empty() const = 0; - virtual void push(SUnit *U) = 0; - - virtual void push_all(const std::vector &Nodes) = 0; - virtual SUnit *pop() = 0; - - virtual void remove(SUnit *SU) = 0; - - /// ScheduledNode - As each node is scheduled, this method is invoked. This - /// allows the priority function to adjust the priority of related - /// unscheduled nodes, for example. - /// - virtual void ScheduledNode(SUnit *) {} - - virtual void UnscheduledNode(SUnit *) {} - }; - - class ScheduleDAG { - public: - SelectionDAG *DAG; // DAG of the current basic block - MachineBasicBlock *BB; // Current basic block - const TargetMachine &TM; // Target processor - const TargetInstrInfo *TII; // Target instruction information - const TargetRegisterInfo *TRI; // Target processor register info - TargetLowering *TLI; // Target lowering info - MachineFunction *MF; // Machine function - MachineRegisterInfo &MRI; // Virtual/real register map - MachineConstantPool *ConstPool; // Target constant pool - std::vector Sequence; // The schedule. Null SUnit*'s - // represent noop instructions. - std::vector SUnits; // The scheduling units. - SmallSet CommuteSet; // Nodes that should be commuted. - - ScheduleDAG(SelectionDAG *dag, MachineBasicBlock *bb, - const TargetMachine &tm); - - virtual ~ScheduleDAG() {} - - /// viewGraph - Pop up a GraphViz/gv window with the ScheduleDAG rendered - /// using 'dot'. - /// - void viewGraph(); - - /// Run - perform scheduling. - /// - void Run(); - - /// isPassiveNode - Return true if the node is a non-scheduled leaf. - /// - static bool isPassiveNode(SDNode *Node) { - if (isa(Node)) return true; - if (isa(Node)) return true; - if (isa(Node)) return true; - if (isa(Node)) return true; - if (isa(Node)) return true; - if (isa(Node)) return true; - if (isa(Node)) return true; - if (isa(Node)) return true; - if (isa(Node)) return true; - if (isa(Node)) return true; - if (Node->getOpcode() == ISD::EntryToken) return true; - return false; - } - - /// NewSUnit - Creates a new SUnit and return a ptr to it. - /// - SUnit *NewSUnit(SDNode *N) { - SUnits.push_back(SUnit(N, (unsigned)SUnits.size())); - SUnits.back().OrigNode = &SUnits.back(); - return &SUnits.back(); - } + virtual ~ScheduleDAGInstrs() {} /// NewSUnit - Creates a new SUnit and return a ptr to it. /// @@ -342,211 +49,20 @@ return &SUnits.back(); } - /// Clone - Creates a clone of the specified SUnit. It does not copy the - /// predecessors / successors info nor the temporary scheduling states. - SUnit *Clone(SUnit *N); - - /// BuildSchedUnits - Build SUnits from the selection dag that we are input. - /// This SUnit graph is similar to the SelectionDAG, but represents flagged - /// together nodes with a single SUnit. - void BuildSchedUnits(); - - /// ComputeLatency - Compute node latency. - /// - void ComputeLatency(SUnit *SU); - - /// CalculateDepths, CalculateHeights - Calculate node depth / height. - /// - void CalculateDepths(); - void CalculateHeights(); - - /// CountResults - The results of target nodes have register or immediate - /// operands first, then an optional chain, and optional flag operands - /// (which do not go into the machine instrs.) - static unsigned CountResults(SDNode *Node); - - /// CountOperands - The inputs to target nodes have any actual inputs first, - /// followed by special operands that describe memory references, then an - /// optional chain operand, then flag operands. Compute the number of - /// actual operands that will go into the resulting MachineInstr. - static unsigned CountOperands(SDNode *Node); - - /// ComputeMemOperandsEnd - Find the index one past the last - /// MemOperandSDNode operand - static unsigned ComputeMemOperandsEnd(SDNode *Node); - - /// EmitNode - Generate machine code for an node and needed dependencies. - /// VRBaseMap contains, for each already emitted node, the first virtual - /// register number for the results of the node. - /// - void EmitNode(SDNode *Node, bool IsClone, - DenseMap &VRBaseMap); - - /// EmitNoop - Emit a noop instruction. - /// - void EmitNoop(); - - MachineBasicBlock *EmitSchedule(); + /// BuildSchedUnits - Build SUnits from the MachineBasicBlock that we are + /// input. + virtual void BuildSchedUnits(); - void dumpSchedule() const; + virtual MachineBasicBlock *EmitSchedule(); /// Schedule - Order nodes according to selected style, filling /// in the Sequence member. /// virtual void Schedule() = 0; - private: - /// EmitSubregNode - Generate machine code for subreg nodes. - /// - void EmitSubregNode(SDNode *Node, - DenseMap &VRBaseMap); - - /// getVR - Return the virtual register corresponding to the specified result - /// of the specified node. - unsigned getVR(SDValue Op, DenseMap &VRBaseMap); - - /// getDstOfCopyToRegUse - If the only use of the specified result number of - /// node is a CopyToReg, return its destination register. Return 0 otherwise. - unsigned getDstOfOnlyCopyToRegUse(SDNode *Node, unsigned ResNo) const; - - void AddOperand(MachineInstr *MI, SDValue Op, unsigned IIOpNum, - const TargetInstrDesc *II, - DenseMap &VRBaseMap); - void AddMemOperand(MachineInstr *MI, const MachineMemOperand &MO); - - void EmitCrossRCCopy(SUnit *SU, DenseMap &VRBaseMap); - - /// EmitCopyFromReg - Generate machine code for an CopyFromReg node or an - /// implicit physical register output. - void EmitCopyFromReg(SDNode *Node, unsigned ResNo, bool IsClone, - unsigned SrcReg, - DenseMap &VRBaseMap); - - void CreateVirtualRegisters(SDNode *Node, MachineInstr *MI, - const TargetInstrDesc &II, - DenseMap &VRBaseMap); - - /// EmitLiveInCopy - Emit a copy for a live in physical register. If the - /// physical register has only a single copy use, then coalesced the copy - /// if possible. - void EmitLiveInCopy(MachineBasicBlock *MBB, - MachineBasicBlock::iterator &InsertPos, - unsigned VirtReg, unsigned PhysReg, - const TargetRegisterClass *RC, - DenseMap &CopyRegMap); - - /// EmitLiveInCopies - If this is the first basic block in the function, - /// and if it has live ins that need to be copied into vregs, emit the - /// copies into the top of the block. - void EmitLiveInCopies(MachineBasicBlock *MBB); - - /// BuildSchedUnitsFromMBB - Build SUnits from the MachineBasicBlock. - /// This SUnit graph is similar to the pre-regalloc SUnit graph, but represents - /// MachineInstrs directly instead of SDNodes. - void BuildSchedUnitsFromMBB(); - }; - - /// createBURRListDAGScheduler - This creates a bottom up register usage - /// reduction list scheduler. - ScheduleDAG* createBURRListDAGScheduler(SelectionDAGISel *IS, - SelectionDAG *DAG, - const TargetMachine *TM, - MachineBasicBlock *BB, - bool Fast); - - /// createTDRRListDAGScheduler - This creates a top down register usage - /// reduction list scheduler. - ScheduleDAG* createTDRRListDAGScheduler(SelectionDAGISel *IS, - SelectionDAG *DAG, - const TargetMachine *TM, - MachineBasicBlock *BB, - bool Fast); - - /// createTDListDAGScheduler - This creates a top-down list scheduler with - /// a hazard recognizer. - ScheduleDAG* createTDListDAGScheduler(SelectionDAGISel *IS, - SelectionDAG *DAG, - const TargetMachine *TM, - MachineBasicBlock *BB, - bool Fast); - - /// createFastDAGScheduler - This creates a "fast" scheduler. - /// - ScheduleDAG *createFastDAGScheduler(SelectionDAGISel *IS, - SelectionDAG *DAG, - const TargetMachine *TM, - MachineBasicBlock *BB, - bool Fast); - - /// createDefaultScheduler - This creates an instruction scheduler appropriate - /// for the target. - ScheduleDAG* createDefaultScheduler(SelectionDAGISel *IS, - SelectionDAG *DAG, - const TargetMachine *TM, - MachineBasicBlock *BB, - bool Fast); - - class SUnitIterator : public forward_iterator { - SUnit *Node; - unsigned Operand; - - SUnitIterator(SUnit *N, unsigned Op) : Node(N), Operand(Op) {} - public: - bool operator==(const SUnitIterator& x) const { - return Operand == x.Operand; - } - bool operator!=(const SUnitIterator& x) const { return !operator==(x); } - - const SUnitIterator &operator=(const SUnitIterator &I) { - assert(I.Node == Node && "Cannot assign iterators to two different nodes!"); - Operand = I.Operand; - return *this; - } - - pointer operator*() const { - return Node->Preds[Operand].Dep; - } - pointer operator->() const { return operator*(); } - - SUnitIterator& operator++() { // Preincrement - ++Operand; - return *this; - } - SUnitIterator operator++(int) { // Postincrement - SUnitIterator tmp = *this; ++*this; return tmp; - } - - static SUnitIterator begin(SUnit *N) { return SUnitIterator(N, 0); } - static SUnitIterator end (SUnit *N) { - return SUnitIterator(N, (unsigned)N->Preds.size()); - } - - unsigned getOperand() const { return Operand; } - const SUnit *getNode() const { return Node; } - bool isCtrlDep() const { return Node->Preds[Operand].isCtrl; } - bool isSpecialDep() const { return Node->Preds[Operand].isSpecial; } - }; + virtual void dumpNode(const SUnit *SU) const; - template <> struct GraphTraits { - typedef SUnit NodeType; - typedef SUnitIterator ChildIteratorType; - static inline NodeType *getEntryNode(SUnit *N) { return N; } - static inline ChildIteratorType child_begin(NodeType *N) { - return SUnitIterator::begin(N); - } - static inline ChildIteratorType child_end(NodeType *N) { - return SUnitIterator::end(N); - } - }; - - template <> struct GraphTraits : public GraphTraits { - typedef std::vector::iterator nodes_iterator; - static nodes_iterator nodes_begin(ScheduleDAG *G) { - return G->SUnits.begin(); - } - static nodes_iterator nodes_end(ScheduleDAG *G) { - return G->SUnits.end(); - } + virtual std::string getGraphNodeLabel(const SUnit *SU) const; }; } Copied: llvm/trunk/include/llvm/CodeGen/ScheduleDAGSDNodes.h (from r59324, llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h) URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ScheduleDAGSDNodes.h?p2=llvm/trunk/include/llvm/CodeGen/ScheduleDAGSDNodes.h&p1=llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h&r1=59324&r2=59676&rev=59676&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h (original) +++ llvm/trunk/include/llvm/CodeGen/ScheduleDAGSDNodes.h Wed Nov 19 17:18:57 2008 @@ -1,4 +1,4 @@ -//===------- llvm/CodeGen/ScheduleDAG.h - Common Base Class------*- C++ -*-===// +//===---- llvm/CodeGen/ScheduleDAGSDNodes.h - SDNode Scheduling -*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,22 +7,19 @@ // //===----------------------------------------------------------------------===// // -// This file implements the ScheduleDAG class, which is used as the common -// base class for SelectionDAG-based instruction scheduler. +// This file implements the ScheduleDAGSDNodes class, which implements +// scheduling for an SDNode-based dependency graph. // //===----------------------------------------------------------------------===// -#ifndef LLVM_CODEGEN_SCHEDULEDAG_H -#define LLVM_CODEGEN_SCHEDULEDAG_H +#ifndef LLVM_CODEGEN_SCHEDULEDAGSDNODES_H +#define LLVM_CODEGEN_SCHEDULEDAGSDNODES_H -#include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/CodeGen/ScheduleDAG.h" #include "llvm/CodeGen/SelectionDAG.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/GraphTraits.h" #include "llvm/ADT/SmallSet.h" namespace llvm { - struct InstrStage; struct SUnit; class MachineConstantPool; class MachineFunction; @@ -30,6 +27,7 @@ class MachineRegisterInfo; class MachineInstr; class TargetRegisterInfo; + class ScheduleDAG; class SelectionDAG; class SelectionDAGISel; class TargetInstrInfo; @@ -77,237 +75,14 @@ virtual void EmitNoop() {} }; - /// SDep - Scheduling dependency. It keeps track of dependent nodes, - /// cost of the depdenency, etc. - struct SDep { - SUnit *Dep; // Dependent - either a predecessor or a successor. - unsigned Reg; // If non-zero, this dep is a phy register dependency. - int Cost; // Cost of the dependency. - bool isCtrl : 1; // True iff it's a control dependency. - bool isSpecial : 1; // True iff it's a special ctrl dep added during sched. - SDep(SUnit *d, unsigned r, int t, bool c, bool s) - : Dep(d), Reg(r), Cost(t), isCtrl(c), isSpecial(s) {} - }; - - /// SUnit - Scheduling unit. It's an wrapper around either a single SDNode or - /// a group of nodes flagged together. - struct SUnit { - private: - SDNode *Node; // Representative node. - MachineInstr *Instr; // Alternatively, a MachineInstr. + class ScheduleDAGSDNodes : public ScheduleDAG { public: - SUnit *OrigNode; // If not this, the node from which - // this node was cloned. - - // Preds/Succs - The SUnits before/after us in the graph. The boolean value - // is true if the edge is a token chain edge, false if it is a value edge. - SmallVector Preds; // All sunit predecessors. - SmallVector Succs; // All sunit successors. - - typedef SmallVector::iterator pred_iterator; - typedef SmallVector::iterator succ_iterator; - typedef SmallVector::const_iterator const_pred_iterator; - typedef SmallVector::const_iterator const_succ_iterator; - - unsigned NodeNum; // Entry # of node in the node vector. - unsigned NodeQueueId; // Queue id of node. - unsigned short Latency; // Node latency. - short NumPreds; // # of non-control preds. - short NumSuccs; // # of non-control sucss. - short NumPredsLeft; // # of preds not scheduled. - short NumSuccsLeft; // # of succs not scheduled. - bool isTwoAddress : 1; // Is a two-address instruction. - bool isCommutable : 1; // Is a commutable instruction. - bool hasPhysRegDefs : 1; // Has physreg defs that are being used. - bool isPending : 1; // True once pending. - bool isAvailable : 1; // True once available. - bool isScheduled : 1; // True once scheduled. - unsigned CycleBound; // Upper/lower cycle to be scheduled at. - unsigned Cycle; // Once scheduled, the cycle of the op. - unsigned Depth; // Node depth; - unsigned Height; // Node height; - const TargetRegisterClass *CopyDstRC; // Is a special copy node if not null. - const TargetRegisterClass *CopySrcRC; - - /// SUnit - Construct an SUnit for pre-regalloc scheduling to represent - /// an SDNode and any nodes flagged to it. - SUnit(SDNode *node, unsigned nodenum) - : Node(node), Instr(0), OrigNode(0), NodeNum(nodenum), NodeQueueId(0), - Latency(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0), NumSuccsLeft(0), - isTwoAddress(false), isCommutable(false), hasPhysRegDefs(false), - isPending(false), isAvailable(false), isScheduled(false), - CycleBound(0), Cycle(0), Depth(0), Height(0), - CopyDstRC(NULL), CopySrcRC(NULL) {} - - /// SUnit - Construct an SUnit for post-regalloc scheduling to represent - /// a MachineInstr. - SUnit(MachineInstr *instr, unsigned nodenum) - : Node(0), Instr(instr), OrigNode(0), NodeNum(nodenum), NodeQueueId(0), - Latency(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0), NumSuccsLeft(0), - isTwoAddress(false), isCommutable(false), hasPhysRegDefs(false), - isPending(false), isAvailable(false), isScheduled(false), - CycleBound(0), Cycle(0), Depth(0), Height(0), - CopyDstRC(NULL), CopySrcRC(NULL) {} - - /// setNode - Assign the representative SDNode for this SUnit. - /// This may be used during pre-regalloc scheduling. - void setNode(SDNode *N) { - assert(!Instr && "Setting SDNode of SUnit with MachineInstr!"); - Node = N; - } - - /// getNode - Return the representative SDNode for this SUnit. - /// This may be used during pre-regalloc scheduling. - SDNode *getNode() const { - assert(!Instr && "Reading SDNode of SUnit with MachineInstr!"); - return Node; - } - - /// setInstr - Assign the instruction for the SUnit. - /// This may be used during post-regalloc scheduling. - void setInstr(MachineInstr *MI) { - assert(!Node && "Setting MachineInstr of SUnit with SDNode!"); - Instr = MI; - } - - /// getInstr - Return the representative MachineInstr for this SUnit. - /// This may be used during post-regalloc scheduling. - MachineInstr *getInstr() const { - assert(!Node && "Reading MachineInstr of SUnit with SDNode!"); - return Instr; - } - - /// addPred - This adds the specified node as a pred of the current node if - /// not already. This returns true if this is a new pred. - bool addPred(SUnit *N, bool isCtrl, bool isSpecial, - unsigned PhyReg = 0, int Cost = 1) { - for (unsigned i = 0, e = (unsigned)Preds.size(); i != e; ++i) - if (Preds[i].Dep == N && - Preds[i].isCtrl == isCtrl && Preds[i].isSpecial == isSpecial) - return false; - Preds.push_back(SDep(N, PhyReg, Cost, isCtrl, isSpecial)); - N->Succs.push_back(SDep(this, PhyReg, Cost, isCtrl, isSpecial)); - if (!isCtrl) { - ++NumPreds; - ++N->NumSuccs; - } - if (!N->isScheduled) - ++NumPredsLeft; - if (!isScheduled) - ++N->NumSuccsLeft; - return true; - } - - bool removePred(SUnit *N, bool isCtrl, bool isSpecial) { - for (SmallVector::iterator I = Preds.begin(), E = Preds.end(); - I != E; ++I) - if (I->Dep == N && I->isCtrl == isCtrl && I->isSpecial == isSpecial) { - bool FoundSucc = false; - for (SmallVector::iterator II = N->Succs.begin(), - EE = N->Succs.end(); II != EE; ++II) - if (II->Dep == this && - II->isCtrl == isCtrl && II->isSpecial == isSpecial) { - FoundSucc = true; - N->Succs.erase(II); - break; - } - assert(FoundSucc && "Mismatching preds / succs lists!"); - Preds.erase(I); - if (!isCtrl) { - --NumPreds; - --N->NumSuccs; - } - if (!N->isScheduled) - --NumPredsLeft; - if (!isScheduled) - --N->NumSuccsLeft; - return true; - } - return false; - } - - bool isPred(SUnit *N) { - for (unsigned i = 0, e = (unsigned)Preds.size(); i != e; ++i) - if (Preds[i].Dep == N) - return true; - return false; - } - - bool isSucc(SUnit *N) { - for (unsigned i = 0, e = (unsigned)Succs.size(); i != e; ++i) - if (Succs[i].Dep == N) - return true; - return false; - } - - void dump(const SelectionDAG *G) const; - void dumpAll(const SelectionDAG *G) const; - }; - - //===--------------------------------------------------------------------===// - /// SchedulingPriorityQueue - This interface is used to plug different - /// priorities computation algorithms into the list scheduler. It implements - /// the interface of a standard priority queue, where nodes are inserted in - /// arbitrary order and returned in priority order. The computation of the - /// priority and the representation of the queue are totally up to the - /// implementation to decide. - /// - class SchedulingPriorityQueue { - public: - virtual ~SchedulingPriorityQueue() {} - - virtual void initNodes(std::vector &SUnits) = 0; - virtual void addNode(const SUnit *SU) = 0; - virtual void updateNode(const SUnit *SU) = 0; - virtual void releaseState() = 0; - - virtual unsigned size() const = 0; - virtual bool empty() const = 0; - virtual void push(SUnit *U) = 0; - - virtual void push_all(const std::vector &Nodes) = 0; - virtual SUnit *pop() = 0; - - virtual void remove(SUnit *SU) = 0; - - /// ScheduledNode - As each node is scheduled, this method is invoked. This - /// allows the priority function to adjust the priority of related - /// unscheduled nodes, for example. - /// - virtual void ScheduledNode(SUnit *) {} - - virtual void UnscheduledNode(SUnit *) {} - }; - - class ScheduleDAG { - public: - SelectionDAG *DAG; // DAG of the current basic block - MachineBasicBlock *BB; // Current basic block - const TargetMachine &TM; // Target processor - const TargetInstrInfo *TII; // Target instruction information - const TargetRegisterInfo *TRI; // Target processor register info - TargetLowering *TLI; // Target lowering info - MachineFunction *MF; // Machine function - MachineRegisterInfo &MRI; // Virtual/real register map - MachineConstantPool *ConstPool; // Target constant pool - std::vector Sequence; // The schedule. Null SUnit*'s - // represent noop instructions. - std::vector SUnits; // The scheduling units. SmallSet CommuteSet; // Nodes that should be commuted. - ScheduleDAG(SelectionDAG *dag, MachineBasicBlock *bb, - const TargetMachine &tm); - - virtual ~ScheduleDAG() {} + ScheduleDAGSDNodes(SelectionDAG *dag, MachineBasicBlock *bb, + const TargetMachine &tm); - /// viewGraph - Pop up a GraphViz/gv window with the ScheduleDAG rendered - /// using 'dot'. - /// - void viewGraph(); - - /// Run - perform scheduling. - /// - void Run(); + virtual ~ScheduleDAGSDNodes() {} /// isPassiveNode - Return true if the node is a non-scheduled leaf. /// @@ -334,31 +109,21 @@ return &SUnits.back(); } - /// NewSUnit - Creates a new SUnit and return a ptr to it. - /// - SUnit *NewSUnit(MachineInstr *MI) { - SUnits.push_back(SUnit(MI, (unsigned)SUnits.size())); - SUnits.back().OrigNode = &SUnits.back(); - return &SUnits.back(); - } - /// Clone - Creates a clone of the specified SUnit. It does not copy the /// predecessors / successors info nor the temporary scheduling states. + /// SUnit *Clone(SUnit *N); + virtual SelectionDAG *getDAG() { return DAG; } + /// BuildSchedUnits - Build SUnits from the selection dag that we are input. /// This SUnit graph is similar to the SelectionDAG, but represents flagged /// together nodes with a single SUnit. - void BuildSchedUnits(); + virtual void BuildSchedUnits(); /// ComputeLatency - Compute node latency. /// - void ComputeLatency(SUnit *SU); - - /// CalculateDepths, CalculateHeights - Calculate node depth / height. - /// - void CalculateDepths(); - void CalculateHeights(); + virtual void ComputeLatency(SUnit *SU); /// CountResults - The results of target nodes have register or immediate /// operands first, then an optional chain, and optional flag operands @@ -382,19 +147,19 @@ void EmitNode(SDNode *Node, bool IsClone, DenseMap &VRBaseMap); - /// EmitNoop - Emit a noop instruction. - /// - void EmitNoop(); - - MachineBasicBlock *EmitSchedule(); - - void dumpSchedule() const; + virtual MachineBasicBlock *EmitSchedule(); /// Schedule - Order nodes according to selected style, filling /// in the Sequence member. /// virtual void Schedule() = 0; + virtual void dumpNode(const SUnit *SU) const; + + virtual std::string getGraphNodeLabel(const SUnit *SU) const; + + virtual void getCustomGraphFeatures(GraphWriter &GW) const; + private: /// EmitSubregNode - Generate machine code for subreg nodes. /// @@ -412,9 +177,6 @@ void AddOperand(MachineInstr *MI, SDValue Op, unsigned IIOpNum, const TargetInstrDesc *II, DenseMap &VRBaseMap); - void AddMemOperand(MachineInstr *MI, const MachineMemOperand &MO); - - void EmitCrossRCCopy(SUnit *SU, DenseMap &VRBaseMap); /// EmitCopyFromReg - Generate machine code for an CopyFromReg node or an /// implicit physical register output. @@ -425,25 +187,6 @@ void CreateVirtualRegisters(SDNode *Node, MachineInstr *MI, const TargetInstrDesc &II, DenseMap &VRBaseMap); - - /// EmitLiveInCopy - Emit a copy for a live in physical register. If the - /// physical register has only a single copy use, then coalesced the copy - /// if possible. - void EmitLiveInCopy(MachineBasicBlock *MBB, - MachineBasicBlock::iterator &InsertPos, - unsigned VirtReg, unsigned PhysReg, - const TargetRegisterClass *RC, - DenseMap &CopyRegMap); - - /// EmitLiveInCopies - If this is the first basic block in the function, - /// and if it has live ins that need to be copied into vregs, emit the - /// copies into the top of the block. - void EmitLiveInCopies(MachineBasicBlock *MBB); - - /// BuildSchedUnitsFromMBB - Build SUnits from the MachineBasicBlock. - /// This SUnit graph is similar to the pre-regalloc SUnit graph, but represents - /// MachineInstrs directly instead of SDNodes. - void BuildSchedUnitsFromMBB(); }; /// createBURRListDAGScheduler - This creates a bottom up register usage @@ -485,69 +228,6 @@ const TargetMachine *TM, MachineBasicBlock *BB, bool Fast); - - class SUnitIterator : public forward_iterator { - SUnit *Node; - unsigned Operand; - - SUnitIterator(SUnit *N, unsigned Op) : Node(N), Operand(Op) {} - public: - bool operator==(const SUnitIterator& x) const { - return Operand == x.Operand; - } - bool operator!=(const SUnitIterator& x) const { return !operator==(x); } - - const SUnitIterator &operator=(const SUnitIterator &I) { - assert(I.Node == Node && "Cannot assign iterators to two different nodes!"); - Operand = I.Operand; - return *this; - } - - pointer operator*() const { - return Node->Preds[Operand].Dep; - } - pointer operator->() const { return operator*(); } - - SUnitIterator& operator++() { // Preincrement - ++Operand; - return *this; - } - SUnitIterator operator++(int) { // Postincrement - SUnitIterator tmp = *this; ++*this; return tmp; - } - - static SUnitIterator begin(SUnit *N) { return SUnitIterator(N, 0); } - static SUnitIterator end (SUnit *N) { - return SUnitIterator(N, (unsigned)N->Preds.size()); - } - - unsigned getOperand() const { return Operand; } - const SUnit *getNode() const { return Node; } - bool isCtrlDep() const { return Node->Preds[Operand].isCtrl; } - bool isSpecialDep() const { return Node->Preds[Operand].isSpecial; } - }; - - template <> struct GraphTraits { - typedef SUnit NodeType; - typedef SUnitIterator ChildIteratorType; - static inline NodeType *getEntryNode(SUnit *N) { return N; } - static inline ChildIteratorType child_begin(NodeType *N) { - return SUnitIterator::begin(N); - } - static inline ChildIteratorType child_end(NodeType *N) { - return SUnitIterator::end(N); - } - }; - - template <> struct GraphTraits : public GraphTraits { - typedef std::vector::iterator nodes_iterator; - static nodes_iterator nodes_begin(ScheduleDAG *G) { - return G->SUnits.begin(); - } - static nodes_iterator nodes_end(ScheduleDAG *G) { - return G->SUnits.end(); - } - }; } #endif Modified: llvm/trunk/lib/CodeGen/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CMakeLists.txt?rev=59676&r1=59675&r2=59676&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/CMakeLists.txt (original) +++ llvm/trunk/lib/CodeGen/CMakeLists.txt Wed Nov 19 17:18:57 2008 @@ -8,6 +8,7 @@ IfConversion.cpp IntrinsicLowering.cpp LLVMTargetMachine.cpp + LatencyPriorityQueue.cpp LiveInterval.cpp LiveIntervalAnalysis.cpp LiveStackAnalysis.cpp @@ -40,6 +41,10 @@ RegAllocSimple.cpp RegisterCoalescer.cpp RegisterScavenging.cpp + ScheduleDAG.cpp + ScheduleDAGEmit.cpp + ScheduleDAGInstrs.cpp + ScheduleDAGPrinter.cpp ShadowStackGC.cpp SimpleRegisterCoalescing.cpp StackProtector.cpp Copied: llvm/trunk/lib/CodeGen/LatencyPriorityQueue.cpp (from r59477, llvm/trunk/lib/CodeGen/SelectionDAG/LatencyPriorityQueue.cpp) URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LatencyPriorityQueue.cpp?p2=llvm/trunk/lib/CodeGen/LatencyPriorityQueue.cpp&p1=llvm/trunk/lib/CodeGen/SelectionDAG/LatencyPriorityQueue.cpp&r1=59477&r2=59676&rev=59676&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LatencyPriorityQueue.cpp (original) +++ llvm/trunk/lib/CodeGen/LatencyPriorityQueue.cpp Wed Nov 19 17:18:57 2008 @@ -14,7 +14,7 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "scheduler" -#include "LatencyPriorityQueue.h" +#include "llvm/CodeGen/LatencyPriorityQueue.h" #include "llvm/Support/Debug.h" using namespace llvm; Modified: llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp?rev=59676&r1=59675&r2=59676&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp (original) +++ llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Wed Nov 19 17:18:57 2008 @@ -20,16 +20,22 @@ #define DEBUG_TYPE "post-RA-sched" #include "llvm/CodeGen/Passes.h" +#include "llvm/CodeGen/ScheduleDAGInstrs.h" +#include "llvm/CodeGen/LatencyPriorityQueue.h" +#include "llvm/CodeGen/SchedulerRegistry.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" +#include "llvm/ADT/Statistic.h" using namespace llvm; +STATISTIC(NumStalls, "Number of pipeline stalls"); + namespace { - class VISIBILITY_HIDDEN SchedulePostRATDList : public MachineFunctionPass { + class VISIBILITY_HIDDEN PostRAScheduler : public MachineFunctionPass { public: static char ID; - SchedulePostRATDList() : MachineFunctionPass(&ID) {} + PostRAScheduler() : MachineFunctionPass(&ID) {} private: MachineFunction *MF; const TargetMachine *TM; @@ -40,27 +46,208 @@ bool runOnMachineFunction(MachineFunction &Fn); }; - char SchedulePostRATDList::ID = 0; + char PostRAScheduler::ID = 0; + + class VISIBILITY_HIDDEN SchedulePostRATDList : public ScheduleDAGInstrs { + public: + SchedulePostRATDList(MachineBasicBlock *mbb, const TargetMachine &tm) + : ScheduleDAGInstrs(mbb, tm) {} + private: + MachineFunction *MF; + const TargetMachine *TM; + + /// AvailableQueue - The priority queue to use for the available SUnits. + /// + LatencyPriorityQueue AvailableQueue; + + /// PendingQueue - This contains all of the instructions whose operands have + /// been issued, but their results are not ready yet (due to the latency of + /// the operation). Once the operands becomes available, the instruction is + /// added to the AvailableQueue. + std::vector PendingQueue; + + public: + const char *getPassName() const { + return "Post RA top-down list latency scheduler (STUB)"; + } + + bool runOnMachineFunction(MachineFunction &Fn); + + void Schedule(); + + private: + void ReleaseSucc(SUnit *SU, SUnit *SuccSU, bool isChain); + void ScheduleNodeTopDown(SUnit *SU, unsigned CurCycle); + void ListScheduleTopDown(); + }; } -bool SchedulePostRATDList::runOnMachineFunction(MachineFunction &Fn) { - DOUT << "SchedulePostRATDList\n"; +bool PostRAScheduler::runOnMachineFunction(MachineFunction &Fn) { + DOUT << "PostRAScheduler\n"; MF = &Fn; TM = &MF->getTarget(); // Loop over all of the basic blocks for (MachineFunction::iterator MBB = Fn.begin(), MBBe = Fn.end(); - MBB != MBBe; ++MBB) - ; + MBB != MBBe; ++MBB) { + + SchedulePostRATDList Scheduler(MBB, *TM); + + Scheduler.Run(); + + Scheduler.EmitSchedule(); + } return true; } +/// Schedule - Schedule the DAG using list scheduling. +void SchedulePostRATDList::Schedule() { + DOUT << "********** List Scheduling **********\n"; + + // Build scheduling units. + BuildSchedUnits(); + + AvailableQueue.initNodes(SUnits); + + ListScheduleTopDown(); + + AvailableQueue.releaseState(); +} + +//===----------------------------------------------------------------------===// +// Top-Down Scheduling +//===----------------------------------------------------------------------===// + +/// ReleaseSucc - Decrement the NumPredsLeft count of a successor. Add it to +/// the PendingQueue if the count reaches zero. Also update its cycle bound. +void SchedulePostRATDList::ReleaseSucc(SUnit *SU, SUnit *SuccSU, bool isChain) { + --SuccSU->NumPredsLeft; + +#ifndef NDEBUG + if (SuccSU->NumPredsLeft < 0) { + cerr << "*** Scheduling failed! ***\n"; + SuccSU->dump(this); + cerr << " has been released too many times!\n"; + assert(0); + } +#endif + + // Compute how many cycles it will be before this actually becomes + // available. This is the max of the start time of all predecessors plus + // their latencies. + // If this is a token edge, we don't need to wait for the latency of the + // preceeding instruction (e.g. a long-latency load) unless there is also + // some other data dependence. + unsigned PredDoneCycle = SU->Cycle; + if (!isChain) + PredDoneCycle += SU->Latency; + else if (SU->Latency) + PredDoneCycle += 1; + SuccSU->CycleBound = std::max(SuccSU->CycleBound, PredDoneCycle); + + if (SuccSU->NumPredsLeft == 0) { + PendingQueue.push_back(SuccSU); + } +} + +/// ScheduleNodeTopDown - Add the node to the schedule. Decrement the pending +/// count of its successors. If a successor pending count is zero, add it to +/// the Available queue. +void SchedulePostRATDList::ScheduleNodeTopDown(SUnit *SU, unsigned CurCycle) { + DOUT << "*** Scheduling [" << CurCycle << "]: "; + DEBUG(SU->dump(this)); + + Sequence.push_back(SU); + SU->Cycle = CurCycle; + + // Top down: release successors. + for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); + I != E; ++I) + ReleaseSucc(SU, I->Dep, I->isCtrl); + + SU->isScheduled = true; + AvailableQueue.ScheduledNode(SU); +} + +/// ListScheduleTopDown - The main loop of list scheduling for top-down +/// schedulers. +void SchedulePostRATDList::ListScheduleTopDown() { + unsigned CurCycle = 0; + + // All leaves to Available queue. + for (unsigned i = 0, e = SUnits.size(); i != e; ++i) { + // It is available if it has no predecessors. + if (SUnits[i].Preds.empty()) { + AvailableQueue.push(&SUnits[i]); + SUnits[i].isAvailable = true; + } + } + + // While Available queue is not empty, grab the node with the highest + // priority. If it is not ready put it back. Schedule the node. + Sequence.reserve(SUnits.size()); + while (!AvailableQueue.empty() || !PendingQueue.empty()) { + // Check to see if any of the pending instructions are ready to issue. If + // so, add them to the available queue. + for (unsigned i = 0, e = PendingQueue.size(); i != e; ++i) { + if (PendingQueue[i]->CycleBound == CurCycle) { + AvailableQueue.push(PendingQueue[i]); + PendingQueue[i]->isAvailable = true; + PendingQueue[i] = PendingQueue.back(); + PendingQueue.pop_back(); + --i; --e; + } else { + assert(PendingQueue[i]->CycleBound > CurCycle && "Negative latency?"); + } + } + + // If there are no instructions available, don't try to issue anything, and + // don't advance the hazard recognizer. + if (AvailableQueue.empty()) { + ++CurCycle; + continue; + } + + SUnit *FoundSUnit = AvailableQueue.pop(); + + // If we found a node to schedule, do it now. + if (FoundSUnit) { + ScheduleNodeTopDown(FoundSUnit, CurCycle); + + // If this is a pseudo-op node, we don't want to increment the current + // cycle. + if (FoundSUnit->Latency) // Don't increment CurCycle for pseudo-ops! + ++CurCycle; + } else { + // Otherwise, we have a pipeline stall, but no other problem, just advance + // the current cycle and try again. + DOUT << "*** Advancing cycle, no work to do\n"; + ++NumStalls; + ++CurCycle; + } + } + +#ifndef NDEBUG + // Verify that all SUnits were scheduled. + bool AnyNotSched = false; + for (unsigned i = 0, e = SUnits.size(); i != e; ++i) { + if (SUnits[i].NumPredsLeft != 0) { + if (!AnyNotSched) + cerr << "*** List scheduling failed! ***\n"; + SUnits[i].dump(this); + cerr << "has not been scheduled!\n"; + AnyNotSched = true; + } + } + assert(!AnyNotSched); +#endif +} //===----------------------------------------------------------------------===// // Public Constructor Functions //===----------------------------------------------------------------------===// FunctionPass *llvm::createPostRAScheduler() { - return new SchedulePostRATDList(); + return new PostRAScheduler(); } Copied: llvm/trunk/lib/CodeGen/ScheduleDAG.cpp (from r59324, llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp) URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ScheduleDAG.cpp?p2=llvm/trunk/lib/CodeGen/ScheduleDAG.cpp&p1=llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp&r1=59324&r2=59676&rev=59676&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/ScheduleDAG.cpp Wed Nov 19 17:18:57 2008 @@ -30,267 +30,7 @@ ConstPool = MF->getConstantPool(); } -/// CheckForPhysRegDependency - Check if the dependency between def and use of -/// a specified operand is a physical register dependency. If so, returns the -/// register and the cost of copying the register. -static void CheckForPhysRegDependency(SDNode *Def, SDNode *User, unsigned Op, - const TargetRegisterInfo *TRI, - const TargetInstrInfo *TII, - unsigned &PhysReg, int &Cost) { - if (Op != 2 || User->getOpcode() != ISD::CopyToReg) - return; - - unsigned Reg = cast(User->getOperand(1))->getReg(); - if (TargetRegisterInfo::isVirtualRegister(Reg)) - return; - - unsigned ResNo = User->getOperand(2).getResNo(); - if (Def->isMachineOpcode()) { - const TargetInstrDesc &II = TII->get(Def->getMachineOpcode()); - if (ResNo >= II.getNumDefs() && - II.ImplicitDefs[ResNo - II.getNumDefs()] == Reg) { - PhysReg = Reg; - const TargetRegisterClass *RC = - TRI->getPhysicalRegisterRegClass(Reg, Def->getValueType(ResNo)); - Cost = RC->getCopyCost(); - } - } -} - -SUnit *ScheduleDAG::Clone(SUnit *Old) { - SUnit *SU = NewSUnit(Old->getNode()); - SU->OrigNode = Old->OrigNode; - SU->Latency = Old->Latency; - SU->isTwoAddress = Old->isTwoAddress; - SU->isCommutable = Old->isCommutable; - SU->hasPhysRegDefs = Old->hasPhysRegDefs; - return SU; -} - - -/// BuildSchedUnits - Build SUnits from the selection dag that we are input. -/// This SUnit graph is similar to the SelectionDAG, but represents flagged -/// together nodes with a single SUnit. -void ScheduleDAG::BuildSchedUnits() { - // For post-regalloc scheduling, build the SUnits from the MachineInstrs - // in the MachineBasicBlock. - if (!DAG) { - BuildSchedUnitsFromMBB(); - return; - } - - // Reserve entries in the vector for each of the SUnits we are creating. This - // ensure that reallocation of the vector won't happen, so SUnit*'s won't get - // invalidated. - SUnits.reserve(DAG->allnodes_size()); - - // During scheduling, the NodeId field of SDNode is used to map SDNodes - // to their associated SUnits by holding SUnits table indices. A value - // of -1 means the SDNode does not yet have an associated SUnit. - for (SelectionDAG::allnodes_iterator NI = DAG->allnodes_begin(), - E = DAG->allnodes_end(); NI != E; ++NI) - NI->setNodeId(-1); - - for (SelectionDAG::allnodes_iterator NI = DAG->allnodes_begin(), - E = DAG->allnodes_end(); NI != E; ++NI) { - if (isPassiveNode(NI)) // Leaf node, e.g. a TargetImmediate. - continue; - - // If this node has already been processed, stop now. - if (NI->getNodeId() != -1) continue; - - SUnit *NodeSUnit = NewSUnit(NI); - - // See if anything is flagged to this node, if so, add them to flagged - // nodes. Nodes can have at most one flag input and one flag output. Flags - // are required the be the last operand and result of a node. - - // Scan up to find flagged preds. - SDNode *N = NI; - if (N->getNumOperands() && - N->getOperand(N->getNumOperands()-1).getValueType() == MVT::Flag) { - do { - N = N->getOperand(N->getNumOperands()-1).getNode(); - assert(N->getNodeId() == -1 && "Node already inserted!"); - N->setNodeId(NodeSUnit->NodeNum); - } while (N->getNumOperands() && - N->getOperand(N->getNumOperands()-1).getValueType()== MVT::Flag); - } - - // Scan down to find any flagged succs. - N = NI; - while (N->getValueType(N->getNumValues()-1) == MVT::Flag) { - SDValue FlagVal(N, N->getNumValues()-1); - - // There are either zero or one users of the Flag result. - bool HasFlagUse = false; - for (SDNode::use_iterator UI = N->use_begin(), E = N->use_end(); - UI != E; ++UI) - if (FlagVal.isOperandOf(*UI)) { - HasFlagUse = true; - assert(N->getNodeId() == -1 && "Node already inserted!"); - N->setNodeId(NodeSUnit->NodeNum); - N = *UI; - break; - } - if (!HasFlagUse) break; - } - - // If there are flag operands involved, N is now the bottom-most node - // of the sequence of nodes that are flagged together. - // Update the SUnit. - NodeSUnit->setNode(N); - assert(N->getNodeId() == -1 && "Node already inserted!"); - N->setNodeId(NodeSUnit->NodeNum); - - ComputeLatency(NodeSUnit); - } - - // Pass 2: add the preds, succs, etc. - for (unsigned su = 0, e = SUnits.size(); su != e; ++su) { - SUnit *SU = &SUnits[su]; - SDNode *MainNode = SU->getNode(); - - if (MainNode->isMachineOpcode()) { - unsigned Opc = MainNode->getMachineOpcode(); - const TargetInstrDesc &TID = TII->get(Opc); - for (unsigned i = 0; i != TID.getNumOperands(); ++i) { - if (TID.getOperandConstraint(i, TOI::TIED_TO) != -1) { - SU->isTwoAddress = true; - break; - } - } - if (TID.isCommutable()) - SU->isCommutable = true; - } - - // Find all predecessors and successors of the group. - for (SDNode *N = SU->getNode(); N; N = N->getFlaggedNode()) { - if (N->isMachineOpcode() && - TII->get(N->getMachineOpcode()).getImplicitDefs() && - CountResults(N) > TII->get(N->getMachineOpcode()).getNumDefs()) - SU->hasPhysRegDefs = true; - - for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { - SDNode *OpN = N->getOperand(i).getNode(); - if (isPassiveNode(OpN)) continue; // Not scheduled. - SUnit *OpSU = &SUnits[OpN->getNodeId()]; - assert(OpSU && "Node has no SUnit!"); - if (OpSU == SU) continue; // In the same group. - - MVT OpVT = N->getOperand(i).getValueType(); - assert(OpVT != MVT::Flag && "Flagged nodes should be in same sunit!"); - bool isChain = OpVT == MVT::Other; - - unsigned PhysReg = 0; - int Cost = 1; - // Determine if this is a physical register dependency. - CheckForPhysRegDependency(OpN, N, i, TRI, TII, PhysReg, Cost); - SU->addPred(OpSU, isChain, false, PhysReg, Cost); - } - } - } -} - -void ScheduleDAG::BuildSchedUnitsFromMBB() { - SUnits.clear(); - SUnits.reserve(BB->size()); - - std::vector PendingLoads; - SUnit *Terminator = 0; - SUnit *Chain = 0; - SUnit *Defs[TargetRegisterInfo::FirstVirtualRegister] = {}; - std::vector Uses[TargetRegisterInfo::FirstVirtualRegister] = {}; - int Cost = 1; // FIXME - - for (MachineBasicBlock::iterator MII = BB->end(), MIE = BB->begin(); - MII != MIE; --MII) { - MachineInstr *MI = prior(MII); - SUnit *SU = NewSUnit(MI); - - for (unsigned j = 0, n = MI->getNumOperands(); j != n; ++j) { - const MachineOperand &MO = MI->getOperand(j); - if (!MO.isReg()) continue; - unsigned Reg = MO.getReg(); - if (Reg == 0) continue; - - assert(TRI->isPhysicalRegister(Reg) && "Virtual register encountered!"); - std::vector &UseList = Uses[Reg]; - SUnit *&Def = Defs[Reg]; - // Optionally add output and anti dependences - if (Def && Def != SU) - Def->addPred(SU, /*isCtrl=*/true, /*isSpecial=*/false, - /*PhyReg=*/Reg, Cost); - for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { - SUnit *&Def = Defs[*Alias]; - if (Def && Def != SU) - Def->addPred(SU, /*isCtrl=*/true, /*isSpecial=*/false, - /*PhyReg=*/*Alias, Cost); - } - - if (MO.isDef()) { - // Add any data dependencies. - for (unsigned i = 0, e = UseList.size(); i != e; ++i) - if (UseList[i] != SU) - UseList[i]->addPred(SU, /*isCtrl=*/false, /*isSpecial=*/false, - /*PhysReg=*/Reg, Cost); - for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { - std::vector &UseList = Uses[*Alias]; - for (unsigned i = 0, e = UseList.size(); i != e; ++i) - if (UseList[i] != SU) - UseList[i]->addPred(SU, /*isCtrl=*/false, /*isSpecial=*/false, - /*PhysReg=*/*Alias, Cost); - } - - UseList.clear(); - Def = SU; - } else { - UseList.push_back(SU); - } - } - bool False = false; - bool True = true; - if (!MI->isSafeToMove(TII, False)) { - if (Chain) - Chain->addPred(SU, /*isCtrl=*/false, /*isSpecial=*/false); - for (unsigned k = 0, m = PendingLoads.size(); k != m; ++k) - PendingLoads[k]->addPred(SU, /*isCtrl=*/false, /*isSpecial=*/false); - PendingLoads.clear(); - Chain = SU; - } else if (!MI->isSafeToMove(TII, True)) { - if (Chain) - Chain->addPred(SU, /*isCtrl=*/false, /*isSpecial=*/false); - PendingLoads.push_back(SU); - } - if (Terminator && SU->Succs.empty()) - Terminator->addPred(SU, /*isCtrl=*/false, /*isSpecial=*/false); - if (MI->getDesc().isTerminator()) - Terminator = SU; - } -} - -void ScheduleDAG::ComputeLatency(SUnit *SU) { - const InstrItineraryData &InstrItins = TM.getInstrItineraryData(); - - // Compute the latency for the node. We use the sum of the latencies for - // all nodes flagged together into this SUnit. - if (InstrItins.isEmpty()) { - // No latency information. - SU->Latency = 1; - return; - } - - SU->Latency = 0; - for (SDNode *N = SU->getNode(); N; N = N->getFlaggedNode()) { - if (N->isMachineOpcode()) { - unsigned SchedClass = TII->get(N->getMachineOpcode()).getSchedClass(); - const InstrStage *S = InstrItins.begin(SchedClass); - const InstrStage *E = InstrItins.end(SchedClass); - for (; S != E; ++S) - SU->Latency += S->Cycles; - } - } -} +ScheduleDAG::~ScheduleDAG() {} /// CalculateDepths - compute depths using algorithms for the longest /// paths in the DAG @@ -401,46 +141,11 @@ } } -/// CountResults - The results of target nodes have register or immediate -/// operands first, then an optional chain, and optional flag operands (which do -/// not go into the resulting MachineInstr). -unsigned ScheduleDAG::CountResults(SDNode *Node) { - unsigned N = Node->getNumValues(); - while (N && Node->getValueType(N - 1) == MVT::Flag) - --N; - if (N && Node->getValueType(N - 1) == MVT::Other) - --N; // Skip over chain result. - return N; -} - -/// CountOperands - The inputs to target nodes have any actual inputs first, -/// followed by special operands that describe memory references, then an -/// optional chain operand, then an optional flag operand. Compute the number -/// of actual operands that will go into the resulting MachineInstr. -unsigned ScheduleDAG::CountOperands(SDNode *Node) { - unsigned N = ComputeMemOperandsEnd(Node); - while (N && isa(Node->getOperand(N - 1).getNode())) - --N; // Ignore MEMOPERAND nodes - return N; -} - -/// ComputeMemOperandsEnd - Find the index one past the last MemOperandSDNode -/// operand -unsigned ScheduleDAG::ComputeMemOperandsEnd(SDNode *Node) { - unsigned N = Node->getNumOperands(); - while (N && Node->getOperand(N - 1).getValueType() == MVT::Flag) - --N; - if (N && Node->getOperand(N - 1).getValueType() == MVT::Other) - --N; // Ignore chain if it exists. - return N; -} - - /// dump - dump the schedule. void ScheduleDAG::dumpSchedule() const { for (unsigned i = 0, e = Sequence.size(); i != e; i++) { if (SUnit *SU = Sequence[i]) - SU->dump(DAG); + SU->dump(this); else cerr << "**** NOOP ****\n"; } @@ -459,25 +164,12 @@ /// SUnit - Scheduling unit. It's an wrapper around either a single SDNode or /// a group of nodes flagged together. -void SUnit::dump(const SelectionDAG *G) const { +void SUnit::dump(const ScheduleDAG *G) const { cerr << "SU(" << NodeNum << "): "; - if (getNode()) - getNode()->dump(G); - else - cerr << "CROSS RC COPY "; - cerr << "\n"; - SmallVector FlaggedNodes; - for (SDNode *N = getNode()->getFlaggedNode(); N; N = N->getFlaggedNode()) - FlaggedNodes.push_back(N); - while (!FlaggedNodes.empty()) { - cerr << " "; - FlaggedNodes.back()->dump(G); - cerr << "\n"; - FlaggedNodes.pop_back(); - } + G->dumpNode(this); } -void SUnit::dumpAll(const SelectionDAG *G) const { +void SUnit::dumpAll(const ScheduleDAG *G) const { dump(G); cerr << " # preds left : " << NumPredsLeft << "\n"; Copied: llvm/trunk/lib/CodeGen/ScheduleDAGEmit.cpp (from r59282, llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGEmit.cpp) URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ScheduleDAGEmit.cpp?p2=llvm/trunk/lib/CodeGen/ScheduleDAGEmit.cpp&p1=llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGEmit.cpp&r1=59282&r2=59676&rev=59676&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGEmit.cpp (original) +++ llvm/trunk/lib/CodeGen/ScheduleDAGEmit.cpp Wed Nov 19 17:18:57 2008 @@ -28,612 +28,10 @@ #include "llvm/Support/MathExtras.h" using namespace llvm; -STATISTIC(NumCommutes, "Number of instructions commuted"); - -/// getInstrOperandRegClass - Return register class of the operand of an -/// instruction of the specified TargetInstrDesc. -static const TargetRegisterClass* -getInstrOperandRegClass(const TargetRegisterInfo *TRI, - const TargetInstrInfo *TII, const TargetInstrDesc &II, - unsigned Op) { - if (Op >= II.getNumOperands()) { - assert(II.isVariadic() && "Invalid operand # of instruction"); - return NULL; - } - if (II.OpInfo[Op].isLookupPtrRegClass()) - return TII->getPointerRegClass(); - return TRI->getRegClass(II.OpInfo[Op].RegClass); -} - -/// EmitCopyFromReg - Generate machine code for an CopyFromReg node or an -/// implicit physical register output. -void ScheduleDAG::EmitCopyFromReg(SDNode *Node, unsigned ResNo, - bool IsClone, unsigned SrcReg, - DenseMap &VRBaseMap) { - unsigned VRBase = 0; - if (TargetRegisterInfo::isVirtualRegister(SrcReg)) { - // Just use the input register directly! - SDValue Op(Node, ResNo); - if (IsClone) - VRBaseMap.erase(Op); - bool isNew = VRBaseMap.insert(std::make_pair(Op, SrcReg)).second; - isNew = isNew; // Silence compiler warning. - assert(isNew && "Node emitted out of order - early"); - return; - } - - // If the node is only used by a CopyToReg and the dest reg is a vreg, use - // the CopyToReg'd destination register instead of creating a new vreg. - bool MatchReg = true; - const TargetRegisterClass *UseRC = NULL; - for (SDNode::use_iterator UI = Node->use_begin(), E = Node->use_end(); - UI != E; ++UI) { - SDNode *User = *UI; - bool Match = true; - if (User->getOpcode() == ISD::CopyToReg && - User->getOperand(2).getNode() == Node && - User->getOperand(2).getResNo() == ResNo) { - unsigned DestReg = cast(User->getOperand(1))->getReg(); - if (TargetRegisterInfo::isVirtualRegister(DestReg)) { - VRBase = DestReg; - Match = false; - } else if (DestReg != SrcReg) - Match = false; - } else { - for (unsigned i = 0, e = User->getNumOperands(); i != e; ++i) { - SDValue Op = User->getOperand(i); - if (Op.getNode() != Node || Op.getResNo() != ResNo) - continue; - MVT VT = Node->getValueType(Op.getResNo()); - if (VT == MVT::Other || VT == MVT::Flag) - continue; - Match = false; - if (User->isMachineOpcode()) { - const TargetInstrDesc &II = TII->get(User->getMachineOpcode()); - const TargetRegisterClass *RC = - getInstrOperandRegClass(TRI,TII,II,i+II.getNumDefs()); - if (!UseRC) - UseRC = RC; - else if (RC) - assert(UseRC == RC && - "Multiple uses expecting different register classes!"); - } - } - } - MatchReg &= Match; - if (VRBase) - break; - } - - MVT VT = Node->getValueType(ResNo); - const TargetRegisterClass *SrcRC = 0, *DstRC = 0; - SrcRC = TRI->getPhysicalRegisterRegClass(SrcReg, VT); - - // Figure out the register class to create for the destreg. - if (VRBase) { - DstRC = MRI.getRegClass(VRBase); - } else if (UseRC) { - assert(UseRC->hasType(VT) && "Incompatible phys register def and uses!"); - DstRC = UseRC; - } else { - DstRC = TLI->getRegClassFor(VT); - } - - // If all uses are reading from the src physical register and copying the - // register is either impossible or very expensive, then don't create a copy. - if (MatchReg && SrcRC->getCopyCost() < 0) { - VRBase = SrcReg; - } else { - // Create the reg, emit the copy. - VRBase = MRI.createVirtualRegister(DstRC); - bool Emitted = - TII->copyRegToReg(*BB, BB->end(), VRBase, SrcReg, DstRC, SrcRC); - Emitted = Emitted; // Silence compiler warning. - assert(Emitted && "Unable to issue a copy instruction!"); - } - - SDValue Op(Node, ResNo); - if (IsClone) - VRBaseMap.erase(Op); - bool isNew = VRBaseMap.insert(std::make_pair(Op, VRBase)).second; - isNew = isNew; // Silence compiler warning. - assert(isNew && "Node emitted out of order - early"); -} - -/// getDstOfCopyToRegUse - If the only use of the specified result number of -/// node is a CopyToReg, return its destination register. Return 0 otherwise. -unsigned ScheduleDAG::getDstOfOnlyCopyToRegUse(SDNode *Node, - unsigned ResNo) const { - if (!Node->hasOneUse()) - return 0; - - SDNode *User = *Node->use_begin(); - if (User->getOpcode() == ISD::CopyToReg && - User->getOperand(2).getNode() == Node && - User->getOperand(2).getResNo() == ResNo) { - unsigned Reg = cast(User->getOperand(1))->getReg(); - if (TargetRegisterInfo::isVirtualRegister(Reg)) - return Reg; - } - return 0; -} - -void ScheduleDAG::CreateVirtualRegisters(SDNode *Node, MachineInstr *MI, - const TargetInstrDesc &II, - DenseMap &VRBaseMap) { - assert(Node->getMachineOpcode() != TargetInstrInfo::IMPLICIT_DEF && - "IMPLICIT_DEF should have been handled as a special case elsewhere!"); - - for (unsigned i = 0; i < II.getNumDefs(); ++i) { - // If the specific node value is only used by a CopyToReg and the dest reg - // is a vreg, use the CopyToReg'd destination register instead of creating - // a new vreg. - unsigned VRBase = 0; - for (SDNode::use_iterator UI = Node->use_begin(), E = Node->use_end(); - UI != E; ++UI) { - SDNode *User = *UI; - if (User->getOpcode() == ISD::CopyToReg && - User->getOperand(2).getNode() == Node && - User->getOperand(2).getResNo() == i) { - unsigned Reg = cast(User->getOperand(1))->getReg(); - if (TargetRegisterInfo::isVirtualRegister(Reg)) { - VRBase = Reg; - MI->addOperand(MachineOperand::CreateReg(Reg, true)); - break; - } - } - } - - // Create the result registers for this node and add the result regs to - // the machine instruction. - if (VRBase == 0) { - const TargetRegisterClass *RC = getInstrOperandRegClass(TRI, TII, II, i); - assert(RC && "Isn't a register operand!"); - VRBase = MRI.createVirtualRegister(RC); - MI->addOperand(MachineOperand::CreateReg(VRBase, true)); - } - - SDValue Op(Node, i); - bool isNew = VRBaseMap.insert(std::make_pair(Op, VRBase)).second; - isNew = isNew; // Silence compiler warning. - assert(isNew && "Node emitted out of order - early"); - } -} - -/// getVR - Return the virtual register corresponding to the specified result -/// of the specified node. -unsigned ScheduleDAG::getVR(SDValue Op, - DenseMap &VRBaseMap) { - if (Op.isMachineOpcode() && - Op.getMachineOpcode() == TargetInstrInfo::IMPLICIT_DEF) { - // Add an IMPLICIT_DEF instruction before every use. - unsigned VReg = getDstOfOnlyCopyToRegUse(Op.getNode(), Op.getResNo()); - // IMPLICIT_DEF can produce any type of result so its TargetInstrDesc - // does not include operand register class info. - if (!VReg) { - const TargetRegisterClass *RC = TLI->getRegClassFor(Op.getValueType()); - VReg = MRI.createVirtualRegister(RC); - } - BuildMI(BB, TII->get(TargetInstrInfo::IMPLICIT_DEF), VReg); - return VReg; - } - - DenseMap::iterator I = VRBaseMap.find(Op); - assert(I != VRBaseMap.end() && "Node emitted out of order - late"); - return I->second; -} - - -/// AddOperand - Add the specified operand to the specified machine instr. II -/// specifies the instruction information for the node, and IIOpNum is the -/// operand number (in the II) that we are adding. IIOpNum and II are used for -/// assertions only. -void ScheduleDAG::AddOperand(MachineInstr *MI, SDValue Op, - unsigned IIOpNum, - const TargetInstrDesc *II, - DenseMap &VRBaseMap) { - if (Op.isMachineOpcode()) { - // Note that this case is redundant with the final else block, but we - // include it because it is the most common and it makes the logic - // simpler here. - assert(Op.getValueType() != MVT::Other && - Op.getValueType() != MVT::Flag && - "Chain and flag operands should occur at end of operand list!"); - // Get/emit the operand. - unsigned VReg = getVR(Op, VRBaseMap); - const TargetInstrDesc &TID = MI->getDesc(); - bool isOptDef = IIOpNum < TID.getNumOperands() && - TID.OpInfo[IIOpNum].isOptionalDef(); - MI->addOperand(MachineOperand::CreateReg(VReg, isOptDef)); - - // Verify that it is right. - assert(TargetRegisterInfo::isVirtualRegister(VReg) && "Not a vreg?"); -#ifndef NDEBUG - if (II) { - // There may be no register class for this operand if it is a variadic - // argument (RC will be NULL in this case). In this case, we just assume - // the regclass is ok. - const TargetRegisterClass *RC = - getInstrOperandRegClass(TRI, TII, *II, IIOpNum); - assert((RC || II->isVariadic()) && "Expected reg class info!"); - const TargetRegisterClass *VRC = MRI.getRegClass(VReg); - if (RC && VRC != RC) { - cerr << "Register class of operand and regclass of use don't agree!\n"; - cerr << "Operand = " << IIOpNum << "\n"; - cerr << "Op->Val = "; Op.getNode()->dump(DAG); cerr << "\n"; - cerr << "MI = "; MI->print(cerr); - cerr << "VReg = " << VReg << "\n"; - cerr << "VReg RegClass size = " << VRC->getSize() - << ", align = " << VRC->getAlignment() << "\n"; - cerr << "Expected RegClass size = " << RC->getSize() - << ", align = " << RC->getAlignment() << "\n"; - cerr << "Fatal error, aborting.\n"; - abort(); - } - } -#endif - } else if (ConstantSDNode *C = dyn_cast(Op)) { - MI->addOperand(MachineOperand::CreateImm(C->getZExtValue())); - } else if (ConstantFPSDNode *F = dyn_cast(Op)) { - const ConstantFP *CFP = F->getConstantFPValue(); - MI->addOperand(MachineOperand::CreateFPImm(CFP)); - } else if (RegisterSDNode *R = dyn_cast(Op)) { - MI->addOperand(MachineOperand::CreateReg(R->getReg(), false)); - } else if (GlobalAddressSDNode *TGA = dyn_cast(Op)) { - MI->addOperand(MachineOperand::CreateGA(TGA->getGlobal(),TGA->getOffset())); - } else if (BasicBlockSDNode *BB = dyn_cast(Op)) { - MI->addOperand(MachineOperand::CreateMBB(BB->getBasicBlock())); - } else if (FrameIndexSDNode *FI = dyn_cast(Op)) { - MI->addOperand(MachineOperand::CreateFI(FI->getIndex())); - } else if (JumpTableSDNode *JT = dyn_cast(Op)) { - MI->addOperand(MachineOperand::CreateJTI(JT->getIndex())); - } else if (ConstantPoolSDNode *CP = dyn_cast(Op)) { - int Offset = CP->getOffset(); - unsigned Align = CP->getAlignment(); - const Type *Type = CP->getType(); - // MachineConstantPool wants an explicit alignment. - if (Align == 0) { - Align = TM.getTargetData()->getPreferredTypeAlignmentShift(Type); - if (Align == 0) { - // Alignment of vector types. FIXME! - Align = TM.getTargetData()->getABITypeSize(Type); - Align = Log2_64(Align); - } - } - - unsigned Idx; - if (CP->isMachineConstantPoolEntry()) - Idx = ConstPool->getConstantPoolIndex(CP->getMachineCPVal(), Align); - else - Idx = ConstPool->getConstantPoolIndex(CP->getConstVal(), Align); - MI->addOperand(MachineOperand::CreateCPI(Idx, Offset)); - } else if (ExternalSymbolSDNode *ES = dyn_cast(Op)) { - MI->addOperand(MachineOperand::CreateES(ES->getSymbol())); - } else { - assert(Op.getValueType() != MVT::Other && - Op.getValueType() != MVT::Flag && - "Chain and flag operands should occur at end of operand list!"); - unsigned VReg = getVR(Op, VRBaseMap); - MI->addOperand(MachineOperand::CreateReg(VReg, false)); - - // Verify that it is right. Note that the reg class of the physreg and the - // vreg don't necessarily need to match, but the target copy insertion has - // to be able to handle it. This handles things like copies from ST(0) to - // an FP vreg on x86. - assert(TargetRegisterInfo::isVirtualRegister(VReg) && "Not a vreg?"); - if (II && !II->isVariadic()) { - assert(getInstrOperandRegClass(TRI, TII, *II, IIOpNum) && - "Don't have operand info for this instruction!"); - } - } -} - void ScheduleDAG::AddMemOperand(MachineInstr *MI, const MachineMemOperand &MO) { MI->addMemOperand(*MF, MO); } -/// getSubRegisterRegClass - Returns the register class of specified register -/// class' "SubIdx"'th sub-register class. -static const TargetRegisterClass* -getSubRegisterRegClass(const TargetRegisterClass *TRC, unsigned SubIdx) { - // Pick the register class of the subregister - TargetRegisterInfo::regclass_iterator I = - TRC->subregclasses_begin() + SubIdx-1; - assert(I < TRC->subregclasses_end() && - "Invalid subregister index for register class"); - return *I; -} - -/// getSuperRegisterRegClass - Returns the register class of a superreg A whose -/// "SubIdx"'th sub-register class is the specified register class and whose -/// type matches the specified type. -static const TargetRegisterClass* -getSuperRegisterRegClass(const TargetRegisterClass *TRC, - unsigned SubIdx, MVT VT) { - // Pick the register class of the superegister for this type - for (TargetRegisterInfo::regclass_iterator I = TRC->superregclasses_begin(), - E = TRC->superregclasses_end(); I != E; ++I) - if ((*I)->hasType(VT) && getSubRegisterRegClass(*I, SubIdx) == TRC) - return *I; - assert(false && "Couldn't find the register class"); - return 0; -} - -/// EmitSubregNode - Generate machine code for subreg nodes. -/// -void ScheduleDAG::EmitSubregNode(SDNode *Node, - DenseMap &VRBaseMap) { - unsigned VRBase = 0; - unsigned Opc = Node->getMachineOpcode(); - - // If the node is only used by a CopyToReg and the dest reg is a vreg, use - // the CopyToReg'd destination register instead of creating a new vreg. - for (SDNode::use_iterator UI = Node->use_begin(), E = Node->use_end(); - UI != E; ++UI) { - SDNode *User = *UI; - if (User->getOpcode() == ISD::CopyToReg && - User->getOperand(2).getNode() == Node) { - unsigned DestReg = cast(User->getOperand(1))->getReg(); - if (TargetRegisterInfo::isVirtualRegister(DestReg)) { - VRBase = DestReg; - break; - } - } - } - - if (Opc == TargetInstrInfo::EXTRACT_SUBREG) { - unsigned SubIdx = cast(Node->getOperand(1))->getZExtValue(); - - // Create the extract_subreg machine instruction. - MachineInstr *MI = BuildMI(*MF, TII->get(TargetInstrInfo::EXTRACT_SUBREG)); - - // Figure out the register class to create for the destreg. - unsigned VReg = getVR(Node->getOperand(0), VRBaseMap); - const TargetRegisterClass *TRC = MRI.getRegClass(VReg); - const TargetRegisterClass *SRC = getSubRegisterRegClass(TRC, SubIdx); - - if (VRBase) { - // Grab the destination register -#ifndef NDEBUG - const TargetRegisterClass *DRC = MRI.getRegClass(VRBase); - assert(SRC && DRC && SRC == DRC && - "Source subregister and destination must have the same class"); -#endif - } else { - // Create the reg - assert(SRC && "Couldn't find source register class"); - VRBase = MRI.createVirtualRegister(SRC); - } - - // Add def, source, and subreg index - MI->addOperand(MachineOperand::CreateReg(VRBase, true)); - AddOperand(MI, Node->getOperand(0), 0, 0, VRBaseMap); - MI->addOperand(MachineOperand::CreateImm(SubIdx)); - BB->push_back(MI); - } else if (Opc == TargetInstrInfo::INSERT_SUBREG || - Opc == TargetInstrInfo::SUBREG_TO_REG) { - SDValue N0 = Node->getOperand(0); - SDValue N1 = Node->getOperand(1); - SDValue N2 = Node->getOperand(2); - unsigned SubReg = getVR(N1, VRBaseMap); - unsigned SubIdx = cast(N2)->getZExtValue(); - - - // Figure out the register class to create for the destreg. - const TargetRegisterClass *TRC = 0; - if (VRBase) { - TRC = MRI.getRegClass(VRBase); - } else { - TRC = getSuperRegisterRegClass(MRI.getRegClass(SubReg), SubIdx, - Node->getValueType(0)); - assert(TRC && "Couldn't determine register class for insert_subreg"); - VRBase = MRI.createVirtualRegister(TRC); // Create the reg - } - - // Create the insert_subreg or subreg_to_reg machine instruction. - MachineInstr *MI = BuildMI(*MF, TII->get(Opc)); - MI->addOperand(MachineOperand::CreateReg(VRBase, true)); - - // If creating a subreg_to_reg, then the first input operand - // is an implicit value immediate, otherwise it's a register - if (Opc == TargetInstrInfo::SUBREG_TO_REG) { - const ConstantSDNode *SD = cast(N0); - MI->addOperand(MachineOperand::CreateImm(SD->getZExtValue())); - } else - AddOperand(MI, N0, 0, 0, VRBaseMap); - // Add the subregster being inserted - AddOperand(MI, N1, 0, 0, VRBaseMap); - MI->addOperand(MachineOperand::CreateImm(SubIdx)); - BB->push_back(MI); - } else - assert(0 && "Node is not insert_subreg, extract_subreg, or subreg_to_reg"); - - SDValue Op(Node, 0); - bool isNew = VRBaseMap.insert(std::make_pair(Op, VRBase)).second; - isNew = isNew; // Silence compiler warning. - assert(isNew && "Node emitted out of order - early"); -} - -/// EmitNode - Generate machine code for an node and needed dependencies. -/// -void ScheduleDAG::EmitNode(SDNode *Node, bool IsClone, - DenseMap &VRBaseMap) { - // If machine instruction - if (Node->isMachineOpcode()) { - unsigned Opc = Node->getMachineOpcode(); - - // Handle subreg insert/extract specially - if (Opc == TargetInstrInfo::EXTRACT_SUBREG || - Opc == TargetInstrInfo::INSERT_SUBREG || - Opc == TargetInstrInfo::SUBREG_TO_REG) { - EmitSubregNode(Node, VRBaseMap); - return; - } - - if (Opc == TargetInstrInfo::IMPLICIT_DEF) - // We want a unique VR for each IMPLICIT_DEF use. - return; - - const TargetInstrDesc &II = TII->get(Opc); - unsigned NumResults = CountResults(Node); - unsigned NodeOperands = CountOperands(Node); - unsigned MemOperandsEnd = ComputeMemOperandsEnd(Node); - bool HasPhysRegOuts = (NumResults > II.getNumDefs()) && - II.getImplicitDefs() != 0; -#ifndef NDEBUG - unsigned NumMIOperands = NodeOperands + NumResults; - assert((II.getNumOperands() == NumMIOperands || - HasPhysRegOuts || II.isVariadic()) && - "#operands for dag node doesn't match .td file!"); -#endif - - // Create the new machine instruction. - MachineInstr *MI = BuildMI(*MF, II); - - // Add result register values for things that are defined by this - // instruction. - if (NumResults) - CreateVirtualRegisters(Node, MI, II, VRBaseMap); - - // Emit all of the actual operands of this instruction, adding them to the - // instruction as appropriate. - for (unsigned i = 0; i != NodeOperands; ++i) - AddOperand(MI, Node->getOperand(i), i+II.getNumDefs(), &II, VRBaseMap); - - // Emit all of the memory operands of this instruction - for (unsigned i = NodeOperands; i != MemOperandsEnd; ++i) - AddMemOperand(MI, cast(Node->getOperand(i))->MO); - - // Commute node if it has been determined to be profitable. - if (CommuteSet.count(Node)) { - MachineInstr *NewMI = TII->commuteInstruction(MI); - if (NewMI == 0) - DOUT << "Sched: COMMUTING FAILED!\n"; - else { - DOUT << "Sched: COMMUTED TO: " << *NewMI; - if (MI != NewMI) { - MF->DeleteMachineInstr(MI); - MI = NewMI; - } - ++NumCommutes; - } - } - - if (II.usesCustomDAGSchedInsertionHook()) - // Insert this instruction into the basic block using a target - // specific inserter which may returns a new basic block. - BB = TLI->EmitInstrWithCustomInserter(MI, BB); - else - BB->push_back(MI); - - // Additional results must be an physical register def. - if (HasPhysRegOuts) { - for (unsigned i = II.getNumDefs(); i < NumResults; ++i) { - unsigned Reg = II.getImplicitDefs()[i - II.getNumDefs()]; - if (Node->hasAnyUseOfValue(i)) - EmitCopyFromReg(Node, i, IsClone, Reg, VRBaseMap); - } - } - return; - } - - switch (Node->getOpcode()) { - default: -#ifndef NDEBUG - Node->dump(DAG); -#endif - assert(0 && "This target-independent node should have been selected!"); - break; - case ISD::EntryToken: - assert(0 && "EntryToken should have been excluded from the schedule!"); - break; - case ISD::TokenFactor: // fall thru - break; - case ISD::CopyToReg: { - unsigned SrcReg; - SDValue SrcVal = Node->getOperand(2); - if (RegisterSDNode *R = dyn_cast(SrcVal)) - SrcReg = R->getReg(); - else - SrcReg = getVR(SrcVal, VRBaseMap); - - unsigned DestReg = cast(Node->getOperand(1))->getReg(); - if (SrcReg == DestReg) // Coalesced away the copy? Ignore. - break; - - const TargetRegisterClass *SrcTRC = 0, *DstTRC = 0; - // Get the register classes of the src/dst. - if (TargetRegisterInfo::isVirtualRegister(SrcReg)) - SrcTRC = MRI.getRegClass(SrcReg); - else - SrcTRC = TRI->getPhysicalRegisterRegClass(SrcReg,SrcVal.getValueType()); - - if (TargetRegisterInfo::isVirtualRegister(DestReg)) - DstTRC = MRI.getRegClass(DestReg); - else - DstTRC = TRI->getPhysicalRegisterRegClass(DestReg, - Node->getOperand(1).getValueType()); - TII->copyRegToReg(*BB, BB->end(), DestReg, SrcReg, DstTRC, SrcTRC); - break; - } - case ISD::CopyFromReg: { - unsigned SrcReg = cast(Node->getOperand(1))->getReg(); - EmitCopyFromReg(Node, 0, IsClone, SrcReg, VRBaseMap); - break; - } - case ISD::INLINEASM: { - unsigned NumOps = Node->getNumOperands(); - if (Node->getOperand(NumOps-1).getValueType() == MVT::Flag) - --NumOps; // Ignore the flag operand. - - // Create the inline asm machine instruction. - MachineInstr *MI = BuildMI(*MF, TII->get(TargetInstrInfo::INLINEASM)); - - // Add the asm string as an external symbol operand. - const char *AsmStr = - cast(Node->getOperand(1))->getSymbol(); - MI->addOperand(MachineOperand::CreateES(AsmStr)); - - // Add all of the operand registers to the instruction. - for (unsigned i = 2; i != NumOps;) { - unsigned Flags = - cast(Node->getOperand(i))->getZExtValue(); - unsigned NumVals = Flags >> 3; - - MI->addOperand(MachineOperand::CreateImm(Flags)); - ++i; // Skip the ID value. - - switch (Flags & 7) { - default: assert(0 && "Bad flags!"); - case 2: // Def of register. - for (; NumVals; --NumVals, ++i) { - unsigned Reg = cast(Node->getOperand(i))->getReg(); - MI->addOperand(MachineOperand::CreateReg(Reg, true)); - } - break; - case 6: // Def of earlyclobber register. - for (; NumVals; --NumVals, ++i) { - unsigned Reg = cast(Node->getOperand(i))->getReg(); - MI->addOperand(MachineOperand::CreateReg(Reg, true, false, false, - false, 0, true)); - } - break; - case 1: // Use of register. - case 3: // Immediate. - case 4: // Addressing mode. - // The addressing mode has been selected, just add all of the - // operands to the machine instruction. - for (; NumVals; --NumVals, ++i) - AddOperand(MI, Node->getOperand(i), 0, 0, VRBaseMap); - break; - } - } - BB->push_back(MI); - break; - } - } -} - void ScheduleDAG::EmitNoop() { TII->insertNoop(*BB, BB->end()); } @@ -643,7 +41,7 @@ for (SUnit::const_pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); I != E; ++I) { if (I->isCtrl) continue; // ignore chain preds - if (!I->Dep->getNode()) { + if (I->Dep->CopyDstRC) { // Copy to physical register. DenseMap::iterator VRI = VRBaseMap.find(I->Dep); assert(VRI != VRBaseMap.end() && "Node emitted out of order - late"); @@ -672,46 +70,3 @@ break; } } - -/// EmitSchedule - Emit the machine code in scheduled order. -MachineBasicBlock *ScheduleDAG::EmitSchedule() { - // For post-regalloc scheduling, we're rescheduling the instructions in the - // block, so start by removing them from the block. - if (!DAG) - while (!BB->empty()) - BB->remove(BB->begin()); - - DenseMap VRBaseMap; - DenseMap CopyVRBaseMap; - for (unsigned i = 0, e = Sequence.size(); i != e; i++) { - SUnit *SU = Sequence[i]; - if (!SU) { - // Null SUnit* is a noop. - EmitNoop(); - continue; - } - - // For post-regalloc scheduling, we already have the instruction; - // just append it to the block. - if (!DAG) { - BB->push_back(SU->getInstr()); - continue; - } - - // For pre-regalloc scheduling, create instructions corresponding to the - // SDNode and any flagged SDNodes and append them to the block. - SmallVector FlaggedNodes; - for (SDNode *N = SU->getNode()->getFlaggedNode(); N; N = N->getFlaggedNode()) - FlaggedNodes.push_back(N); - while (!FlaggedNodes.empty()) { - EmitNode(FlaggedNodes.back(), SU->OrigNode != SU, VRBaseMap); - FlaggedNodes.pop_back(); - } - if (!SU->getNode()) - EmitCrossRCCopy(SU, CopyVRBaseMap); - else - EmitNode(SU->getNode(), SU->OrigNode != SU, VRBaseMap); - } - - return BB; -} Copied: llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp (from r59324, llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp) URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp?p2=llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp&p1=llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp&r1=59324&r2=59676&rev=59676&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp Wed Nov 19 17:18:57 2008 @@ -12,187 +12,20 @@ // //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "pre-RA-sched" -#include "llvm/CodeGen/ScheduleDAG.h" +#define DEBUG_TYPE "sched-instrs" +#include "llvm/CodeGen/ScheduleDAGInstrs.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/raw_ostream.h" using namespace llvm; -ScheduleDAG::ScheduleDAG(SelectionDAG *dag, MachineBasicBlock *bb, - const TargetMachine &tm) - : DAG(dag), BB(bb), TM(tm), MRI(BB->getParent()->getRegInfo()) { - TII = TM.getInstrInfo(); - MF = BB->getParent(); - TRI = TM.getRegisterInfo(); - TLI = TM.getTargetLowering(); - ConstPool = MF->getConstantPool(); -} - -/// CheckForPhysRegDependency - Check if the dependency between def and use of -/// a specified operand is a physical register dependency. If so, returns the -/// register and the cost of copying the register. -static void CheckForPhysRegDependency(SDNode *Def, SDNode *User, unsigned Op, - const TargetRegisterInfo *TRI, - const TargetInstrInfo *TII, - unsigned &PhysReg, int &Cost) { - if (Op != 2 || User->getOpcode() != ISD::CopyToReg) - return; - - unsigned Reg = cast(User->getOperand(1))->getReg(); - if (TargetRegisterInfo::isVirtualRegister(Reg)) - return; - - unsigned ResNo = User->getOperand(2).getResNo(); - if (Def->isMachineOpcode()) { - const TargetInstrDesc &II = TII->get(Def->getMachineOpcode()); - if (ResNo >= II.getNumDefs() && - II.ImplicitDefs[ResNo - II.getNumDefs()] == Reg) { - PhysReg = Reg; - const TargetRegisterClass *RC = - TRI->getPhysicalRegisterRegClass(Reg, Def->getValueType(ResNo)); - Cost = RC->getCopyCost(); - } - } -} - -SUnit *ScheduleDAG::Clone(SUnit *Old) { - SUnit *SU = NewSUnit(Old->getNode()); - SU->OrigNode = Old->OrigNode; - SU->Latency = Old->Latency; - SU->isTwoAddress = Old->isTwoAddress; - SU->isCommutable = Old->isCommutable; - SU->hasPhysRegDefs = Old->hasPhysRegDefs; - return SU; -} - - -/// BuildSchedUnits - Build SUnits from the selection dag that we are input. -/// This SUnit graph is similar to the SelectionDAG, but represents flagged -/// together nodes with a single SUnit. -void ScheduleDAG::BuildSchedUnits() { - // For post-regalloc scheduling, build the SUnits from the MachineInstrs - // in the MachineBasicBlock. - if (!DAG) { - BuildSchedUnitsFromMBB(); - return; - } +ScheduleDAGInstrs::ScheduleDAGInstrs(MachineBasicBlock *bb, + const TargetMachine &tm) + : ScheduleDAG(0, bb, tm) {} - // Reserve entries in the vector for each of the SUnits we are creating. This - // ensure that reallocation of the vector won't happen, so SUnit*'s won't get - // invalidated. - SUnits.reserve(DAG->allnodes_size()); - - // During scheduling, the NodeId field of SDNode is used to map SDNodes - // to their associated SUnits by holding SUnits table indices. A value - // of -1 means the SDNode does not yet have an associated SUnit. - for (SelectionDAG::allnodes_iterator NI = DAG->allnodes_begin(), - E = DAG->allnodes_end(); NI != E; ++NI) - NI->setNodeId(-1); - - for (SelectionDAG::allnodes_iterator NI = DAG->allnodes_begin(), - E = DAG->allnodes_end(); NI != E; ++NI) { - if (isPassiveNode(NI)) // Leaf node, e.g. a TargetImmediate. - continue; - - // If this node has already been processed, stop now. - if (NI->getNodeId() != -1) continue; - - SUnit *NodeSUnit = NewSUnit(NI); - - // See if anything is flagged to this node, if so, add them to flagged - // nodes. Nodes can have at most one flag input and one flag output. Flags - // are required the be the last operand and result of a node. - - // Scan up to find flagged preds. - SDNode *N = NI; - if (N->getNumOperands() && - N->getOperand(N->getNumOperands()-1).getValueType() == MVT::Flag) { - do { - N = N->getOperand(N->getNumOperands()-1).getNode(); - assert(N->getNodeId() == -1 && "Node already inserted!"); - N->setNodeId(NodeSUnit->NodeNum); - } while (N->getNumOperands() && - N->getOperand(N->getNumOperands()-1).getValueType()== MVT::Flag); - } - - // Scan down to find any flagged succs. - N = NI; - while (N->getValueType(N->getNumValues()-1) == MVT::Flag) { - SDValue FlagVal(N, N->getNumValues()-1); - - // There are either zero or one users of the Flag result. - bool HasFlagUse = false; - for (SDNode::use_iterator UI = N->use_begin(), E = N->use_end(); - UI != E; ++UI) - if (FlagVal.isOperandOf(*UI)) { - HasFlagUse = true; - assert(N->getNodeId() == -1 && "Node already inserted!"); - N->setNodeId(NodeSUnit->NodeNum); - N = *UI; - break; - } - if (!HasFlagUse) break; - } - - // If there are flag operands involved, N is now the bottom-most node - // of the sequence of nodes that are flagged together. - // Update the SUnit. - NodeSUnit->setNode(N); - assert(N->getNodeId() == -1 && "Node already inserted!"); - N->setNodeId(NodeSUnit->NodeNum); - - ComputeLatency(NodeSUnit); - } - - // Pass 2: add the preds, succs, etc. - for (unsigned su = 0, e = SUnits.size(); su != e; ++su) { - SUnit *SU = &SUnits[su]; - SDNode *MainNode = SU->getNode(); - - if (MainNode->isMachineOpcode()) { - unsigned Opc = MainNode->getMachineOpcode(); - const TargetInstrDesc &TID = TII->get(Opc); - for (unsigned i = 0; i != TID.getNumOperands(); ++i) { - if (TID.getOperandConstraint(i, TOI::TIED_TO) != -1) { - SU->isTwoAddress = true; - break; - } - } - if (TID.isCommutable()) - SU->isCommutable = true; - } - - // Find all predecessors and successors of the group. - for (SDNode *N = SU->getNode(); N; N = N->getFlaggedNode()) { - if (N->isMachineOpcode() && - TII->get(N->getMachineOpcode()).getImplicitDefs() && - CountResults(N) > TII->get(N->getMachineOpcode()).getNumDefs()) - SU->hasPhysRegDefs = true; - - for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { - SDNode *OpN = N->getOperand(i).getNode(); - if (isPassiveNode(OpN)) continue; // Not scheduled. - SUnit *OpSU = &SUnits[OpN->getNodeId()]; - assert(OpSU && "Node has no SUnit!"); - if (OpSU == SU) continue; // In the same group. - - MVT OpVT = N->getOperand(i).getValueType(); - assert(OpVT != MVT::Flag && "Flagged nodes should be in same sunit!"); - bool isChain = OpVT == MVT::Other; - - unsigned PhysReg = 0; - int Cost = 1; - // Determine if this is a physical register dependency. - CheckForPhysRegDependency(OpN, N, i, TRI, TII, PhysReg, Cost); - SU->addPred(OpSU, isChain, false, PhysReg, Cost); - } - } - } -} - -void ScheduleDAG::BuildSchedUnitsFromMBB() { +void ScheduleDAGInstrs::BuildSchedUnits() { SUnits.clear(); SUnits.reserve(BB->size()); @@ -269,250 +102,34 @@ } } -void ScheduleDAG::ComputeLatency(SUnit *SU) { - const InstrItineraryData &InstrItins = TM.getInstrItineraryData(); - - // Compute the latency for the node. We use the sum of the latencies for - // all nodes flagged together into this SUnit. - if (InstrItins.isEmpty()) { - // No latency information. - SU->Latency = 1; - return; - } - - SU->Latency = 0; - for (SDNode *N = SU->getNode(); N; N = N->getFlaggedNode()) { - if (N->isMachineOpcode()) { - unsigned SchedClass = TII->get(N->getMachineOpcode()).getSchedClass(); - const InstrStage *S = InstrItins.begin(SchedClass); - const InstrStage *E = InstrItins.end(SchedClass); - for (; S != E; ++S) - SU->Latency += S->Cycles; - } - } +void ScheduleDAGInstrs::dumpNode(const SUnit *SU) const { + SU->getInstr()->dump(); } -/// CalculateDepths - compute depths using algorithms for the longest -/// paths in the DAG -void ScheduleDAG::CalculateDepths() { - unsigned DAGSize = SUnits.size(); - std::vector WorkList; - WorkList.reserve(DAGSize); - - // Initialize the data structures - for (unsigned i = 0, e = DAGSize; i != e; ++i) { - SUnit *SU = &SUnits[i]; - unsigned Degree = SU->Preds.size(); - // Temporarily use the Depth field as scratch space for the degree count. - SU->Depth = Degree; - - // Is it a node without dependencies? - if (Degree == 0) { - assert(SU->Preds.empty() && "SUnit should have no predecessors"); - // Collect leaf nodes - WorkList.push_back(SU); - } - } - - // Process nodes in the topological order - while (!WorkList.empty()) { - SUnit *SU = WorkList.back(); - WorkList.pop_back(); - unsigned SUDepth = 0; - - // Use dynamic programming: - // When current node is being processed, all of its dependencies - // are already processed. - // So, just iterate over all predecessors and take the longest path - for (SUnit::const_pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); - I != E; ++I) { - unsigned PredDepth = I->Dep->Depth; - if (PredDepth+1 > SUDepth) { - SUDepth = PredDepth + 1; - } - } +std::string ScheduleDAGInstrs::getGraphNodeLabel(const SUnit *SU) const { + std::string s; + raw_string_ostream oss(s); + SU->getInstr()->print(oss); + return oss.str(); +} + +// EmitSchedule - Emit the machine code in scheduled order. +MachineBasicBlock *ScheduleDAGInstrs::EmitSchedule() { + // For MachineInstr-based scheduling, we're rescheduling the instructions in + // the block, so start by removing them from the block. + while (!BB->empty()) + BB->remove(BB->begin()); - SU->Depth = SUDepth; - - // Update degrees of all nodes depending on current SUnit - for (SUnit::const_succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); - I != E; ++I) { - SUnit *SU = I->Dep; - if (!--SU->Depth) - // If all dependencies of the node are processed already, - // then the longest path for the node can be computed now - WorkList.push_back(SU); - } - } -} - -/// CalculateHeights - compute heights using algorithms for the longest -/// paths in the DAG -void ScheduleDAG::CalculateHeights() { - unsigned DAGSize = SUnits.size(); - std::vector WorkList; - WorkList.reserve(DAGSize); - - // Initialize the data structures - for (unsigned i = 0, e = DAGSize; i != e; ++i) { - SUnit *SU = &SUnits[i]; - unsigned Degree = SU->Succs.size(); - // Temporarily use the Height field as scratch space for the degree count. - SU->Height = Degree; - - // Is it a node without dependencies? - if (Degree == 0) { - assert(SU->Succs.empty() && "Something wrong"); - assert(WorkList.empty() && "Should be empty"); - // Collect leaf nodes - WorkList.push_back(SU); - } - } - - // Process nodes in the topological order - while (!WorkList.empty()) { - SUnit *SU = WorkList.back(); - WorkList.pop_back(); - unsigned SUHeight = 0; - - // Use dynamic programming: - // When current node is being processed, all of its dependencies - // are already processed. - // So, just iterate over all successors and take the longest path - for (SUnit::const_succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); - I != E; ++I) { - unsigned SuccHeight = I->Dep->Height; - if (SuccHeight+1 > SUHeight) { - SUHeight = SuccHeight + 1; - } - } - - SU->Height = SUHeight; - - // Update degrees of all nodes depending on current SUnit - for (SUnit::const_pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); - I != E; ++I) { - SUnit *SU = I->Dep; - if (!--SU->Height) - // If all dependencies of the node are processed already, - // then the longest path for the node can be computed now - WorkList.push_back(SU); - } - } -} - -/// CountResults - The results of target nodes have register or immediate -/// operands first, then an optional chain, and optional flag operands (which do -/// not go into the resulting MachineInstr). -unsigned ScheduleDAG::CountResults(SDNode *Node) { - unsigned N = Node->getNumValues(); - while (N && Node->getValueType(N - 1) == MVT::Flag) - --N; - if (N && Node->getValueType(N - 1) == MVT::Other) - --N; // Skip over chain result. - return N; -} - -/// CountOperands - The inputs to target nodes have any actual inputs first, -/// followed by special operands that describe memory references, then an -/// optional chain operand, then an optional flag operand. Compute the number -/// of actual operands that will go into the resulting MachineInstr. -unsigned ScheduleDAG::CountOperands(SDNode *Node) { - unsigned N = ComputeMemOperandsEnd(Node); - while (N && isa(Node->getOperand(N - 1).getNode())) - --N; // Ignore MEMOPERAND nodes - return N; -} - -/// ComputeMemOperandsEnd - Find the index one past the last MemOperandSDNode -/// operand -unsigned ScheduleDAG::ComputeMemOperandsEnd(SDNode *Node) { - unsigned N = Node->getNumOperands(); - while (N && Node->getOperand(N - 1).getValueType() == MVT::Flag) - --N; - if (N && Node->getOperand(N - 1).getValueType() == MVT::Other) - --N; // Ignore chain if it exists. - return N; -} - - -/// dump - dump the schedule. -void ScheduleDAG::dumpSchedule() const { for (unsigned i = 0, e = Sequence.size(); i != e; i++) { - if (SUnit *SU = Sequence[i]) - SU->dump(DAG); - else - cerr << "**** NOOP ****\n"; - } -} - - -/// Run - perform scheduling. -/// -void ScheduleDAG::Run() { - Schedule(); - - DOUT << "*** Final schedule ***\n"; - DEBUG(dumpSchedule()); - DOUT << "\n"; -} + SUnit *SU = Sequence[i]; + if (!SU) { + // Null SUnit* is a noop. + EmitNoop(); + continue; + } -/// SUnit - Scheduling unit. It's an wrapper around either a single SDNode or -/// a group of nodes flagged together. -void SUnit::dump(const SelectionDAG *G) const { - cerr << "SU(" << NodeNum << "): "; - if (getNode()) - getNode()->dump(G); - else - cerr << "CROSS RC COPY "; - cerr << "\n"; - SmallVector FlaggedNodes; - for (SDNode *N = getNode()->getFlaggedNode(); N; N = N->getFlaggedNode()) - FlaggedNodes.push_back(N); - while (!FlaggedNodes.empty()) { - cerr << " "; - FlaggedNodes.back()->dump(G); - cerr << "\n"; - FlaggedNodes.pop_back(); + BB->push_back(SU->getInstr()); } -} - -void SUnit::dumpAll(const SelectionDAG *G) const { - dump(G); - cerr << " # preds left : " << NumPredsLeft << "\n"; - cerr << " # succs left : " << NumSuccsLeft << "\n"; - cerr << " Latency : " << Latency << "\n"; - cerr << " Depth : " << Depth << "\n"; - cerr << " Height : " << Height << "\n"; - - if (Preds.size() != 0) { - cerr << " Predecessors:\n"; - for (SUnit::const_succ_iterator I = Preds.begin(), E = Preds.end(); - I != E; ++I) { - if (I->isCtrl) - cerr << " ch #"; - else - cerr << " val #"; - cerr << I->Dep << " - SU(" << I->Dep->NodeNum << ")"; - if (I->isSpecial) - cerr << " *"; - cerr << "\n"; - } - } - if (Succs.size() != 0) { - cerr << " Successors:\n"; - for (SUnit::const_succ_iterator I = Succs.begin(), E = Succs.end(); - I != E; ++I) { - if (I->isCtrl) - cerr << " ch #"; - else - cerr << " val #"; - cerr << I->Dep << " - SU(" << I->Dep->NodeNum << ")"; - if (I->isSpecial) - cerr << " *"; - cerr << "\n"; - } - } - cerr << "\n"; + return BB; } Copied: llvm/trunk/lib/CodeGen/ScheduleDAGPrinter.cpp (from r59660, llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp) URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ScheduleDAGPrinter.cpp?p2=llvm/trunk/lib/CodeGen/ScheduleDAGPrinter.cpp&p1=llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp&r1=59660&r2=59676&rev=59676&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp (original) +++ llvm/trunk/lib/CodeGen/ScheduleDAGPrinter.cpp Wed Nov 19 17:18:57 2008 @@ -1,4 +1,4 @@ -//===-- SelectionDAGPrinter.cpp - Implement SelectionDAG::viewGraph() -----===// +//===-- ScheduleDAGPrinter.cpp - Implement ScheduleDAG::viewGraph() -------===// // // The LLVM Compiler Infrastructure // @@ -7,14 +7,13 @@ // //===----------------------------------------------------------------------===// // -// This implements the SelectionDAG::viewGraph method. +// This implements the ScheduleDAG::viewGraph method. // //===----------------------------------------------------------------------===// #include "llvm/Constants.h" #include "llvm/Function.h" #include "llvm/Assembly/Writer.h" -#include "llvm/CodeGen/SelectionDAG.h" #include "llvm/CodeGen/ScheduleDAG.h" #include "llvm/CodeGen/MachineConstantPool.h" #include "llvm/CodeGen/MachineFunction.h" @@ -33,358 +32,6 @@ namespace llvm { template<> - struct DOTGraphTraits : public DefaultDOTGraphTraits { - static bool hasEdgeDestLabels() { - return true; - } - - static unsigned numEdgeDestLabels(const void *Node) { - return ((const SDNode *) Node)->getNumValues(); - } - - static std::string getEdgeDestLabel(const void *Node, unsigned i) { - return ((const SDNode *) Node)->getValueType(i).getMVTString(); - } - - /// edgeTargetsEdgeSource - This method returns true if this outgoing edge - /// should actually target another edge source, not a node. If this method is - /// implemented, getEdgeTarget should be implemented. - template - static bool edgeTargetsEdgeSource(const void *Node, EdgeIter I) { - return true; - } - - /// getEdgeTarget - If edgeTargetsEdgeSource returns true, this method is - /// called to determine which outgoing edge of Node is the target of this - /// edge. - template - static EdgeIter getEdgeTarget(const void *Node, EdgeIter I) { - SDNode *TargetNode = *I; - SDNodeIterator NI = SDNodeIterator::begin(TargetNode); - std::advance(NI, I.getNode()->getOperand(I.getOperand()).getResNo()); - return NI; - } - - static std::string getGraphName(const SelectionDAG *G) { - return G->getMachineFunction().getFunction()->getName(); - } - - static bool renderGraphFromBottomUp() { - return true; - } - - static bool hasNodeAddressLabel(const SDNode *Node, - const SelectionDAG *Graph) { - return true; - } - - /// If you want to override the dot attributes printed for a particular - /// edge, override this method. - template - static std::string getEdgeAttributes(const void *Node, EdgeIter EI) { - SDValue Op = EI.getNode()->getOperand(EI.getOperand()); - MVT VT = Op.getValueType(); - if (VT == MVT::Flag) - return "color=red,style=bold"; - else if (VT == MVT::Other) - return "color=blue,style=dashed"; - return ""; - } - - - static std::string getNodeLabel(const SDNode *Node, - const SelectionDAG *Graph); - static std::string getNodeAttributes(const SDNode *N, - const SelectionDAG *Graph) { -#ifndef NDEBUG - const std::string &Attrs = Graph->getGraphAttrs(N); - if (!Attrs.empty()) { - if (Attrs.find("shape=") == std::string::npos) - return std::string("shape=Mrecord,") + Attrs; - else - return Attrs; - } -#endif - return "shape=Mrecord"; - } - - static void addCustomGraphFeatures(SelectionDAG *G, - GraphWriter &GW) { - GW.emitSimpleNode(0, "plaintext=circle", "GraphRoot"); - if (G->getRoot().getNode()) - GW.emitEdge(0, -1, G->getRoot().getNode(), G->getRoot().getResNo(), - "color=blue,style=dashed"); - } - }; -} - -std::string DOTGraphTraits::getNodeLabel(const SDNode *Node, - const SelectionDAG *G) { - std::string Op = Node->getOperationName(G); - - if (const ConstantSDNode *CSDN = dyn_cast(Node)) { - Op += ": " + utostr(CSDN->getZExtValue()); - } else if (const ConstantFPSDNode *CSDN = dyn_cast(Node)) { - Op += ": " + ftostr(CSDN->getValueAPF()); - } else if (const GlobalAddressSDNode *GADN = - dyn_cast(Node)) { - Op += ": " + GADN->getGlobal()->getName(); - if (int64_t Offset = GADN->getOffset()) { - if (Offset > 0) - Op += "+" + itostr(Offset); - else - Op += itostr(Offset); - } - } else if (const FrameIndexSDNode *FIDN = dyn_cast(Node)) { - Op += " " + itostr(FIDN->getIndex()); - } else if (const JumpTableSDNode *JTDN = dyn_cast(Node)) { - Op += " " + itostr(JTDN->getIndex()); - } else if (const ConstantPoolSDNode *CP = dyn_cast(Node)){ - if (CP->isMachineConstantPoolEntry()) { - Op += '<'; - { - raw_string_ostream OSS(Op); - OSS << *CP->getMachineCPVal(); - } - Op += '>'; - } else { - if (ConstantFP *CFP = dyn_cast(CP->getConstVal())) - Op += "<" + ftostr(CFP->getValueAPF()) + ">"; - else if (ConstantInt *CI = dyn_cast(CP->getConstVal())) - Op += "<" + utostr(CI->getZExtValue()) + ">"; - else { - Op += '<'; - { - raw_string_ostream OSS(Op); - WriteAsOperand(OSS, CP->getConstVal(), false); - } - Op += '>'; - } - } - Op += " A=" + itostr(1 << CP->getAlignment()); - } else if (const BasicBlockSDNode *BBDN = dyn_cast(Node)) { - Op = "BB: "; - const Value *LBB = (const Value*)BBDN->getBasicBlock()->getBasicBlock(); - if (LBB) - Op += LBB->getName(); - //Op += " " + (const void*)BBDN->getBasicBlock(); - } else if (const RegisterSDNode *R = dyn_cast(Node)) { - if (G && R->getReg() != 0 && - TargetRegisterInfo::isPhysicalRegister(R->getReg())) { - Op = Op + " " + - G->getTarget().getRegisterInfo()->getName(R->getReg()); - } else { - Op += " #" + utostr(R->getReg()); - } - } else if (const DbgStopPointSDNode *D = dyn_cast(Node)) { - Op += ": " + D->getCompileUnit()->getFileName(); - Op += ":" + utostr(D->getLine()); - if (D->getColumn() != 0) - Op += ":" + utostr(D->getColumn()); - } else if (const LabelSDNode *L = dyn_cast(Node)) { - Op += ": LabelID=" + utostr(L->getLabelID()); - } else if (const CallSDNode *C = dyn_cast(Node)) { - Op += ": CallingConv=" + utostr(C->getCallingConv()); - if (C->isVarArg()) - Op += ", isVarArg"; - if (C->isTailCall()) - Op += ", isTailCall"; - } else if (const ExternalSymbolSDNode *ES = - dyn_cast(Node)) { - Op += "'" + std::string(ES->getSymbol()) + "'"; - } else if (const SrcValueSDNode *M = dyn_cast(Node)) { - if (M->getValue()) - Op += "<" + M->getValue()->getName() + ">"; - else - Op += ""; - } else if (const MemOperandSDNode *M = dyn_cast(Node)) { - const Value *V = M->MO.getValue(); - Op += '<'; - if (!V) { - Op += "(unknown)"; - } else if (isa(V)) { - // PseudoSourceValues don't have names, so use their print method. - { - raw_string_ostream OSS(Op); - OSS << *M->MO.getValue(); - } - } else { - Op += V->getName(); - } - Op += '+' + itostr(M->MO.getOffset()) + '>'; - } else if (const ARG_FLAGSSDNode *N = dyn_cast(Node)) { - Op = Op + " AF=" + N->getArgFlags().getArgFlagsString(); - } else if (const VTSDNode *N = dyn_cast(Node)) { - Op = Op + " VT=" + N->getVT().getMVTString(); - } else if (const LoadSDNode *LD = dyn_cast(Node)) { - bool doExt = true; - switch (LD->getExtensionType()) { - default: doExt = false; break; - case ISD::EXTLOAD: - Op = Op + "getMemoryVT().getMVTString() + ">"; - if (LD->isVolatile()) - Op += ""; - Op += LD->getIndexedModeName(LD->getAddressingMode()); - if (LD->getAlignment() > 1) - Op += " A=" + utostr(LD->getAlignment()); - } else if (const StoreSDNode *ST = dyn_cast(Node)) { - if (ST->isTruncatingStore()) - Op += "getMemoryVT().getMVTString() + ">"; - if (ST->isVolatile()) - Op += ""; - Op += ST->getIndexedModeName(ST->getAddressingMode()); - if (ST->getAlignment() > 1) - Op += " A=" + utostr(ST->getAlignment()); - } - -#if 0 - Op += " Id=" + itostr(Node->getNodeId()); -#endif - - return Op; -} - - -/// viewGraph - Pop up a ghostview window with the reachable parts of the DAG -/// rendered using 'dot'. -/// -void SelectionDAG::viewGraph(const std::string &Title) { -// This code is only for debugging! -#ifndef NDEBUG - ViewGraph(this, "dag." + getMachineFunction().getFunction()->getName(), - Title); -#else - cerr << "SelectionDAG::viewGraph is only available in debug builds on " - << "systems with Graphviz or gv!\n"; -#endif // NDEBUG -} - -// This overload is defined out-of-line here instead of just using a -// default parameter because this is easiest for gdb to call. -void SelectionDAG::viewGraph() { - viewGraph(""); -} - -/// clearGraphAttrs - Clear all previously defined node graph attributes. -/// Intended to be used from a debugging tool (eg. gdb). -void SelectionDAG::clearGraphAttrs() { -#ifndef NDEBUG - NodeGraphAttrs.clear(); -#else - cerr << "SelectionDAG::clearGraphAttrs is only available in debug builds" - << " on systems with Graphviz or gv!\n"; -#endif -} - - -/// setGraphAttrs - Set graph attributes for a node. (eg. "color=red".) -/// -void SelectionDAG::setGraphAttrs(const SDNode *N, const char *Attrs) { -#ifndef NDEBUG - NodeGraphAttrs[N] = Attrs; -#else - cerr << "SelectionDAG::setGraphAttrs is only available in debug builds" - << " on systems with Graphviz or gv!\n"; -#endif -} - - -/// getGraphAttrs - Get graph attributes for a node. (eg. "color=red".) -/// Used from getNodeAttributes. -const std::string SelectionDAG::getGraphAttrs(const SDNode *N) const { -#ifndef NDEBUG - std::map::const_iterator I = - NodeGraphAttrs.find(N); - - if (I != NodeGraphAttrs.end()) - return I->second; - else - return ""; -#else - cerr << "SelectionDAG::getGraphAttrs is only available in debug builds" - << " on systems with Graphviz or gv!\n"; - return std::string(""); -#endif -} - -/// setGraphColor - Convenience for setting node color attribute. -/// -void SelectionDAG::setGraphColor(const SDNode *N, const char *Color) { -#ifndef NDEBUG - NodeGraphAttrs[N] = std::string("color=") + Color; -#else - cerr << "SelectionDAG::setGraphColor is only available in debug builds" - << " on systems with Graphviz or gv!\n"; -#endif -} - -/// setSubgraphColorHelper - Implement setSubgraphColor. Return -/// whether we truncated the search. -/// -bool SelectionDAG::setSubgraphColorHelper(SDNode *N, const char *Color, DenseSet &visited, - int level, bool &printed) { - bool hit_limit = false; - -#ifndef NDEBUG - if (level >= 20) { - if (!printed) { - printed = true; - DOUT << "setSubgraphColor hit max level\n"; - } - return true; - } - - unsigned oldSize = visited.size(); - visited.insert(N); - if (visited.size() != oldSize) { - setGraphColor(N, Color); - for(SDNodeIterator i = SDNodeIterator::begin(N), iend = SDNodeIterator::end(N); - i != iend; - ++i) { - hit_limit = setSubgraphColorHelper(*i, Color, visited, level+1, printed) || hit_limit; - } - } -#else - cerr << "SelectionDAG::setSubgraphColor is only available in debug builds" - << " on systems with Graphviz or gv!\n"; -#endif - return hit_limit; -} - -/// setSubgraphColor - Convenience for setting subgraph color attribute. -/// -void SelectionDAG::setSubgraphColor(SDNode *N, const char *Color) { -#ifndef NDEBUG - DenseSet visited; - bool printed = false; - if (setSubgraphColorHelper(N, Color, visited, 0, printed)) { - // Visually mark that we hit the limit - if (strcmp(Color, "red") == 0) { - setSubgraphColorHelper(N, "blue", visited, 0, printed); - } - else if (strcmp(Color, "yellow") == 0) { - setSubgraphColorHelper(N, "green", visited, 0, printed); - } - } - -#else - cerr << "SelectionDAG::setSubgraphColor is only available in debug builds" - << " on systems with Graphviz or gv!\n"; -#endif -} - -namespace llvm { - template<> struct DOTGraphTraits : public DefaultDOTGraphTraits { static std::string getGraphName(const ScheduleDAG *G) { return G->MF->getFunction()->getName(); @@ -420,56 +67,16 @@ static void addCustomGraphFeatures(ScheduleDAG *G, GraphWriter &GW) { - // Draw a special "GraphRoot" node to indicate the root of the graph. - GW.emitSimpleNode(0, "plaintext=circle", "GraphRoot"); - if (G->DAG) { - // For an SDNode-based ScheduleDAG, point to the root of the ScheduleDAG. - const SDNode *N = G->DAG->getRoot().getNode(); - if (N && N->getNodeId() != -1) - GW.emitEdge(0, -1, &G->SUnits[N->getNodeId()], -1, - "color=blue,style=dashed"); - } else { - // For a MachineInstr-based ScheduleDAG, find a root to point to. - for (unsigned i = 0, e = G->SUnits.size(); i != e; ++i) { - if (G->SUnits[i].Succs.empty()) { - GW.emitEdge(0, -1, &G->SUnits[i], -1, - "color=blue,style=dashed"); - break; - } - } - } + return G->addCustomGraphFeatures(GW); } }; } std::string DOTGraphTraits::getNodeLabel(const SUnit *SU, const ScheduleDAG *G) { - std::string Op; - - if (G->DAG) { - if (!SU->getNode()) - Op = ""; - else { - SmallVector FlaggedNodes; - for (SDNode *N = SU->getNode(); N; N = N->getFlaggedNode()) - FlaggedNodes.push_back(N); - while (!FlaggedNodes.empty()) { - Op += DOTGraphTraits::getNodeLabel(FlaggedNodes.back(), - G->DAG) + "\n"; - FlaggedNodes.pop_back(); - } - } - } else { - std::string s; - raw_string_ostream oss(s); - SU->getInstr()->print(oss); - Op += oss.str(); - } - - return Op; + return G->getGraphNodeLabel(SU); } - /// viewGraph - Pop up a ghostview window with the reachable parts of the DAG /// rendered using 'dot'. /// Modified: llvm/trunk/lib/CodeGen/SelectionDAG/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/CMakeLists.txt?rev=59676&r1=59675&r2=59676&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/CMakeLists.txt (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/CMakeLists.txt Wed Nov 19 17:18:57 2008 @@ -2,15 +2,14 @@ CallingConvLower.cpp DAGCombiner.cpp FastISel.cpp - LatencyPriorityQueue.cpp LegalizeDAG.cpp LegalizeFloatTypes.cpp LegalizeIntegerTypes.cpp LegalizeTypes.cpp LegalizeTypesGeneric.cpp LegalizeVectorTypes.cpp - ScheduleDAG.cpp - ScheduleDAGEmit.cpp + ScheduleDAGSDNodes.cpp + ScheduleDAGSDNodesEmit.cpp ScheduleDAGFast.cpp ScheduleDAGList.cpp ScheduleDAGRRList.cpp Removed: llvm/trunk/lib/CodeGen/SelectionDAG/LatencyPriorityQueue.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LatencyPriorityQueue.cpp?rev=59675&view=auto ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LatencyPriorityQueue.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LatencyPriorityQueue.cpp (removed) @@ -1,165 +0,0 @@ -//===---- LatencyPriorityQueue.cpp - A latency-oriented priority queue ----===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the LatencyPriorityQueue class, which is a -// SchedulingPriorityQueue that schedules using latency information to -// reduce the length of the critical path through the basic block. -// -//===----------------------------------------------------------------------===// - -#define DEBUG_TYPE "scheduler" -#include "LatencyPriorityQueue.h" -#include "llvm/Support/Debug.h" -using namespace llvm; - -bool latency_sort::operator()(const SUnit *LHS, const SUnit *RHS) const { - unsigned LHSNum = LHS->NodeNum; - unsigned RHSNum = RHS->NodeNum; - - // The most important heuristic is scheduling the critical path. - unsigned LHSLatency = PQ->getLatency(LHSNum); - unsigned RHSLatency = PQ->getLatency(RHSNum); - if (LHSLatency < RHSLatency) return true; - if (LHSLatency > RHSLatency) return false; - - // After that, if two nodes have identical latencies, look to see if one will - // unblock more other nodes than the other. - unsigned LHSBlocked = PQ->getNumSolelyBlockNodes(LHSNum); - unsigned RHSBlocked = PQ->getNumSolelyBlockNodes(RHSNum); - if (LHSBlocked < RHSBlocked) return true; - if (LHSBlocked > RHSBlocked) return false; - - // Finally, just to provide a stable ordering, use the node number as a - // deciding factor. - return LHSNum < RHSNum; -} - - -/// CalcNodePriority - Calculate the maximal path from the node to the exit. -/// -int LatencyPriorityQueue::CalcLatency(const SUnit &SU) { - int &Latency = Latencies[SU.NodeNum]; - if (Latency != -1) - return Latency; - - std::vector WorkList; - WorkList.push_back(&SU); - while (!WorkList.empty()) { - const SUnit *Cur = WorkList.back(); - bool AllDone = true; - int MaxSuccLatency = 0; - for (SUnit::const_succ_iterator I = Cur->Succs.begin(),E = Cur->Succs.end(); - I != E; ++I) { - int SuccLatency = Latencies[I->Dep->NodeNum]; - if (SuccLatency == -1) { - AllDone = false; - WorkList.push_back(I->Dep); - } else { - MaxSuccLatency = std::max(MaxSuccLatency, SuccLatency); - } - } - if (AllDone) { - Latencies[Cur->NodeNum] = MaxSuccLatency + Cur->Latency; - WorkList.pop_back(); - } - } - - return Latency; -} - -/// CalculatePriorities - Calculate priorities of all scheduling units. -void LatencyPriorityQueue::CalculatePriorities() { - Latencies.assign(SUnits->size(), -1); - NumNodesSolelyBlocking.assign(SUnits->size(), 0); - - // For each node, calculate the maximal path from the node to the exit. - std::vector > WorkList; - for (unsigned i = 0, e = SUnits->size(); i != e; ++i) { - const SUnit *SU = &(*SUnits)[i]; - if (SU->Succs.empty()) - WorkList.push_back(std::make_pair(SU, 0U)); - } - - while (!WorkList.empty()) { - const SUnit *SU = WorkList.back().first; - unsigned SuccLat = WorkList.back().second; - WorkList.pop_back(); - int &Latency = Latencies[SU->NodeNum]; - if (Latency == -1 || (SU->Latency + SuccLat) > (unsigned)Latency) { - Latency = SU->Latency + SuccLat; - for (SUnit::const_pred_iterator I = SU->Preds.begin(),E = SU->Preds.end(); - I != E; ++I) - WorkList.push_back(std::make_pair(I->Dep, Latency)); - } - } -} - -/// getSingleUnscheduledPred - If there is exactly one unscheduled predecessor -/// of SU, return it, otherwise return null. -SUnit *LatencyPriorityQueue::getSingleUnscheduledPred(SUnit *SU) { - SUnit *OnlyAvailablePred = 0; - for (SUnit::const_pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); - I != E; ++I) { - SUnit &Pred = *I->Dep; - if (!Pred.isScheduled) { - // We found an available, but not scheduled, predecessor. If it's the - // only one we have found, keep track of it... otherwise give up. - if (OnlyAvailablePred && OnlyAvailablePred != &Pred) - return 0; - OnlyAvailablePred = &Pred; - } - } - - return OnlyAvailablePred; -} - -void LatencyPriorityQueue::push_impl(SUnit *SU) { - // Look at all of the successors of this node. Count the number of nodes that - // this node is the sole unscheduled node for. - unsigned NumNodesBlocking = 0; - for (SUnit::const_succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); - I != E; ++I) - if (getSingleUnscheduledPred(I->Dep) == SU) - ++NumNodesBlocking; - NumNodesSolelyBlocking[SU->NodeNum] = NumNodesBlocking; - - Queue.push(SU); -} - - -// ScheduledNode - As nodes are scheduled, we look to see if there are any -// successor nodes that have a single unscheduled predecessor. If so, that -// single predecessor has a higher priority, since scheduling it will make -// the node available. -void LatencyPriorityQueue::ScheduledNode(SUnit *SU) { - for (SUnit::const_succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); - I != E; ++I) - AdjustPriorityOfUnscheduledPreds(I->Dep); -} - -/// AdjustPriorityOfUnscheduledPreds - One of the predecessors of SU was just -/// scheduled. If SU is not itself available, then there is at least one -/// predecessor node that has not been scheduled yet. If SU has exactly ONE -/// unscheduled predecessor, we want to increase its priority: it getting -/// scheduled will make this node available, so it is better than some other -/// node of the same priority that will not make a node available. -void LatencyPriorityQueue::AdjustPriorityOfUnscheduledPreds(SUnit *SU) { - if (SU->isAvailable) return; // All preds scheduled. - - SUnit *OnlyAvailablePred = getSingleUnscheduledPred(SU); - if (OnlyAvailablePred == 0 || !OnlyAvailablePred->isAvailable) return; - - // Okay, we found a single predecessor that is available, but not scheduled. - // Since it is available, it must be in the priority queue. First remove it. - remove(OnlyAvailablePred); - - // Reinsert the node into the priority queue, which recomputes its - // NumNodesSolelyBlocking value. - push(OnlyAvailablePred); -} Removed: llvm/trunk/lib/CodeGen/SelectionDAG/LatencyPriorityQueue.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LatencyPriorityQueue.h?rev=59675&view=auto ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LatencyPriorityQueue.h (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LatencyPriorityQueue.h (removed) @@ -1,124 +0,0 @@ -//===---- LatencyPriorityQueue.h - A latency-oriented priority queue ------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file declares the LatencyPriorityQueue class, which is a -// SchedulingPriorityQueue that schedules using latency information to -// reduce the length of the critical path through the basic block. -// -//===----------------------------------------------------------------------===// - -#ifndef LATENCY_PRIORITY_QUEUE_H -#define LATENCY_PRIORITY_QUEUE_H - -#include "llvm/CodeGen/ScheduleDAG.h" -#include "llvm/ADT/PriorityQueue.h" - -namespace llvm { - class LatencyPriorityQueue; - - /// Sorting functions for the Available queue. - struct latency_sort : public std::binary_function { - LatencyPriorityQueue *PQ; - explicit latency_sort(LatencyPriorityQueue *pq) : PQ(pq) {} - - bool operator()(const SUnit* left, const SUnit* right) const; - }; - - class LatencyPriorityQueue : public SchedulingPriorityQueue { - // SUnits - The SUnits for the current graph. - std::vector *SUnits; - - // Latencies - The latency (max of latency from this node to the bb exit) - // for each node. - std::vector Latencies; - - /// NumNodesSolelyBlocking - This vector contains, for every node in the - /// Queue, the number of nodes that the node is the sole unscheduled - /// predecessor for. This is used as a tie-breaker heuristic for better - /// mobility. - std::vector NumNodesSolelyBlocking; - - PriorityQueue, latency_sort> Queue; - public: - LatencyPriorityQueue() : Queue(latency_sort(this)) { - } - - void initNodes(std::vector &sunits) { - SUnits = &sunits; - // Calculate node priorities. - CalculatePriorities(); - } - - void addNode(const SUnit *SU) { - Latencies.resize(SUnits->size(), -1); - NumNodesSolelyBlocking.resize(SUnits->size(), 0); - CalcLatency(*SU); - } - - void updateNode(const SUnit *SU) { - Latencies[SU->NodeNum] = -1; - CalcLatency(*SU); - } - - void releaseState() { - SUnits = 0; - Latencies.clear(); - } - - unsigned getLatency(unsigned NodeNum) const { - assert(NodeNum < Latencies.size()); - return Latencies[NodeNum]; - } - - unsigned getNumSolelyBlockNodes(unsigned NodeNum) const { - assert(NodeNum < NumNodesSolelyBlocking.size()); - return NumNodesSolelyBlocking[NodeNum]; - } - - unsigned size() const { return Queue.size(); } - - bool empty() const { return Queue.empty(); } - - virtual void push(SUnit *U) { - push_impl(U); - } - void push_impl(SUnit *U); - - void push_all(const std::vector &Nodes) { - for (unsigned i = 0, e = Nodes.size(); i != e; ++i) - push_impl(Nodes[i]); - } - - SUnit *pop() { - if (empty()) return NULL; - SUnit *V = Queue.top(); - Queue.pop(); - return V; - } - - void remove(SUnit *SU) { - assert(!Queue.empty() && "Not in queue!"); - Queue.erase_one(SU); - } - - // ScheduledNode - As nodes are scheduled, we look to see if there are any - // successor nodes that have a single unscheduled predecessor. If so, that - // single predecessor has a higher priority, since scheduling it will make - // the node available. - void ScheduledNode(SUnit *Node); - - private: - void CalculatePriorities(); - int CalcLatency(const SUnit &SU); - void AdjustPriorityOfUnscheduledPreds(SUnit *SU); - SUnit *getSingleUnscheduledPred(SUnit *SU); - }; -} - -#endif Removed: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp?rev=59675&view=auto ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp (removed) @@ -1,522 +0,0 @@ -//===---- ScheduleDAG.cpp - Implement the ScheduleDAG class ---------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This implements the ScheduleDAG class, which is a base class used by -// scheduling implementation classes. -// -//===----------------------------------------------------------------------===// - -#define DEBUG_TYPE "pre-RA-sched" -#include "llvm/CodeGen/ScheduleDAG.h" -#include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetInstrInfo.h" -#include "llvm/Target/TargetRegisterInfo.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/raw_ostream.h" -using namespace llvm; - -ScheduleDAG::ScheduleDAG(SelectionDAG *dag, MachineBasicBlock *bb, - const TargetMachine &tm) - : DAG(dag), BB(bb), TM(tm), MRI(BB->getParent()->getRegInfo()) { - TII = TM.getInstrInfo(); - MF = BB->getParent(); - TRI = TM.getRegisterInfo(); - TLI = TM.getTargetLowering(); - ConstPool = MF->getConstantPool(); -} - -/// CheckForPhysRegDependency - Check if the dependency between def and use of -/// a specified operand is a physical register dependency. If so, returns the -/// register and the cost of copying the register. -static void CheckForPhysRegDependency(SDNode *Def, SDNode *User, unsigned Op, - const TargetRegisterInfo *TRI, - const TargetInstrInfo *TII, - unsigned &PhysReg, int &Cost) { - if (Op != 2 || User->getOpcode() != ISD::CopyToReg) - return; - - unsigned Reg = cast(User->getOperand(1))->getReg(); - if (TargetRegisterInfo::isVirtualRegister(Reg)) - return; - - unsigned ResNo = User->getOperand(2).getResNo(); - if (Def->isMachineOpcode()) { - const TargetInstrDesc &II = TII->get(Def->getMachineOpcode()); - if (ResNo >= II.getNumDefs() && - II.ImplicitDefs[ResNo - II.getNumDefs()] == Reg) { - PhysReg = Reg; - const TargetRegisterClass *RC = - TRI->getPhysicalRegisterRegClass(Reg, Def->getValueType(ResNo)); - Cost = RC->getCopyCost(); - } - } -} - -SUnit *ScheduleDAG::Clone(SUnit *Old) { - SUnit *SU = NewSUnit(Old->getNode()); - SU->OrigNode = Old->OrigNode; - SU->Latency = Old->Latency; - SU->isTwoAddress = Old->isTwoAddress; - SU->isCommutable = Old->isCommutable; - SU->hasPhysRegDefs = Old->hasPhysRegDefs; - return SU; -} - - -/// BuildSchedUnits - Build SUnits from the selection dag that we are input. -/// This SUnit graph is similar to the SelectionDAG, but represents flagged -/// together nodes with a single SUnit. -void ScheduleDAG::BuildSchedUnits() { - // For post-regalloc scheduling, build the SUnits from the MachineInstrs - // in the MachineBasicBlock. - if (!DAG) { - BuildSchedUnitsFromMBB(); - return; - } - - // Reserve entries in the vector for each of the SUnits we are creating. This - // ensure that reallocation of the vector won't happen, so SUnit*'s won't get - // invalidated. - SUnits.reserve(DAG->allnodes_size()); - - // During scheduling, the NodeId field of SDNode is used to map SDNodes - // to their associated SUnits by holding SUnits table indices. A value - // of -1 means the SDNode does not yet have an associated SUnit. - for (SelectionDAG::allnodes_iterator NI = DAG->allnodes_begin(), - E = DAG->allnodes_end(); NI != E; ++NI) - NI->setNodeId(-1); - - for (SelectionDAG::allnodes_iterator NI = DAG->allnodes_begin(), - E = DAG->allnodes_end(); NI != E; ++NI) { - if (isPassiveNode(NI)) // Leaf node, e.g. a TargetImmediate. - continue; - - // If this node has already been processed, stop now. - if (NI->getNodeId() != -1) continue; - - SUnit *NodeSUnit = NewSUnit(NI); - - // See if anything is flagged to this node, if so, add them to flagged - // nodes. Nodes can have at most one flag input and one flag output. Flags - // are required the be the last operand and result of a node. - - // Scan up to find flagged preds. - SDNode *N = NI; - if (N->getNumOperands() && - N->getOperand(N->getNumOperands()-1).getValueType() == MVT::Flag) { - do { - N = N->getOperand(N->getNumOperands()-1).getNode(); - assert(N->getNodeId() == -1 && "Node already inserted!"); - N->setNodeId(NodeSUnit->NodeNum); - } while (N->getNumOperands() && - N->getOperand(N->getNumOperands()-1).getValueType()== MVT::Flag); - } - - // Scan down to find any flagged succs. - N = NI; - while (N->getValueType(N->getNumValues()-1) == MVT::Flag) { - SDValue FlagVal(N, N->getNumValues()-1); - - // There are either zero or one users of the Flag result. - bool HasFlagUse = false; - for (SDNode::use_iterator UI = N->use_begin(), E = N->use_end(); - UI != E; ++UI) - if (FlagVal.isOperandOf(*UI)) { - HasFlagUse = true; - assert(N->getNodeId() == -1 && "Node already inserted!"); - N->setNodeId(NodeSUnit->NodeNum); - N = *UI; - break; - } - if (!HasFlagUse) break; - } - - // If there are flag operands involved, N is now the bottom-most node - // of the sequence of nodes that are flagged together. - // Update the SUnit. - NodeSUnit->setNode(N); - assert(N->getNodeId() == -1 && "Node already inserted!"); - N->setNodeId(NodeSUnit->NodeNum); - - ComputeLatency(NodeSUnit); - } - - // Pass 2: add the preds, succs, etc. - for (unsigned su = 0, e = SUnits.size(); su != e; ++su) { - SUnit *SU = &SUnits[su]; - SDNode *MainNode = SU->getNode(); - - if (MainNode->isMachineOpcode()) { - unsigned Opc = MainNode->getMachineOpcode(); - const TargetInstrDesc &TID = TII->get(Opc); - for (unsigned i = 0; i != TID.getNumOperands(); ++i) { - if (TID.getOperandConstraint(i, TOI::TIED_TO) != -1) { - SU->isTwoAddress = true; - break; - } - } - if (TID.isCommutable()) - SU->isCommutable = true; - } - - // Find all predecessors and successors of the group. - for (SDNode *N = SU->getNode(); N; N = N->getFlaggedNode()) { - if (N->isMachineOpcode() && - TII->get(N->getMachineOpcode()).getImplicitDefs() && - CountResults(N) > TII->get(N->getMachineOpcode()).getNumDefs()) - SU->hasPhysRegDefs = true; - - for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { - SDNode *OpN = N->getOperand(i).getNode(); - if (isPassiveNode(OpN)) continue; // Not scheduled. - SUnit *OpSU = &SUnits[OpN->getNodeId()]; - assert(OpSU && "Node has no SUnit!"); - if (OpSU == SU) continue; // In the same group. - - MVT OpVT = N->getOperand(i).getValueType(); - assert(OpVT != MVT::Flag && "Flagged nodes should be in same sunit!"); - bool isChain = OpVT == MVT::Other; - - unsigned PhysReg = 0; - int Cost = 1; - // Determine if this is a physical register dependency. - CheckForPhysRegDependency(OpN, N, i, TRI, TII, PhysReg, Cost); - SU->addPred(OpSU, isChain, false, PhysReg, Cost); - } - } - } -} - -void ScheduleDAG::BuildSchedUnitsFromMBB() { - SUnits.clear(); - SUnits.reserve(BB->size()); - - std::vector PendingLoads; - SUnit *Terminator = 0; - SUnit *Chain = 0; - SUnit *Defs[TargetRegisterInfo::FirstVirtualRegister] = {}; - std::vector Uses[TargetRegisterInfo::FirstVirtualRegister] = {}; - int Cost = 1; // FIXME - - for (MachineBasicBlock::iterator MII = BB->end(), MIE = BB->begin(); - MII != MIE; --MII) { - MachineInstr *MI = prior(MII); - SUnit *SU = NewSUnit(MI); - - for (unsigned j = 0, n = MI->getNumOperands(); j != n; ++j) { - const MachineOperand &MO = MI->getOperand(j); - if (!MO.isReg()) continue; - unsigned Reg = MO.getReg(); - if (Reg == 0) continue; - - assert(TRI->isPhysicalRegister(Reg) && "Virtual register encountered!"); - std::vector &UseList = Uses[Reg]; - SUnit *&Def = Defs[Reg]; - // Optionally add output and anti dependences - if (Def && Def != SU) - Def->addPred(SU, /*isCtrl=*/true, /*isSpecial=*/false, - /*PhyReg=*/Reg, Cost); - for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { - SUnit *&Def = Defs[*Alias]; - if (Def && Def != SU) - Def->addPred(SU, /*isCtrl=*/true, /*isSpecial=*/false, - /*PhyReg=*/*Alias, Cost); - } - - if (MO.isDef()) { - // Add any data dependencies. - for (unsigned i = 0, e = UseList.size(); i != e; ++i) - if (UseList[i] != SU) - UseList[i]->addPred(SU, /*isCtrl=*/false, /*isSpecial=*/false, - /*PhysReg=*/Reg, Cost); - for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { - std::vector &UseList = Uses[*Alias]; - for (unsigned i = 0, e = UseList.size(); i != e; ++i) - if (UseList[i] != SU) - UseList[i]->addPred(SU, /*isCtrl=*/false, /*isSpecial=*/false, - /*PhysReg=*/*Alias, Cost); - } - - UseList.clear(); - Def = SU; - } else { - UseList.push_back(SU); - } - } - bool False = false; - bool True = true; - if (!MI->isSafeToMove(TII, False)) { - if (Chain) - Chain->addPred(SU, /*isCtrl=*/false, /*isSpecial=*/false); - for (unsigned k = 0, m = PendingLoads.size(); k != m; ++k) - PendingLoads[k]->addPred(SU, /*isCtrl=*/false, /*isSpecial=*/false); - PendingLoads.clear(); - Chain = SU; - } else if (!MI->isSafeToMove(TII, True)) { - if (Chain) - Chain->addPred(SU, /*isCtrl=*/false, /*isSpecial=*/false); - PendingLoads.push_back(SU); - } - if (Terminator && SU->Succs.empty()) - Terminator->addPred(SU, /*isCtrl=*/false, /*isSpecial=*/false); - if (MI->getDesc().isTerminator()) - Terminator = SU; - } -} - -void ScheduleDAG::ComputeLatency(SUnit *SU) { - const InstrItineraryData &InstrItins = TM.getInstrItineraryData(); - - // Compute the latency for the node. We use the sum of the latencies for - // all nodes flagged together into this SUnit. - if (InstrItins.isEmpty()) { - // No latency information. - SU->Latency = 1; - return; - } - - SU->Latency = 0; - for (SDNode *N = SU->getNode(); N; N = N->getFlaggedNode()) { - if (N->isMachineOpcode()) { - unsigned SchedClass = TII->get(N->getMachineOpcode()).getSchedClass(); - const InstrStage *S = InstrItins.begin(SchedClass); - const InstrStage *E = InstrItins.end(SchedClass); - for (; S != E; ++S) - SU->Latency += S->Cycles; - } - } -} - -/// CalculateDepths - compute depths using algorithms for the longest -/// paths in the DAG -void ScheduleDAG::CalculateDepths() { - unsigned DAGSize = SUnits.size(); - std::vector WorkList; - WorkList.reserve(DAGSize); - - // Initialize the data structures - for (unsigned i = 0, e = DAGSize; i != e; ++i) { - SUnit *SU = &SUnits[i]; - unsigned Degree = SU->Preds.size(); - // Temporarily use the Depth field as scratch space for the degree count. - SU->Depth = Degree; - - // Is it a node without dependencies? - if (Degree == 0) { - assert(SU->Preds.empty() && "SUnit should have no predecessors"); - // Collect leaf nodes - WorkList.push_back(SU); - } - } - - // Process nodes in the topological order - while (!WorkList.empty()) { - SUnit *SU = WorkList.back(); - WorkList.pop_back(); - unsigned SUDepth = 0; - - // Use dynamic programming: - // When current node is being processed, all of its dependencies - // are already processed. - // So, just iterate over all predecessors and take the longest path - for (SUnit::const_pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); - I != E; ++I) { - unsigned PredDepth = I->Dep->Depth; - if (PredDepth+1 > SUDepth) { - SUDepth = PredDepth + 1; - } - } - - SU->Depth = SUDepth; - - // Update degrees of all nodes depending on current SUnit - for (SUnit::const_succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); - I != E; ++I) { - SUnit *SU = I->Dep; - if (!--SU->Depth) - // If all dependencies of the node are processed already, - // then the longest path for the node can be computed now - WorkList.push_back(SU); - } - } -} - -/// CalculateHeights - compute heights using algorithms for the longest -/// paths in the DAG -void ScheduleDAG::CalculateHeights() { - unsigned DAGSize = SUnits.size(); - std::vector WorkList; - WorkList.reserve(DAGSize); - - // Initialize the data structures - for (unsigned i = 0, e = DAGSize; i != e; ++i) { - SUnit *SU = &SUnits[i]; - unsigned Degree = SU->Succs.size(); - // Temporarily use the Height field as scratch space for the degree count. - SU->Height = Degree; - - // Is it a node without dependencies? - if (Degree == 0) { - assert(SU->Succs.empty() && "Something wrong"); - assert(WorkList.empty() && "Should be empty"); - // Collect leaf nodes - WorkList.push_back(SU); - } - } - - // Process nodes in the topological order - while (!WorkList.empty()) { - SUnit *SU = WorkList.back(); - WorkList.pop_back(); - unsigned SUHeight = 0; - - // Use dynamic programming: - // When current node is being processed, all of its dependencies - // are already processed. - // So, just iterate over all successors and take the longest path - for (SUnit::const_succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); - I != E; ++I) { - unsigned SuccHeight = I->Dep->Height; - if (SuccHeight+1 > SUHeight) { - SUHeight = SuccHeight + 1; - } - } - - SU->Height = SUHeight; - - // Update degrees of all nodes depending on current SUnit - for (SUnit::const_pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); - I != E; ++I) { - SUnit *SU = I->Dep; - if (!--SU->Height) - // If all dependencies of the node are processed already, - // then the longest path for the node can be computed now - WorkList.push_back(SU); - } - } -} - -/// CountResults - The results of target nodes have register or immediate -/// operands first, then an optional chain, and optional flag operands (which do -/// not go into the resulting MachineInstr). -unsigned ScheduleDAG::CountResults(SDNode *Node) { - unsigned N = Node->getNumValues(); - while (N && Node->getValueType(N - 1) == MVT::Flag) - --N; - if (N && Node->getValueType(N - 1) == MVT::Other) - --N; // Skip over chain result. - return N; -} - -/// CountOperands - The inputs to target nodes have any actual inputs first, -/// followed by special operands that describe memory references, then an -/// optional chain operand, then an optional flag operand. Compute the number -/// of actual operands that will go into the resulting MachineInstr. -unsigned ScheduleDAG::CountOperands(SDNode *Node) { - unsigned N = ComputeMemOperandsEnd(Node); - while (N && isa(Node->getOperand(N - 1).getNode())) - --N; // Ignore MEMOPERAND nodes - return N; -} - -/// ComputeMemOperandsEnd - Find the index one past the last MemOperandSDNode -/// operand -unsigned ScheduleDAG::ComputeMemOperandsEnd(SDNode *Node) { - unsigned N = Node->getNumOperands(); - while (N && Node->getOperand(N - 1).getValueType() == MVT::Flag) - --N; - if (N && Node->getOperand(N - 1).getValueType() == MVT::Other) - --N; // Ignore chain if it exists. - return N; -} - - -/// dump - dump the schedule. -void ScheduleDAG::dumpSchedule() const { - for (unsigned i = 0, e = Sequence.size(); i != e; i++) { - if (SUnit *SU = Sequence[i]) - SU->dump(this); - else - cerr << "**** NOOP ****\n"; - } -} - - -/// Run - perform scheduling. -/// -void ScheduleDAG::Run() { - Schedule(); - - DOUT << "*** Final schedule ***\n"; - DEBUG(dumpSchedule()); - DOUT << "\n"; -} - -/// SUnit - Scheduling unit. It's an wrapper around either a single SDNode or -/// a group of nodes flagged together. -void SUnit::print(raw_ostream &O, const ScheduleDAG *G) const { - O << "SU(" << NodeNum << "): "; - if (getNode()) { - SmallVector FlaggedNodes; - for (SDNode *N = getNode(); N; N = N->getFlaggedNode()) - FlaggedNodes.push_back(N); - while (!FlaggedNodes.empty()) { - O << " "; - FlaggedNodes.back()->print(O, G->DAG); - O << "\n"; - FlaggedNodes.pop_back(); - } - } else { - O << "CROSS RC COPY\n"; - } -} - -void SUnit::dump(const ScheduleDAG *G) const { - print(errs(), G); -} - -void SUnit::dumpAll(const ScheduleDAG *G) const { - dump(G); - - cerr << " # preds left : " << NumPredsLeft << "\n"; - cerr << " # succs left : " << NumSuccsLeft << "\n"; - cerr << " Latency : " << Latency << "\n"; - cerr << " Depth : " << Depth << "\n"; - cerr << " Height : " << Height << "\n"; - - if (Preds.size() != 0) { - cerr << " Predecessors:\n"; - for (SUnit::const_succ_iterator I = Preds.begin(), E = Preds.end(); - I != E; ++I) { - if (I->isCtrl) - cerr << " ch #"; - else - cerr << " val #"; - cerr << I->Dep << " - SU(" << I->Dep->NodeNum << ")"; - if (I->isSpecial) - cerr << " *"; - cerr << "\n"; - } - } - if (Succs.size() != 0) { - cerr << " Successors:\n"; - for (SUnit::const_succ_iterator I = Succs.begin(), E = Succs.end(); - I != E; ++I) { - if (I->isCtrl) - cerr << " ch #"; - else - cerr << " val #"; - cerr << I->Dep << " - SU(" << I->Dep->NodeNum << ")"; - if (I->isSpecial) - cerr << " *"; - cerr << "\n"; - } - } - cerr << "\n"; -} Removed: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGEmit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGEmit.cpp?rev=59675&view=auto ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGEmit.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGEmit.cpp (removed) @@ -1,717 +0,0 @@ -//===---- ScheduleDAGEmit.cpp - Emit routines for the ScheduleDAG class ---===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This implements the Emit routines for the ScheduleDAG class, which creates -// MachineInstrs according to the computed schedule. -// -//===----------------------------------------------------------------------===// - -#define DEBUG_TYPE "pre-RA-sched" -#include "llvm/CodeGen/ScheduleDAG.h" -#include "llvm/CodeGen/MachineConstantPool.h" -#include "llvm/CodeGen/MachineFunction.h" -#include "llvm/CodeGen/MachineInstrBuilder.h" -#include "llvm/CodeGen/MachineRegisterInfo.h" -#include "llvm/Target/TargetData.h" -#include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetInstrInfo.h" -#include "llvm/Target/TargetLowering.h" -#include "llvm/ADT/Statistic.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/MathExtras.h" -using namespace llvm; - -STATISTIC(NumCommutes, "Number of instructions commuted"); - -/// getInstrOperandRegClass - Return register class of the operand of an -/// instruction of the specified TargetInstrDesc. -static const TargetRegisterClass* -getInstrOperandRegClass(const TargetRegisterInfo *TRI, - const TargetInstrInfo *TII, const TargetInstrDesc &II, - unsigned Op) { - if (Op >= II.getNumOperands()) { - assert(II.isVariadic() && "Invalid operand # of instruction"); - return NULL; - } - if (II.OpInfo[Op].isLookupPtrRegClass()) - return TII->getPointerRegClass(); - return TRI->getRegClass(II.OpInfo[Op].RegClass); -} - -/// EmitCopyFromReg - Generate machine code for an CopyFromReg node or an -/// implicit physical register output. -void ScheduleDAG::EmitCopyFromReg(SDNode *Node, unsigned ResNo, - bool IsClone, unsigned SrcReg, - DenseMap &VRBaseMap) { - unsigned VRBase = 0; - if (TargetRegisterInfo::isVirtualRegister(SrcReg)) { - // Just use the input register directly! - SDValue Op(Node, ResNo); - if (IsClone) - VRBaseMap.erase(Op); - bool isNew = VRBaseMap.insert(std::make_pair(Op, SrcReg)).second; - isNew = isNew; // Silence compiler warning. - assert(isNew && "Node emitted out of order - early"); - return; - } - - // If the node is only used by a CopyToReg and the dest reg is a vreg, use - // the CopyToReg'd destination register instead of creating a new vreg. - bool MatchReg = true; - const TargetRegisterClass *UseRC = NULL; - for (SDNode::use_iterator UI = Node->use_begin(), E = Node->use_end(); - UI != E; ++UI) { - SDNode *User = *UI; - bool Match = true; - if (User->getOpcode() == ISD::CopyToReg && - User->getOperand(2).getNode() == Node && - User->getOperand(2).getResNo() == ResNo) { - unsigned DestReg = cast(User->getOperand(1))->getReg(); - if (TargetRegisterInfo::isVirtualRegister(DestReg)) { - VRBase = DestReg; - Match = false; - } else if (DestReg != SrcReg) - Match = false; - } else { - for (unsigned i = 0, e = User->getNumOperands(); i != e; ++i) { - SDValue Op = User->getOperand(i); - if (Op.getNode() != Node || Op.getResNo() != ResNo) - continue; - MVT VT = Node->getValueType(Op.getResNo()); - if (VT == MVT::Other || VT == MVT::Flag) - continue; - Match = false; - if (User->isMachineOpcode()) { - const TargetInstrDesc &II = TII->get(User->getMachineOpcode()); - const TargetRegisterClass *RC = - getInstrOperandRegClass(TRI,TII,II,i+II.getNumDefs()); - if (!UseRC) - UseRC = RC; - else if (RC) - assert(UseRC == RC && - "Multiple uses expecting different register classes!"); - } - } - } - MatchReg &= Match; - if (VRBase) - break; - } - - MVT VT = Node->getValueType(ResNo); - const TargetRegisterClass *SrcRC = 0, *DstRC = 0; - SrcRC = TRI->getPhysicalRegisterRegClass(SrcReg, VT); - - // Figure out the register class to create for the destreg. - if (VRBase) { - DstRC = MRI.getRegClass(VRBase); - } else if (UseRC) { - assert(UseRC->hasType(VT) && "Incompatible phys register def and uses!"); - DstRC = UseRC; - } else { - DstRC = TLI->getRegClassFor(VT); - } - - // If all uses are reading from the src physical register and copying the - // register is either impossible or very expensive, then don't create a copy. - if (MatchReg && SrcRC->getCopyCost() < 0) { - VRBase = SrcReg; - } else { - // Create the reg, emit the copy. - VRBase = MRI.createVirtualRegister(DstRC); - bool Emitted = - TII->copyRegToReg(*BB, BB->end(), VRBase, SrcReg, DstRC, SrcRC); - Emitted = Emitted; // Silence compiler warning. - assert(Emitted && "Unable to issue a copy instruction!"); - } - - SDValue Op(Node, ResNo); - if (IsClone) - VRBaseMap.erase(Op); - bool isNew = VRBaseMap.insert(std::make_pair(Op, VRBase)).second; - isNew = isNew; // Silence compiler warning. - assert(isNew && "Node emitted out of order - early"); -} - -/// getDstOfCopyToRegUse - If the only use of the specified result number of -/// node is a CopyToReg, return its destination register. Return 0 otherwise. -unsigned ScheduleDAG::getDstOfOnlyCopyToRegUse(SDNode *Node, - unsigned ResNo) const { - if (!Node->hasOneUse()) - return 0; - - SDNode *User = *Node->use_begin(); - if (User->getOpcode() == ISD::CopyToReg && - User->getOperand(2).getNode() == Node && - User->getOperand(2).getResNo() == ResNo) { - unsigned Reg = cast(User->getOperand(1))->getReg(); - if (TargetRegisterInfo::isVirtualRegister(Reg)) - return Reg; - } - return 0; -} - -void ScheduleDAG::CreateVirtualRegisters(SDNode *Node, MachineInstr *MI, - const TargetInstrDesc &II, - DenseMap &VRBaseMap) { - assert(Node->getMachineOpcode() != TargetInstrInfo::IMPLICIT_DEF && - "IMPLICIT_DEF should have been handled as a special case elsewhere!"); - - for (unsigned i = 0; i < II.getNumDefs(); ++i) { - // If the specific node value is only used by a CopyToReg and the dest reg - // is a vreg, use the CopyToReg'd destination register instead of creating - // a new vreg. - unsigned VRBase = 0; - for (SDNode::use_iterator UI = Node->use_begin(), E = Node->use_end(); - UI != E; ++UI) { - SDNode *User = *UI; - if (User->getOpcode() == ISD::CopyToReg && - User->getOperand(2).getNode() == Node && - User->getOperand(2).getResNo() == i) { - unsigned Reg = cast(User->getOperand(1))->getReg(); - if (TargetRegisterInfo::isVirtualRegister(Reg)) { - VRBase = Reg; - MI->addOperand(MachineOperand::CreateReg(Reg, true)); - break; - } - } - } - - // Create the result registers for this node and add the result regs to - // the machine instruction. - if (VRBase == 0) { - const TargetRegisterClass *RC = getInstrOperandRegClass(TRI, TII, II, i); - assert(RC && "Isn't a register operand!"); - VRBase = MRI.createVirtualRegister(RC); - MI->addOperand(MachineOperand::CreateReg(VRBase, true)); - } - - SDValue Op(Node, i); - bool isNew = VRBaseMap.insert(std::make_pair(Op, VRBase)).second; - isNew = isNew; // Silence compiler warning. - assert(isNew && "Node emitted out of order - early"); - } -} - -/// getVR - Return the virtual register corresponding to the specified result -/// of the specified node. -unsigned ScheduleDAG::getVR(SDValue Op, - DenseMap &VRBaseMap) { - if (Op.isMachineOpcode() && - Op.getMachineOpcode() == TargetInstrInfo::IMPLICIT_DEF) { - // Add an IMPLICIT_DEF instruction before every use. - unsigned VReg = getDstOfOnlyCopyToRegUse(Op.getNode(), Op.getResNo()); - // IMPLICIT_DEF can produce any type of result so its TargetInstrDesc - // does not include operand register class info. - if (!VReg) { - const TargetRegisterClass *RC = TLI->getRegClassFor(Op.getValueType()); - VReg = MRI.createVirtualRegister(RC); - } - BuildMI(BB, TII->get(TargetInstrInfo::IMPLICIT_DEF), VReg); - return VReg; - } - - DenseMap::iterator I = VRBaseMap.find(Op); - assert(I != VRBaseMap.end() && "Node emitted out of order - late"); - return I->second; -} - - -/// AddOperand - Add the specified operand to the specified machine instr. II -/// specifies the instruction information for the node, and IIOpNum is the -/// operand number (in the II) that we are adding. IIOpNum and II are used for -/// assertions only. -void ScheduleDAG::AddOperand(MachineInstr *MI, SDValue Op, - unsigned IIOpNum, - const TargetInstrDesc *II, - DenseMap &VRBaseMap) { - if (Op.isMachineOpcode()) { - // Note that this case is redundant with the final else block, but we - // include it because it is the most common and it makes the logic - // simpler here. - assert(Op.getValueType() != MVT::Other && - Op.getValueType() != MVT::Flag && - "Chain and flag operands should occur at end of operand list!"); - // Get/emit the operand. - unsigned VReg = getVR(Op, VRBaseMap); - const TargetInstrDesc &TID = MI->getDesc(); - bool isOptDef = IIOpNum < TID.getNumOperands() && - TID.OpInfo[IIOpNum].isOptionalDef(); - MI->addOperand(MachineOperand::CreateReg(VReg, isOptDef)); - - // Verify that it is right. - assert(TargetRegisterInfo::isVirtualRegister(VReg) && "Not a vreg?"); -#ifndef NDEBUG - if (II) { - // There may be no register class for this operand if it is a variadic - // argument (RC will be NULL in this case). In this case, we just assume - // the regclass is ok. - const TargetRegisterClass *RC = - getInstrOperandRegClass(TRI, TII, *II, IIOpNum); - assert((RC || II->isVariadic()) && "Expected reg class info!"); - const TargetRegisterClass *VRC = MRI.getRegClass(VReg); - if (RC && VRC != RC) { - cerr << "Register class of operand and regclass of use don't agree!\n"; - cerr << "Operand = " << IIOpNum << "\n"; - cerr << "Op->Val = "; Op.getNode()->dump(DAG); cerr << "\n"; - cerr << "MI = "; MI->print(cerr); - cerr << "VReg = " << VReg << "\n"; - cerr << "VReg RegClass size = " << VRC->getSize() - << ", align = " << VRC->getAlignment() << "\n"; - cerr << "Expected RegClass size = " << RC->getSize() - << ", align = " << RC->getAlignment() << "\n"; - cerr << "Fatal error, aborting.\n"; - abort(); - } - } -#endif - } else if (ConstantSDNode *C = dyn_cast(Op)) { - MI->addOperand(MachineOperand::CreateImm(C->getZExtValue())); - } else if (ConstantFPSDNode *F = dyn_cast(Op)) { - const ConstantFP *CFP = F->getConstantFPValue(); - MI->addOperand(MachineOperand::CreateFPImm(CFP)); - } else if (RegisterSDNode *R = dyn_cast(Op)) { - MI->addOperand(MachineOperand::CreateReg(R->getReg(), false)); - } else if (GlobalAddressSDNode *TGA = dyn_cast(Op)) { - MI->addOperand(MachineOperand::CreateGA(TGA->getGlobal(),TGA->getOffset())); - } else if (BasicBlockSDNode *BB = dyn_cast(Op)) { - MI->addOperand(MachineOperand::CreateMBB(BB->getBasicBlock())); - } else if (FrameIndexSDNode *FI = dyn_cast(Op)) { - MI->addOperand(MachineOperand::CreateFI(FI->getIndex())); - } else if (JumpTableSDNode *JT = dyn_cast(Op)) { - MI->addOperand(MachineOperand::CreateJTI(JT->getIndex())); - } else if (ConstantPoolSDNode *CP = dyn_cast(Op)) { - int Offset = CP->getOffset(); - unsigned Align = CP->getAlignment(); - const Type *Type = CP->getType(); - // MachineConstantPool wants an explicit alignment. - if (Align == 0) { - Align = TM.getTargetData()->getPreferredTypeAlignmentShift(Type); - if (Align == 0) { - // Alignment of vector types. FIXME! - Align = TM.getTargetData()->getABITypeSize(Type); - Align = Log2_64(Align); - } - } - - unsigned Idx; - if (CP->isMachineConstantPoolEntry()) - Idx = ConstPool->getConstantPoolIndex(CP->getMachineCPVal(), Align); - else - Idx = ConstPool->getConstantPoolIndex(CP->getConstVal(), Align); - MI->addOperand(MachineOperand::CreateCPI(Idx, Offset)); - } else if (ExternalSymbolSDNode *ES = dyn_cast(Op)) { - MI->addOperand(MachineOperand::CreateES(ES->getSymbol())); - } else { - assert(Op.getValueType() != MVT::Other && - Op.getValueType() != MVT::Flag && - "Chain and flag operands should occur at end of operand list!"); - unsigned VReg = getVR(Op, VRBaseMap); - MI->addOperand(MachineOperand::CreateReg(VReg, false)); - - // Verify that it is right. Note that the reg class of the physreg and the - // vreg don't necessarily need to match, but the target copy insertion has - // to be able to handle it. This handles things like copies from ST(0) to - // an FP vreg on x86. - assert(TargetRegisterInfo::isVirtualRegister(VReg) && "Not a vreg?"); - if (II && !II->isVariadic()) { - assert(getInstrOperandRegClass(TRI, TII, *II, IIOpNum) && - "Don't have operand info for this instruction!"); - } - } -} - -void ScheduleDAG::AddMemOperand(MachineInstr *MI, const MachineMemOperand &MO) { - MI->addMemOperand(*MF, MO); -} - -/// getSubRegisterRegClass - Returns the register class of specified register -/// class' "SubIdx"'th sub-register class. -static const TargetRegisterClass* -getSubRegisterRegClass(const TargetRegisterClass *TRC, unsigned SubIdx) { - // Pick the register class of the subregister - TargetRegisterInfo::regclass_iterator I = - TRC->subregclasses_begin() + SubIdx-1; - assert(I < TRC->subregclasses_end() && - "Invalid subregister index for register class"); - return *I; -} - -/// getSuperRegisterRegClass - Returns the register class of a superreg A whose -/// "SubIdx"'th sub-register class is the specified register class and whose -/// type matches the specified type. -static const TargetRegisterClass* -getSuperRegisterRegClass(const TargetRegisterClass *TRC, - unsigned SubIdx, MVT VT) { - // Pick the register class of the superegister for this type - for (TargetRegisterInfo::regclass_iterator I = TRC->superregclasses_begin(), - E = TRC->superregclasses_end(); I != E; ++I) - if ((*I)->hasType(VT) && getSubRegisterRegClass(*I, SubIdx) == TRC) - return *I; - assert(false && "Couldn't find the register class"); - return 0; -} - -/// EmitSubregNode - Generate machine code for subreg nodes. -/// -void ScheduleDAG::EmitSubregNode(SDNode *Node, - DenseMap &VRBaseMap) { - unsigned VRBase = 0; - unsigned Opc = Node->getMachineOpcode(); - - // If the node is only used by a CopyToReg and the dest reg is a vreg, use - // the CopyToReg'd destination register instead of creating a new vreg. - for (SDNode::use_iterator UI = Node->use_begin(), E = Node->use_end(); - UI != E; ++UI) { - SDNode *User = *UI; - if (User->getOpcode() == ISD::CopyToReg && - User->getOperand(2).getNode() == Node) { - unsigned DestReg = cast(User->getOperand(1))->getReg(); - if (TargetRegisterInfo::isVirtualRegister(DestReg)) { - VRBase = DestReg; - break; - } - } - } - - if (Opc == TargetInstrInfo::EXTRACT_SUBREG) { - unsigned SubIdx = cast(Node->getOperand(1))->getZExtValue(); - - // Create the extract_subreg machine instruction. - MachineInstr *MI = BuildMI(*MF, TII->get(TargetInstrInfo::EXTRACT_SUBREG)); - - // Figure out the register class to create for the destreg. - unsigned VReg = getVR(Node->getOperand(0), VRBaseMap); - const TargetRegisterClass *TRC = MRI.getRegClass(VReg); - const TargetRegisterClass *SRC = getSubRegisterRegClass(TRC, SubIdx); - - if (VRBase) { - // Grab the destination register -#ifndef NDEBUG - const TargetRegisterClass *DRC = MRI.getRegClass(VRBase); - assert(SRC && DRC && SRC == DRC && - "Source subregister and destination must have the same class"); -#endif - } else { - // Create the reg - assert(SRC && "Couldn't find source register class"); - VRBase = MRI.createVirtualRegister(SRC); - } - - // Add def, source, and subreg index - MI->addOperand(MachineOperand::CreateReg(VRBase, true)); - AddOperand(MI, Node->getOperand(0), 0, 0, VRBaseMap); - MI->addOperand(MachineOperand::CreateImm(SubIdx)); - BB->push_back(MI); - } else if (Opc == TargetInstrInfo::INSERT_SUBREG || - Opc == TargetInstrInfo::SUBREG_TO_REG) { - SDValue N0 = Node->getOperand(0); - SDValue N1 = Node->getOperand(1); - SDValue N2 = Node->getOperand(2); - unsigned SubReg = getVR(N1, VRBaseMap); - unsigned SubIdx = cast(N2)->getZExtValue(); - - - // Figure out the register class to create for the destreg. - const TargetRegisterClass *TRC = 0; - if (VRBase) { - TRC = MRI.getRegClass(VRBase); - } else { - TRC = getSuperRegisterRegClass(MRI.getRegClass(SubReg), SubIdx, - Node->getValueType(0)); - assert(TRC && "Couldn't determine register class for insert_subreg"); - VRBase = MRI.createVirtualRegister(TRC); // Create the reg - } - - // Create the insert_subreg or subreg_to_reg machine instruction. - MachineInstr *MI = BuildMI(*MF, TII->get(Opc)); - MI->addOperand(MachineOperand::CreateReg(VRBase, true)); - - // If creating a subreg_to_reg, then the first input operand - // is an implicit value immediate, otherwise it's a register - if (Opc == TargetInstrInfo::SUBREG_TO_REG) { - const ConstantSDNode *SD = cast(N0); - MI->addOperand(MachineOperand::CreateImm(SD->getZExtValue())); - } else - AddOperand(MI, N0, 0, 0, VRBaseMap); - // Add the subregster being inserted - AddOperand(MI, N1, 0, 0, VRBaseMap); - MI->addOperand(MachineOperand::CreateImm(SubIdx)); - BB->push_back(MI); - } else - assert(0 && "Node is not insert_subreg, extract_subreg, or subreg_to_reg"); - - SDValue Op(Node, 0); - bool isNew = VRBaseMap.insert(std::make_pair(Op, VRBase)).second; - isNew = isNew; // Silence compiler warning. - assert(isNew && "Node emitted out of order - early"); -} - -/// EmitNode - Generate machine code for an node and needed dependencies. -/// -void ScheduleDAG::EmitNode(SDNode *Node, bool IsClone, - DenseMap &VRBaseMap) { - // If machine instruction - if (Node->isMachineOpcode()) { - unsigned Opc = Node->getMachineOpcode(); - - // Handle subreg insert/extract specially - if (Opc == TargetInstrInfo::EXTRACT_SUBREG || - Opc == TargetInstrInfo::INSERT_SUBREG || - Opc == TargetInstrInfo::SUBREG_TO_REG) { - EmitSubregNode(Node, VRBaseMap); - return; - } - - if (Opc == TargetInstrInfo::IMPLICIT_DEF) - // We want a unique VR for each IMPLICIT_DEF use. - return; - - const TargetInstrDesc &II = TII->get(Opc); - unsigned NumResults = CountResults(Node); - unsigned NodeOperands = CountOperands(Node); - unsigned MemOperandsEnd = ComputeMemOperandsEnd(Node); - bool HasPhysRegOuts = (NumResults > II.getNumDefs()) && - II.getImplicitDefs() != 0; -#ifndef NDEBUG - unsigned NumMIOperands = NodeOperands + NumResults; - assert((II.getNumOperands() == NumMIOperands || - HasPhysRegOuts || II.isVariadic()) && - "#operands for dag node doesn't match .td file!"); -#endif - - // Create the new machine instruction. - MachineInstr *MI = BuildMI(*MF, II); - - // Add result register values for things that are defined by this - // instruction. - if (NumResults) - CreateVirtualRegisters(Node, MI, II, VRBaseMap); - - // Emit all of the actual operands of this instruction, adding them to the - // instruction as appropriate. - for (unsigned i = 0; i != NodeOperands; ++i) - AddOperand(MI, Node->getOperand(i), i+II.getNumDefs(), &II, VRBaseMap); - - // Emit all of the memory operands of this instruction - for (unsigned i = NodeOperands; i != MemOperandsEnd; ++i) - AddMemOperand(MI, cast(Node->getOperand(i))->MO); - - // Commute node if it has been determined to be profitable. - if (CommuteSet.count(Node)) { - MachineInstr *NewMI = TII->commuteInstruction(MI); - if (NewMI == 0) - DOUT << "Sched: COMMUTING FAILED!\n"; - else { - DOUT << "Sched: COMMUTED TO: " << *NewMI; - if (MI != NewMI) { - MF->DeleteMachineInstr(MI); - MI = NewMI; - } - ++NumCommutes; - } - } - - if (II.usesCustomDAGSchedInsertionHook()) - // Insert this instruction into the basic block using a target - // specific inserter which may returns a new basic block. - BB = TLI->EmitInstrWithCustomInserter(MI, BB); - else - BB->push_back(MI); - - // Additional results must be an physical register def. - if (HasPhysRegOuts) { - for (unsigned i = II.getNumDefs(); i < NumResults; ++i) { - unsigned Reg = II.getImplicitDefs()[i - II.getNumDefs()]; - if (Node->hasAnyUseOfValue(i)) - EmitCopyFromReg(Node, i, IsClone, Reg, VRBaseMap); - } - } - return; - } - - switch (Node->getOpcode()) { - default: -#ifndef NDEBUG - Node->dump(DAG); -#endif - assert(0 && "This target-independent node should have been selected!"); - break; - case ISD::EntryToken: - assert(0 && "EntryToken should have been excluded from the schedule!"); - break; - case ISD::TokenFactor: // fall thru - break; - case ISD::CopyToReg: { - unsigned SrcReg; - SDValue SrcVal = Node->getOperand(2); - if (RegisterSDNode *R = dyn_cast(SrcVal)) - SrcReg = R->getReg(); - else - SrcReg = getVR(SrcVal, VRBaseMap); - - unsigned DestReg = cast(Node->getOperand(1))->getReg(); - if (SrcReg == DestReg) // Coalesced away the copy? Ignore. - break; - - const TargetRegisterClass *SrcTRC = 0, *DstTRC = 0; - // Get the register classes of the src/dst. - if (TargetRegisterInfo::isVirtualRegister(SrcReg)) - SrcTRC = MRI.getRegClass(SrcReg); - else - SrcTRC = TRI->getPhysicalRegisterRegClass(SrcReg,SrcVal.getValueType()); - - if (TargetRegisterInfo::isVirtualRegister(DestReg)) - DstTRC = MRI.getRegClass(DestReg); - else - DstTRC = TRI->getPhysicalRegisterRegClass(DestReg, - Node->getOperand(1).getValueType()); - TII->copyRegToReg(*BB, BB->end(), DestReg, SrcReg, DstTRC, SrcTRC); - break; - } - case ISD::CopyFromReg: { - unsigned SrcReg = cast(Node->getOperand(1))->getReg(); - EmitCopyFromReg(Node, 0, IsClone, SrcReg, VRBaseMap); - break; - } - case ISD::INLINEASM: { - unsigned NumOps = Node->getNumOperands(); - if (Node->getOperand(NumOps-1).getValueType() == MVT::Flag) - --NumOps; // Ignore the flag operand. - - // Create the inline asm machine instruction. - MachineInstr *MI = BuildMI(*MF, TII->get(TargetInstrInfo::INLINEASM)); - - // Add the asm string as an external symbol operand. - const char *AsmStr = - cast(Node->getOperand(1))->getSymbol(); - MI->addOperand(MachineOperand::CreateES(AsmStr)); - - // Add all of the operand registers to the instruction. - for (unsigned i = 2; i != NumOps;) { - unsigned Flags = - cast(Node->getOperand(i))->getZExtValue(); - unsigned NumVals = Flags >> 3; - - MI->addOperand(MachineOperand::CreateImm(Flags)); - ++i; // Skip the ID value. - - switch (Flags & 7) { - default: assert(0 && "Bad flags!"); - case 2: // Def of register. - for (; NumVals; --NumVals, ++i) { - unsigned Reg = cast(Node->getOperand(i))->getReg(); - MI->addOperand(MachineOperand::CreateReg(Reg, true)); - } - break; - case 6: // Def of earlyclobber register. - for (; NumVals; --NumVals, ++i) { - unsigned Reg = cast(Node->getOperand(i))->getReg(); - MI->addOperand(MachineOperand::CreateReg(Reg, true, false, false, - false, 0, true)); - } - break; - case 1: // Use of register. - case 3: // Immediate. - case 4: // Addressing mode. - // The addressing mode has been selected, just add all of the - // operands to the machine instruction. - for (; NumVals; --NumVals, ++i) - AddOperand(MI, Node->getOperand(i), 0, 0, VRBaseMap); - break; - } - } - BB->push_back(MI); - break; - } - } -} - -void ScheduleDAG::EmitNoop() { - TII->insertNoop(*BB, BB->end()); -} - -void ScheduleDAG::EmitCrossRCCopy(SUnit *SU, - DenseMap &VRBaseMap) { - for (SUnit::const_pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); - I != E; ++I) { - if (I->isCtrl) continue; // ignore chain preds - if (!I->Dep->getNode()) { - // Copy to physical register. - DenseMap::iterator VRI = VRBaseMap.find(I->Dep); - assert(VRI != VRBaseMap.end() && "Node emitted out of order - late"); - // Find the destination physical register. - unsigned Reg = 0; - for (SUnit::const_succ_iterator II = SU->Succs.begin(), - EE = SU->Succs.end(); II != EE; ++II) { - if (I->Reg) { - Reg = I->Reg; - break; - } - } - assert(I->Reg && "Unknown physical register!"); - TII->copyRegToReg(*BB, BB->end(), Reg, VRI->second, - SU->CopyDstRC, SU->CopySrcRC); - } else { - // Copy from physical register. - assert(I->Reg && "Unknown physical register!"); - unsigned VRBase = MRI.createVirtualRegister(SU->CopyDstRC); - bool isNew = VRBaseMap.insert(std::make_pair(SU, VRBase)).second; - isNew = isNew; // Silence compiler warning. - assert(isNew && "Node emitted out of order - early"); - TII->copyRegToReg(*BB, BB->end(), VRBase, I->Reg, - SU->CopyDstRC, SU->CopySrcRC); - } - break; - } -} - -/// EmitSchedule - Emit the machine code in scheduled order. -MachineBasicBlock *ScheduleDAG::EmitSchedule() { - // For post-regalloc scheduling, we're rescheduling the instructions in the - // block, so start by removing them from the block. - if (!DAG) - while (!BB->empty()) - BB->remove(BB->begin()); - - DenseMap VRBaseMap; - DenseMap CopyVRBaseMap; - for (unsigned i = 0, e = Sequence.size(); i != e; i++) { - SUnit *SU = Sequence[i]; - if (!SU) { - // Null SUnit* is a noop. - EmitNoop(); - continue; - } - - // For post-regalloc scheduling, we already have the instruction; - // just append it to the block. - if (!DAG) { - BB->push_back(SU->getInstr()); - continue; - } - - // For pre-regalloc scheduling, create instructions corresponding to the - // SDNode and any flagged SDNodes and append them to the block. - SmallVector FlaggedNodes; - for (SDNode *N = SU->getNode()->getFlaggedNode(); N; N = N->getFlaggedNode()) - FlaggedNodes.push_back(N); - while (!FlaggedNodes.empty()) { - EmitNode(FlaggedNodes.back(), SU->OrigNode != SU, VRBaseMap); - FlaggedNodes.pop_back(); - } - if (!SU->getNode()) - EmitCrossRCCopy(SU, CopyVRBaseMap); - else - EmitNode(SU->getNode(), SU->OrigNode != SU, VRBaseMap); - } - - return BB; -} Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp?rev=59676&r1=59675&r2=59676&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp Wed Nov 19 17:18:57 2008 @@ -12,7 +12,7 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "pre-RA-sched" -#include "llvm/CodeGen/ScheduleDAG.h" +#include "llvm/CodeGen/ScheduleDAGSDNodes.h" #include "llvm/CodeGen/SchedulerRegistry.h" #include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Target/TargetData.h" @@ -58,7 +58,7 @@ //===----------------------------------------------------------------------===// /// ScheduleDAGFast - The actual "fast" list scheduler implementation. /// -class VISIBILITY_HIDDEN ScheduleDAGFast : public ScheduleDAG { +class VISIBILITY_HIDDEN ScheduleDAGFast : public ScheduleDAGSDNodes { private: /// AvailableQueue - The priority queue to use for the available SUnits. FastPriorityQueue AvailableQueue; @@ -73,7 +73,7 @@ public: ScheduleDAGFast(SelectionDAG *dag, MachineBasicBlock *bb, const TargetMachine &tm) - : ScheduleDAG(dag, bb, tm) {} + : ScheduleDAGSDNodes(dag, bb, tm) {} void Schedule(); Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp?rev=59676&r1=59675&r2=59676&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Wed Nov 19 17:18:57 2008 @@ -19,7 +19,8 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "pre-RA-sched" -#include "llvm/CodeGen/ScheduleDAG.h" +#include "llvm/CodeGen/LatencyPriorityQueue.h" +#include "llvm/CodeGen/ScheduleDAGSDNodes.h" #include "llvm/CodeGen/SchedulerRegistry.h" #include "llvm/CodeGen/SelectionDAGISel.h" #include "llvm/Target/TargetRegisterInfo.h" @@ -30,7 +31,6 @@ #include "llvm/Support/Compiler.h" #include "llvm/ADT/PriorityQueue.h" #include "llvm/ADT/Statistic.h" -#include "LatencyPriorityQueue.h" #include using namespace llvm; @@ -46,7 +46,7 @@ /// ScheduleDAGList - The actual list scheduler implementation. This supports /// top-down scheduling. /// -class VISIBILITY_HIDDEN ScheduleDAGList : public ScheduleDAG { +class VISIBILITY_HIDDEN ScheduleDAGList : public ScheduleDAGSDNodes { private: /// AvailableQueue - The priority queue to use for the available SUnits. /// @@ -66,7 +66,7 @@ const TargetMachine &tm, SchedulingPriorityQueue *availqueue, HazardRecognizer *HR) - : ScheduleDAG(dag, bb, tm), + : ScheduleDAGSDNodes(dag, bb, tm), AvailableQueue(availqueue), HazardRec(HR) { } @@ -212,13 +212,13 @@ if (!N) break; FoundNode = N; } - + HazardRecognizer::HazardType HT = HazardRec->getHazardType(FoundNode); if (HT == HazardRecognizer::NoHazard) { FoundSUnit = CurSUnit; break; } - + // Remember if this is a noop hazard. HasNoopHazards |= HT == HazardRecognizer::NoopHazard; Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp?rev=59676&r1=59675&r2=59676&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Wed Nov 19 17:18:57 2008 @@ -16,7 +16,7 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "pre-RA-sched" -#include "llvm/CodeGen/ScheduleDAG.h" +#include "llvm/CodeGen/ScheduleDAGSDNodes.h" #include "llvm/CodeGen/SchedulerRegistry.h" #include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Target/TargetData.h" @@ -53,7 +53,7 @@ /// ScheduleDAGRRList - The actual register reduction list scheduler /// implementation. This supports both top-down and bottom-up scheduling. /// -class VISIBILITY_HIDDEN ScheduleDAGRRList : public ScheduleDAG { +class VISIBILITY_HIDDEN ScheduleDAGRRList : public ScheduleDAGSDNodes { private: /// isBottomUp - This is true if the scheduling problem is bottom-up, false if /// it is top-down. @@ -77,7 +77,7 @@ ScheduleDAGRRList(SelectionDAG *dag, MachineBasicBlock *bb, const TargetMachine &tm, bool isbottomup, bool f, SchedulingPriorityQueue *availqueue) - : ScheduleDAG(dag, bb, tm), isBottomUp(isbottomup), Fast(f), + : ScheduleDAGSDNodes(dag, bb, tm), isBottomUp(isbottomup), Fast(f), AvailableQueue(availqueue) { } Copied: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp (from r59324, llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp) URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp?p2=llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp&p1=llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp&r1=59324&r2=59676&rev=59676&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp Wed Nov 19 17:18:57 2008 @@ -1,4 +1,4 @@ -//===---- ScheduleDAG.cpp - Implement the ScheduleDAG class ---------------===// +//===--- ScheduleDAGSDNodes.cpp - Implement the ScheduleDAGSDNodes class --===// // // The LLVM Compiler Infrastructure // @@ -13,21 +13,28 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "pre-RA-sched" -#include "llvm/CodeGen/ScheduleDAG.h" +#include "llvm/CodeGen/ScheduleDAGSDNodes.h" +#include "llvm/CodeGen/SelectionDAG.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/raw_ostream.h" using namespace llvm; -ScheduleDAG::ScheduleDAG(SelectionDAG *dag, MachineBasicBlock *bb, - const TargetMachine &tm) - : DAG(dag), BB(bb), TM(tm), MRI(BB->getParent()->getRegInfo()) { - TII = TM.getInstrInfo(); - MF = BB->getParent(); - TRI = TM.getRegisterInfo(); - TLI = TM.getTargetLowering(); - ConstPool = MF->getConstantPool(); +ScheduleDAGSDNodes::ScheduleDAGSDNodes(SelectionDAG *dag, MachineBasicBlock *bb, + const TargetMachine &tm) + : ScheduleDAG(dag, bb, tm) { +} + +SUnit *ScheduleDAGSDNodes::Clone(SUnit *Old) { + SUnit *SU = NewSUnit(Old->getNode()); + SU->OrigNode = Old->OrigNode; + SU->Latency = Old->Latency; + SU->isTwoAddress = Old->isTwoAddress; + SU->isCommutable = Old->isCommutable; + SU->hasPhysRegDefs = Old->hasPhysRegDefs; + return SU; } /// CheckForPhysRegDependency - Check if the dependency between def and use of @@ -57,28 +64,10 @@ } } -SUnit *ScheduleDAG::Clone(SUnit *Old) { - SUnit *SU = NewSUnit(Old->getNode()); - SU->OrigNode = Old->OrigNode; - SU->Latency = Old->Latency; - SU->isTwoAddress = Old->isTwoAddress; - SU->isCommutable = Old->isCommutable; - SU->hasPhysRegDefs = Old->hasPhysRegDefs; - return SU; -} - - /// BuildSchedUnits - Build SUnits from the selection dag that we are input. /// This SUnit graph is similar to the SelectionDAG, but represents flagged /// together nodes with a single SUnit. -void ScheduleDAG::BuildSchedUnits() { - // For post-regalloc scheduling, build the SUnits from the MachineInstrs - // in the MachineBasicBlock. - if (!DAG) { - BuildSchedUnitsFromMBB(); - return; - } - +void ScheduleDAGSDNodes::BuildSchedUnits() { // Reserve entries in the vector for each of the SUnits we are creating. This // ensure that reallocation of the vector won't happen, so SUnit*'s won't get // invalidated. @@ -192,84 +181,7 @@ } } -void ScheduleDAG::BuildSchedUnitsFromMBB() { - SUnits.clear(); - SUnits.reserve(BB->size()); - - std::vector PendingLoads; - SUnit *Terminator = 0; - SUnit *Chain = 0; - SUnit *Defs[TargetRegisterInfo::FirstVirtualRegister] = {}; - std::vector Uses[TargetRegisterInfo::FirstVirtualRegister] = {}; - int Cost = 1; // FIXME - - for (MachineBasicBlock::iterator MII = BB->end(), MIE = BB->begin(); - MII != MIE; --MII) { - MachineInstr *MI = prior(MII); - SUnit *SU = NewSUnit(MI); - - for (unsigned j = 0, n = MI->getNumOperands(); j != n; ++j) { - const MachineOperand &MO = MI->getOperand(j); - if (!MO.isReg()) continue; - unsigned Reg = MO.getReg(); - if (Reg == 0) continue; - - assert(TRI->isPhysicalRegister(Reg) && "Virtual register encountered!"); - std::vector &UseList = Uses[Reg]; - SUnit *&Def = Defs[Reg]; - // Optionally add output and anti dependences - if (Def && Def != SU) - Def->addPred(SU, /*isCtrl=*/true, /*isSpecial=*/false, - /*PhyReg=*/Reg, Cost); - for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { - SUnit *&Def = Defs[*Alias]; - if (Def && Def != SU) - Def->addPred(SU, /*isCtrl=*/true, /*isSpecial=*/false, - /*PhyReg=*/*Alias, Cost); - } - - if (MO.isDef()) { - // Add any data dependencies. - for (unsigned i = 0, e = UseList.size(); i != e; ++i) - if (UseList[i] != SU) - UseList[i]->addPred(SU, /*isCtrl=*/false, /*isSpecial=*/false, - /*PhysReg=*/Reg, Cost); - for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { - std::vector &UseList = Uses[*Alias]; - for (unsigned i = 0, e = UseList.size(); i != e; ++i) - if (UseList[i] != SU) - UseList[i]->addPred(SU, /*isCtrl=*/false, /*isSpecial=*/false, - /*PhysReg=*/*Alias, Cost); - } - - UseList.clear(); - Def = SU; - } else { - UseList.push_back(SU); - } - } - bool False = false; - bool True = true; - if (!MI->isSafeToMove(TII, False)) { - if (Chain) - Chain->addPred(SU, /*isCtrl=*/false, /*isSpecial=*/false); - for (unsigned k = 0, m = PendingLoads.size(); k != m; ++k) - PendingLoads[k]->addPred(SU, /*isCtrl=*/false, /*isSpecial=*/false); - PendingLoads.clear(); - Chain = SU; - } else if (!MI->isSafeToMove(TII, True)) { - if (Chain) - Chain->addPred(SU, /*isCtrl=*/false, /*isSpecial=*/false); - PendingLoads.push_back(SU); - } - if (Terminator && SU->Succs.empty()) - Terminator->addPred(SU, /*isCtrl=*/false, /*isSpecial=*/false); - if (MI->getDesc().isTerminator()) - Terminator = SU; - } -} - -void ScheduleDAG::ComputeLatency(SUnit *SU) { +void ScheduleDAGSDNodes::ComputeLatency(SUnit *SU) { const InstrItineraryData &InstrItins = TM.getInstrItineraryData(); // Compute the latency for the node. We use the sum of the latencies for @@ -292,119 +204,10 @@ } } -/// CalculateDepths - compute depths using algorithms for the longest -/// paths in the DAG -void ScheduleDAG::CalculateDepths() { - unsigned DAGSize = SUnits.size(); - std::vector WorkList; - WorkList.reserve(DAGSize); - - // Initialize the data structures - for (unsigned i = 0, e = DAGSize; i != e; ++i) { - SUnit *SU = &SUnits[i]; - unsigned Degree = SU->Preds.size(); - // Temporarily use the Depth field as scratch space for the degree count. - SU->Depth = Degree; - - // Is it a node without dependencies? - if (Degree == 0) { - assert(SU->Preds.empty() && "SUnit should have no predecessors"); - // Collect leaf nodes - WorkList.push_back(SU); - } - } - - // Process nodes in the topological order - while (!WorkList.empty()) { - SUnit *SU = WorkList.back(); - WorkList.pop_back(); - unsigned SUDepth = 0; - - // Use dynamic programming: - // When current node is being processed, all of its dependencies - // are already processed. - // So, just iterate over all predecessors and take the longest path - for (SUnit::const_pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); - I != E; ++I) { - unsigned PredDepth = I->Dep->Depth; - if (PredDepth+1 > SUDepth) { - SUDepth = PredDepth + 1; - } - } - - SU->Depth = SUDepth; - - // Update degrees of all nodes depending on current SUnit - for (SUnit::const_succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); - I != E; ++I) { - SUnit *SU = I->Dep; - if (!--SU->Depth) - // If all dependencies of the node are processed already, - // then the longest path for the node can be computed now - WorkList.push_back(SU); - } - } -} - -/// CalculateHeights - compute heights using algorithms for the longest -/// paths in the DAG -void ScheduleDAG::CalculateHeights() { - unsigned DAGSize = SUnits.size(); - std::vector WorkList; - WorkList.reserve(DAGSize); - - // Initialize the data structures - for (unsigned i = 0, e = DAGSize; i != e; ++i) { - SUnit *SU = &SUnits[i]; - unsigned Degree = SU->Succs.size(); - // Temporarily use the Height field as scratch space for the degree count. - SU->Height = Degree; - - // Is it a node without dependencies? - if (Degree == 0) { - assert(SU->Succs.empty() && "Something wrong"); - assert(WorkList.empty() && "Should be empty"); - // Collect leaf nodes - WorkList.push_back(SU); - } - } - - // Process nodes in the topological order - while (!WorkList.empty()) { - SUnit *SU = WorkList.back(); - WorkList.pop_back(); - unsigned SUHeight = 0; - - // Use dynamic programming: - // When current node is being processed, all of its dependencies - // are already processed. - // So, just iterate over all successors and take the longest path - for (SUnit::const_succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); - I != E; ++I) { - unsigned SuccHeight = I->Dep->Height; - if (SuccHeight+1 > SUHeight) { - SUHeight = SuccHeight + 1; - } - } - - SU->Height = SUHeight; - - // Update degrees of all nodes depending on current SUnit - for (SUnit::const_pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); - I != E; ++I) { - SUnit *SU = I->Dep; - if (!--SU->Height) - // If all dependencies of the node are processed already, - // then the longest path for the node can be computed now - WorkList.push_back(SU); - } - } -} - /// CountResults - The results of target nodes have register or immediate /// operands first, then an optional chain, and optional flag operands (which do /// not go into the resulting MachineInstr). -unsigned ScheduleDAG::CountResults(SDNode *Node) { +unsigned ScheduleDAGSDNodes::CountResults(SDNode *Node) { unsigned N = Node->getNumValues(); while (N && Node->getValueType(N - 1) == MVT::Flag) --N; @@ -417,7 +220,7 @@ /// followed by special operands that describe memory references, then an /// optional chain operand, then an optional flag operand. Compute the number /// of actual operands that will go into the resulting MachineInstr. -unsigned ScheduleDAG::CountOperands(SDNode *Node) { +unsigned ScheduleDAGSDNodes::CountOperands(SDNode *Node) { unsigned N = ComputeMemOperandsEnd(Node); while (N && isa(Node->getOperand(N - 1).getNode())) --N; // Ignore MEMOPERAND nodes @@ -426,7 +229,7 @@ /// ComputeMemOperandsEnd - Find the index one past the last MemOperandSDNode /// operand -unsigned ScheduleDAG::ComputeMemOperandsEnd(SDNode *Node) { +unsigned ScheduleDAGSDNodes::ComputeMemOperandsEnd(SDNode *Node) { unsigned N = Node->getNumOperands(); while (N && Node->getOperand(N - 1).getValueType() == MVT::Flag) --N; @@ -436,83 +239,19 @@ } -/// dump - dump the schedule. -void ScheduleDAG::dumpSchedule() const { - for (unsigned i = 0, e = Sequence.size(); i != e; i++) { - if (SUnit *SU = Sequence[i]) - SU->dump(DAG); - else - cerr << "**** NOOP ****\n"; - } -} - - -/// Run - perform scheduling. -/// -void ScheduleDAG::Run() { - Schedule(); - - DOUT << "*** Final schedule ***\n"; - DEBUG(dumpSchedule()); - DOUT << "\n"; -} - -/// SUnit - Scheduling unit. It's an wrapper around either a single SDNode or -/// a group of nodes flagged together. -void SUnit::dump(const SelectionDAG *G) const { - cerr << "SU(" << NodeNum << "): "; - if (getNode()) - getNode()->dump(G); +void ScheduleDAGSDNodes::dumpNode(const SUnit *SU) const { + if (SU->getNode()) + SU->getNode()->dump(DAG); else cerr << "CROSS RC COPY "; cerr << "\n"; SmallVector FlaggedNodes; - for (SDNode *N = getNode()->getFlaggedNode(); N; N = N->getFlaggedNode()) + for (SDNode *N = SU->getNode()->getFlaggedNode(); N; N = N->getFlaggedNode()) FlaggedNodes.push_back(N); while (!FlaggedNodes.empty()) { cerr << " "; - FlaggedNodes.back()->dump(G); + FlaggedNodes.back()->dump(DAG); cerr << "\n"; FlaggedNodes.pop_back(); } } - -void SUnit::dumpAll(const SelectionDAG *G) const { - dump(G); - - cerr << " # preds left : " << NumPredsLeft << "\n"; - cerr << " # succs left : " << NumSuccsLeft << "\n"; - cerr << " Latency : " << Latency << "\n"; - cerr << " Depth : " << Depth << "\n"; - cerr << " Height : " << Height << "\n"; - - if (Preds.size() != 0) { - cerr << " Predecessors:\n"; - for (SUnit::const_succ_iterator I = Preds.begin(), E = Preds.end(); - I != E; ++I) { - if (I->isCtrl) - cerr << " ch #"; - else - cerr << " val #"; - cerr << I->Dep << " - SU(" << I->Dep->NodeNum << ")"; - if (I->isSpecial) - cerr << " *"; - cerr << "\n"; - } - } - if (Succs.size() != 0) { - cerr << " Successors:\n"; - for (SUnit::const_succ_iterator I = Succs.begin(), E = Succs.end(); - I != E; ++I) { - if (I->isCtrl) - cerr << " ch #"; - else - cerr << " val #"; - cerr << I->Dep << " - SU(" << I->Dep->NodeNum << ")"; - if (I->isSpecial) - cerr << " *"; - cerr << "\n"; - } - } - cerr << "\n"; -} Copied: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp (from r59282, llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGEmit.cpp) URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp?p2=llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp&p1=llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGEmit.cpp&r1=59282&r2=59676&rev=59676&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGEmit.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp Wed Nov 19 17:18:57 2008 @@ -13,7 +13,7 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "pre-RA-sched" -#include "llvm/CodeGen/ScheduleDAG.h" +#include "llvm/CodeGen/ScheduleDAGSDNodes.h" #include "llvm/CodeGen/MachineConstantPool.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstrBuilder.h" @@ -47,9 +47,9 @@ /// EmitCopyFromReg - Generate machine code for an CopyFromReg node or an /// implicit physical register output. -void ScheduleDAG::EmitCopyFromReg(SDNode *Node, unsigned ResNo, - bool IsClone, unsigned SrcReg, - DenseMap &VRBaseMap) { +void ScheduleDAGSDNodes::EmitCopyFromReg(SDNode *Node, unsigned ResNo, + bool IsClone, unsigned SrcReg, + DenseMap &VRBaseMap) { unsigned VRBase = 0; if (TargetRegisterInfo::isVirtualRegister(SrcReg)) { // Just use the input register directly! @@ -142,8 +142,8 @@ /// getDstOfCopyToRegUse - If the only use of the specified result number of /// node is a CopyToReg, return its destination register. Return 0 otherwise. -unsigned ScheduleDAG::getDstOfOnlyCopyToRegUse(SDNode *Node, - unsigned ResNo) const { +unsigned ScheduleDAGSDNodes::getDstOfOnlyCopyToRegUse(SDNode *Node, + unsigned ResNo) const { if (!Node->hasOneUse()) return 0; @@ -158,7 +158,7 @@ return 0; } -void ScheduleDAG::CreateVirtualRegisters(SDNode *Node, MachineInstr *MI, +void ScheduleDAGSDNodes::CreateVirtualRegisters(SDNode *Node, MachineInstr *MI, const TargetInstrDesc &II, DenseMap &VRBaseMap) { assert(Node->getMachineOpcode() != TargetInstrInfo::IMPLICIT_DEF && @@ -202,8 +202,8 @@ /// getVR - Return the virtual register corresponding to the specified result /// of the specified node. -unsigned ScheduleDAG::getVR(SDValue Op, - DenseMap &VRBaseMap) { +unsigned ScheduleDAGSDNodes::getVR(SDValue Op, + DenseMap &VRBaseMap) { if (Op.isMachineOpcode() && Op.getMachineOpcode() == TargetInstrInfo::IMPLICIT_DEF) { // Add an IMPLICIT_DEF instruction before every use. @@ -228,10 +228,10 @@ /// specifies the instruction information for the node, and IIOpNum is the /// operand number (in the II) that we are adding. IIOpNum and II are used for /// assertions only. -void ScheduleDAG::AddOperand(MachineInstr *MI, SDValue Op, - unsigned IIOpNum, - const TargetInstrDesc *II, - DenseMap &VRBaseMap) { +void ScheduleDAGSDNodes::AddOperand(MachineInstr *MI, SDValue Op, + unsigned IIOpNum, + const TargetInstrDesc *II, + DenseMap &VRBaseMap) { if (Op.isMachineOpcode()) { // Note that this case is redundant with the final else block, but we // include it because it is the most common and it makes the logic @@ -328,10 +328,6 @@ } } -void ScheduleDAG::AddMemOperand(MachineInstr *MI, const MachineMemOperand &MO) { - MI->addMemOperand(*MF, MO); -} - /// getSubRegisterRegClass - Returns the register class of specified register /// class' "SubIdx"'th sub-register class. static const TargetRegisterClass* @@ -361,8 +357,8 @@ /// EmitSubregNode - Generate machine code for subreg nodes. /// -void ScheduleDAG::EmitSubregNode(SDNode *Node, - DenseMap &VRBaseMap) { +void ScheduleDAGSDNodes::EmitSubregNode(SDNode *Node, + DenseMap &VRBaseMap) { unsigned VRBase = 0; unsigned Opc = Node->getMachineOpcode(); @@ -456,8 +452,8 @@ /// EmitNode - Generate machine code for an node and needed dependencies. /// -void ScheduleDAG::EmitNode(SDNode *Node, bool IsClone, - DenseMap &VRBaseMap) { +void ScheduleDAGSDNodes::EmitNode(SDNode *Node, bool IsClone, + DenseMap &VRBaseMap) { // If machine instruction if (Node->isMachineOpcode()) { unsigned Opc = Node->getMachineOpcode(); @@ -634,53 +630,8 @@ } } -void ScheduleDAG::EmitNoop() { - TII->insertNoop(*BB, BB->end()); -} - -void ScheduleDAG::EmitCrossRCCopy(SUnit *SU, - DenseMap &VRBaseMap) { - for (SUnit::const_pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); - I != E; ++I) { - if (I->isCtrl) continue; // ignore chain preds - if (!I->Dep->getNode()) { - // Copy to physical register. - DenseMap::iterator VRI = VRBaseMap.find(I->Dep); - assert(VRI != VRBaseMap.end() && "Node emitted out of order - late"); - // Find the destination physical register. - unsigned Reg = 0; - for (SUnit::const_succ_iterator II = SU->Succs.begin(), - EE = SU->Succs.end(); II != EE; ++II) { - if (I->Reg) { - Reg = I->Reg; - break; - } - } - assert(I->Reg && "Unknown physical register!"); - TII->copyRegToReg(*BB, BB->end(), Reg, VRI->second, - SU->CopyDstRC, SU->CopySrcRC); - } else { - // Copy from physical register. - assert(I->Reg && "Unknown physical register!"); - unsigned VRBase = MRI.createVirtualRegister(SU->CopyDstRC); - bool isNew = VRBaseMap.insert(std::make_pair(SU, VRBase)).second; - isNew = isNew; // Silence compiler warning. - assert(isNew && "Node emitted out of order - early"); - TII->copyRegToReg(*BB, BB->end(), VRBase, I->Reg, - SU->CopyDstRC, SU->CopySrcRC); - } - break; - } -} - /// EmitSchedule - Emit the machine code in scheduled order. -MachineBasicBlock *ScheduleDAG::EmitSchedule() { - // For post-regalloc scheduling, we're rescheduling the instructions in the - // block, so start by removing them from the block. - if (!DAG) - while (!BB->empty()) - BB->remove(BB->begin()); - +MachineBasicBlock *ScheduleDAGSDNodes::EmitSchedule() { DenseMap VRBaseMap; DenseMap CopyVRBaseMap; for (unsigned i = 0, e = Sequence.size(); i != e; i++) { @@ -691,13 +642,6 @@ continue; } - // For post-regalloc scheduling, we already have the instruction; - // just append it to the block. - if (!DAG) { - BB->push_back(SU->getInstr()); - continue; - } - // For pre-regalloc scheduling, create instructions corresponding to the // SDNode and any flagged SDNodes and append them to the block. SmallVector FlaggedNodes; Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=59676&r1=59675&r2=59676&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Wed Nov 19 17:18:57 2008 @@ -34,7 +34,7 @@ #include "llvm/CodeGen/MachineJumpTableInfo.h" #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/MachineRegisterInfo.h" -#include "llvm/CodeGen/ScheduleDAG.h" +#include "llvm/CodeGen/ScheduleDAGSDNodes.h" #include "llvm/CodeGen/SchedulerRegistry.h" #include "llvm/CodeGen/SelectionDAG.h" #include "llvm/Target/TargetRegisterInfo.h" Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp?rev=59676&r1=59675&r2=59676&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp Wed Nov 19 17:18:57 2008 @@ -15,7 +15,7 @@ #include "llvm/Function.h" #include "llvm/Assembly/Writer.h" #include "llvm/CodeGen/SelectionDAG.h" -#include "llvm/CodeGen/ScheduleDAG.h" +#include "llvm/CodeGen/ScheduleDAGSDNodes.h" #include "llvm/CodeGen/MachineConstantPool.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineModuleInfo.h" @@ -383,71 +383,7 @@ #endif } -namespace llvm { - template<> - struct DOTGraphTraits : public DefaultDOTGraphTraits { - static std::string getGraphName(const ScheduleDAG *G) { - return G->MF->getFunction()->getName(); - } - - static bool renderGraphFromBottomUp() { - return true; - } - - static bool hasNodeAddressLabel(const SUnit *Node, - const ScheduleDAG *Graph) { - return true; - } - - /// If you want to override the dot attributes printed for a particular - /// edge, override this method. - template - static std::string getEdgeAttributes(const void *Node, EdgeIter EI) { - if (EI.isSpecialDep()) - return "color=cyan,style=dashed"; - if (EI.isCtrlDep()) - return "color=blue,style=dashed"; - return ""; - } - - - static std::string getNodeLabel(const SUnit *Node, - const ScheduleDAG *Graph); - static std::string getNodeAttributes(const SUnit *N, - const ScheduleDAG *Graph) { - return "shape=Mrecord"; - } - - static void addCustomGraphFeatures(ScheduleDAG *G, - GraphWriter &GW) { - // Draw a special "GraphRoot" node to indicate the root of the graph. - GW.emitSimpleNode(0, "plaintext=circle", "GraphRoot"); - if (G->DAG) { - // For an SDNode-based ScheduleDAG, point to the root of the ScheduleDAG. - const SDNode *N = G->DAG->getRoot().getNode(); - if (N && N->getNodeId() != -1) - GW.emitEdge(0, -1, &G->SUnits[N->getNodeId()], -1, - "color=blue,style=dashed"); - } else { - // For a MachineInstr-based ScheduleDAG, find a root to point to. - for (unsigned i = 0, e = G->SUnits.size(); i != e; ++i) { - if (G->SUnits[i].Succs.empty()) { - GW.emitEdge(0, -1, &G->SUnits[i], -1, - "color=blue,style=dashed"); - break; - } - } - } - } - }; -} - -std::string DOTGraphTraits::getNodeLabel(const SUnit *SU, - const ScheduleDAG *G) { - return G->getGraphNodeLabel(SU); -} - -std::string ScheduleDAG::getGraphNodeLabel(const SUnit *SU) const { +std::string ScheduleDAGSDNodes::getGraphNodeLabel(const SUnit *SU) const { std::string s; raw_string_ostream O(s); O << "SU(" << SU->NodeNum << "): "; @@ -467,17 +403,13 @@ return O.str(); } -/// viewGraph - Pop up a ghostview window with the reachable parts of the DAG -/// rendered using 'dot'. -/// -void ScheduleDAG::viewGraph() { -// This code is only for debugging! -#ifndef NDEBUG - ViewGraph(this, "dag." + MF->getFunction()->getName(), - "Scheduling-Units Graph for " + MF->getFunction()->getName() + ':' + - BB->getBasicBlock()->getName()); -#else - cerr << "ScheduleDAG::viewGraph is only available in debug builds on " - << "systems with Graphviz or gv!\n"; -#endif // NDEBUG +void ScheduleDAGSDNodes::getCustomGraphFeatures(GraphWriter &GW) const { + if (DAG) { + // Draw a special "GraphRoot" node to indicate the root of the graph. + GW.emitSimpleNode(0, "plaintext=circle", "GraphRoot"); + const SDNode *N = DAG->getRoot().getNode(); + if (N && N->getNodeId() != -1) + GW.emitEdge(0, -1, &SUnits[N->getNodeId()], -1, + "color=blue,style=dashed"); + } } Modified: llvm/trunk/lib/Target/CellSPU/SPUHazardRecognizers.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUHazardRecognizers.h?rev=59676&r1=59675&r2=59676&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUHazardRecognizers.h (original) +++ llvm/trunk/lib/Target/CellSPU/SPUHazardRecognizers.h Wed Nov 19 17:18:57 2008 @@ -15,7 +15,7 @@ #ifndef SPUHAZRECS_H #define SPUHAZRECS_H -#include "llvm/CodeGen/ScheduleDAG.h" +#include "llvm/CodeGen/ScheduleDAGSDNodes.h" #include "SPUInstrInfo.h" namespace llvm { Modified: llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.h?rev=59676&r1=59675&r2=59676&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.h (original) +++ llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.h Wed Nov 19 17:18:57 2008 @@ -14,7 +14,7 @@ #ifndef PPCHAZRECS_H #define PPCHAZRECS_H -#include "llvm/CodeGen/ScheduleDAG.h" +#include "llvm/CodeGen/ScheduleDAGSDNodes.h" #include "PPCInstrInfo.h" namespace llvm { From evan.cheng at apple.com Wed Nov 19 17:21:11 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 19 Nov 2008 23:21:11 -0000 Subject: [llvm-commits] [llvm] r59677 - /llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp Message-ID: <200811192321.mAJNLCiu024580@zion.cs.uiuc.edu> Author: evancheng Date: Wed Nov 19 17:21:11 2008 New Revision: 59677 URL: http://llvm.org/viewvc/llvm-project?rev=59677&view=rev Log: Eliminate a compile time warning. Modified: llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp Modified: llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp?rev=59677&r1=59676&r2=59677&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp (original) +++ llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp Wed Nov 19 17:21:11 2008 @@ -516,10 +516,12 @@ assert(0 && "psuedo instructions should be removed before code emission"); break; case TargetInstrInfo::INLINEASM: { - const char* Value = MI.getOperand(0).getSymbolName(); - /* We allow inline assembler nodes with empty bodies - they can - implicitly define registers, which is ok for JIT. */ - assert((Value[0] == 0) && "JIT does not support inline asm!\n"); + // We allow inline assembler nodes with empty bodies - they can + // implicitly define registers, which is ok for JIT. + if (MI.getOperand(0).getSymbolName()[0]) { + assert(0 && "JIT does not support inline asm!\n"); + abort(); + } break; } case TargetInstrInfo::DBG_LABEL: From evan.cheng at apple.com Wed Nov 19 17:21:33 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 19 Nov 2008 23:21:33 -0000 Subject: [llvm-commits] [llvm] r59678 - /llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp Message-ID: <200811192321.mAJNLXKF024620@zion.cs.uiuc.edu> Author: evancheng Date: Wed Nov 19 17:21:33 2008 New Revision: 59678 URL: http://llvm.org/viewvc/llvm-project?rev=59678&view=rev Log: Eliminate a compile time warning. Modified: llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp Modified: llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp?rev=59678&r1=59677&r2=59678&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp Wed Nov 19 17:21:33 2008 @@ -552,10 +552,12 @@ default: abort(); // FIXME: case TargetInstrInfo::INLINEASM: { - const char* Value = MI.getOperand(0).getSymbolName(); - /* We allow inline assembler nodes with empty bodies - they can - implicitly define registers, which is ok for JIT. */ - assert((Value[0] == 0) && "JIT does not support inline asm!\n"); + // We allow inline assembler nodes with empty bodies - they can + // implicitly define registers, which is ok for JIT. + if (MI.getOperand(0).getSymbolName()[0]) { + assert(0 && "JIT does not support inline asm!\n"); + abort(); + } break; } case TargetInstrInfo::DBG_LABEL: From gohman at apple.com Wed Nov 19 17:39:23 2008 From: gohman at apple.com (Dan Gohman) Date: Wed, 19 Nov 2008 23:39:23 -0000 Subject: [llvm-commits] [llvm] r59679 - /llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp Message-ID: <200811192339.mAJNdOHq025227@zion.cs.uiuc.edu> Author: djg Date: Wed Nov 19 17:39:02 2008 New Revision: 59679 URL: http://llvm.org/viewvc/llvm-project?rev=59679&view=rev Log: Simplify this code a little. In the fast scheduler, CreateNewSUnit and CreateClone don't add any extra value. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp?rev=59679&r1=59678&r2=59679&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp Wed Nov 19 17:39:02 2008 @@ -97,18 +97,6 @@ SmallVector&); bool DelayForLiveRegsBottomUp(SUnit*, SmallVector&); void ListScheduleBottomUp(); - - /// CreateNewSUnit - Creates a new SUnit and returns a pointer to it. - SUnit *CreateNewSUnit(SDNode *N) { - SUnit *NewNode = NewSUnit(N); - return NewNode; - } - - /// CreateClone - Creates a new SUnit from an existing one. - SUnit *CreateClone(SUnit *N) { - SUnit *NewNode = Clone(N); - return NewNode; - } }; } // end anonymous namespace @@ -256,7 +244,7 @@ DAG->ReplaceAllUsesOfValueWith(SDValue(SU->getNode(), OldNumVals-1), SDValue(LoadNode, 1)); - SUnit *NewSU = CreateNewSUnit(N); + SUnit *NewSU = NewSUnit(N); assert(N->getNodeId() == -1 && "Node already inserted!"); N->setNodeId(NewSU->NodeNum); @@ -282,7 +270,7 @@ LoadSU = &SUnits[LoadNode->getNodeId()]; isNewLoad = false; } else { - LoadSU = CreateNewSUnit(LoadNode); + LoadSU = NewSUnit(LoadNode); LoadNode->setNodeId(LoadSU->NodeNum); LoadSU->Depth = SU->Depth; @@ -360,7 +348,7 @@ } DOUT << "Duplicating SU # " << SU->NodeNum << "\n"; - NewSU = CreateClone(SU); + NewSU = Clone(SU); // New SUnit has the exact same predecessors. for (SUnit::pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); @@ -399,11 +387,11 @@ const TargetRegisterClass *DestRC, const TargetRegisterClass *SrcRC, SmallVector &Copies) { - SUnit *CopyFromSU = CreateNewSUnit(NULL); + SUnit *CopyFromSU = NewSUnit(static_cast(NULL)); CopyFromSU->CopySrcRC = SrcRC; CopyFromSU->CopyDstRC = DestRC; - SUnit *CopyToSU = CreateNewSUnit(NULL); + SUnit *CopyToSU = NewSUnit(static_cast(NULL)); CopyToSU->CopySrcRC = DestRC; CopyToSU->CopyDstRC = SrcRC; From gohman at apple.com Wed Nov 19 17:43:39 2008 From: gohman at apple.com (Dan Gohman) Date: Wed, 19 Nov 2008 23:43:39 -0000 Subject: [llvm-commits] [test-suite] r59680 - /test-suite/trunk/Makefile.programs Message-ID: <200811192343.mAJNhd6X025506@zion.cs.uiuc.edu> Author: djg Date: Wed Nov 19 17:43:35 2008 New Revision: 59680 URL: http://llvm.org/viewvc/llvm-project?rev=59680&view=rev Log: Test post-pass scheduling with LLCBETA. Modified: test-suite/trunk/Makefile.programs Modified: test-suite/trunk/Makefile.programs URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/Makefile.programs?rev=59680&r1=59679&r2=59680&view=diff ============================================================================== --- test-suite/trunk/Makefile.programs (original) +++ test-suite/trunk/Makefile.programs Wed Nov 19 17:43:35 2008 @@ -226,7 +226,8 @@ LLCBETAOPTION := -sched=simple endif ifeq ($(ARCH),x86) -LLCBETAOPTION := -machine-licm +LLCBETAOPTION := -disable-post-RA-scheduler=false +#-machine-licm #-fast-isel #-aggressive-remat #-new-spilling-heuristic From isanbard at gmail.com Wed Nov 19 18:12:05 2008 From: isanbard at gmail.com (Bill Wendling) Date: Thu, 20 Nov 2008 00:12:05 -0000 Subject: [llvm-commits] [llvm] r59681 - /llvm/trunk/utils/buildit/build_llvm Message-ID: <200811200012.mAK0C5AO027145@zion.cs.uiuc.edu> Author: void Date: Wed Nov 19 18:11:57 2008 New Revision: 59681 URL: http://llvm.org/viewvc/llvm-project?rev=59681&view=rev Log: Copy the tblgen utility. Modified: llvm/trunk/utils/buildit/build_llvm Modified: llvm/trunk/utils/buildit/build_llvm URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/buildit/build_llvm?rev=59681&r1=59680&r2=59681&view=diff ============================================================================== --- llvm/trunk/utils/buildit/build_llvm (original) +++ llvm/trunk/utils/buildit/build_llvm Wed Nov 19 18:11:57 2008 @@ -179,6 +179,9 @@ strip -Sx $DEST_DIR$DEST_ROOT/lib/*.so fi +# Copy over the tblgen utility. +cp `find $DIR -name tblgen` $DT_HOME/local/bin + # Remove .dir files cd $DEST_DIR$DEST_ROOT rm bin/.dir etc/llvm/.dir lib/.dir From gohman at apple.com Wed Nov 19 18:17:38 2008 From: gohman at apple.com (Dan Gohman) Date: Wed, 19 Nov 2008 16:17:38 -0800 Subject: [llvm-commits] [llvm] r59681 - /llvm/trunk/utils/buildit/build_llvm In-Reply-To: <200811200012.mAK0C5AO027145@zion.cs.uiuc.edu> References: <200811200012.mAK0C5AO027145@zion.cs.uiuc.edu> Message-ID: <407ADDD8-9641-49E1-BE6C-837F01D21016@apple.com> On Nov 19, 2008, at 4:12 PM, Bill Wendling wrote: > Author: void > Date: Wed Nov 19 18:11:57 2008 > New Revision: 59681 > > URL: http://llvm.org/viewvc/llvm-project?rev=59681&view=rev > Log: > Copy the tblgen utility. What use is there for tblgen outside of the LLVM build? Dan From dpatel at apple.com Wed Nov 19 18:56:24 2008 From: dpatel at apple.com (Devang Patel) Date: Thu, 20 Nov 2008 00:56:24 -0000 Subject: [llvm-commits] [test-suite] r59685 - /test-suite/trunk/TEST.dbgopt.Makefile Message-ID: <200811200056.mAK0uOT5031173@zion.cs.uiuc.edu> Author: dpatel Date: Wed Nov 19 18:56:24 2008 New Revision: 59685 URL: http://llvm.org/viewvc/llvm-project?rev=59685&view=rev Log: Add -strip-debug on the command line to remove debug info at the end. Modified: test-suite/trunk/TEST.dbgopt.Makefile Modified: test-suite/trunk/TEST.dbgopt.Makefile URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/TEST.dbgopt.Makefile?rev=59685&r1=59684&r2=59685&view=diff ============================================================================== --- test-suite/trunk/TEST.dbgopt.Makefile (original) +++ test-suite/trunk/TEST.dbgopt.Makefile Wed Nov 19 18:56:24 2008 @@ -8,7 +8,7 @@ # is influencing the optimizer. # # $ opt input.bc -strip-nondebug -strip-debug -std-compile-output -strip -o first.bc -# $ opt input.bc -strip-nondebug -std-compile-output -strip -o second.bc +# $ opt input.bc -strip-nondebug -std-compile-output -strip-debug -strip -o second.bc # ##===----------------------------------------------------------------------===## @@ -21,7 +21,7 @@ $(LLVMGXX) $*.cpp -g --emit-llvm -c -o Output/$*.bc $(LOPT) Output/$*.bc -strip-nondebug -strip-debug -std-compile-opts -strip -f -o Output/$*.t.bc $(LDIS) Output/$*.t.bc -f -o Output/$*.first.ll - $(LOPT) Output/$*.bc -strip-nondebug -std-compile-opts -strip -f -o Output/$*.t.bc + $(LOPT) Output/$*.bc -strip-nondebug -std-compile-opts -strip-debug -strip -f -o Output/$*.t.bc $(LDIS) Output/$*.t.bc -f -o Output/$*.second.ll @-if diff Output/$*.first.ll Output/$*.second.ll > Output/$*.diff; then \ echo "--------- TEST-PASS: $*"; \ @@ -34,7 +34,7 @@ $(LLVMGCC) $*.c -g --emit-llvm -c -o Output/$*.bc $(LOPT) Output/$*.bc -strip-nondebug -strip-debug -std-compile-opts -strip -f -o Output/$*.t.bc $(LDIS) Output/$*.t.bc -f -o Output/$*.first.ll - $(LOPT) Output/$*.bc -strip-nondebug -std-compile-opts -strip -f -o Output/$*.t.bc + $(LOPT) Output/$*.bc -strip-nondebug -std-compile-opts -strip-debug -strip -f -o Output/$*.t.bc $(LDIS) Output/$*.t.bc -f -o Output/$*.second.ll @-if diff Output/$*.first.ll Output/$*.second.ll > Output/$*.diff; then \ echo "--------- TEST-PASS: $*"; \ From gohman at apple.com Wed Nov 19 19:00:08 2008 From: gohman at apple.com (Dan Gohman) Date: Thu, 20 Nov 2008 01:00:08 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r59686 - in /llvm-gcc-4.2/trunk/gcc: llvm-backend.cpp llvm-linker-hack.cpp Message-ID: <200811200100.mAK108Vt031520@zion.cs.uiuc.edu> Author: djg Date: Wed Nov 19 19:00:08 2008 New Revision: 59686 URL: http://llvm.org/viewvc/llvm-project?rev=59686&view=rev Log: Change ScheduleDAG.h to ScheduleDAGSDNodes.h to be consistent with recent LLVM scheduler changes. Modified: llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp llvm-gcc-4.2/trunk/gcc/llvm-linker-hack.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp?rev=59686&r1=59685&r2=59686&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Wed Nov 19 19:00:08 2008 @@ -36,7 +36,7 @@ #include "llvm/Bitcode/ReaderWriter.h" #include "llvm/CodeGen/RegAllocRegistry.h" #include "llvm/CodeGen/SchedulerRegistry.h" -#include "llvm/CodeGen/ScheduleDAG.h" +#include "llvm/CodeGen/ScheduleDAGSDNodes.h" #include "llvm/Target/SubtargetFeature.h" #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetLowering.h" Modified: llvm-gcc-4.2/trunk/gcc/llvm-linker-hack.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-linker-hack.cpp?rev=59686&r1=59685&r2=59686&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-linker-hack.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-linker-hack.cpp Wed Nov 19 19:00:08 2008 @@ -28,7 +28,7 @@ #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/IPO.h" #include "llvm/Bitcode/ReaderWriter.h" -#include "llvm/CodeGen/ScheduleDAG.h" +#include "llvm/CodeGen/ScheduleDAGSDNodes.h" #include "llvm/CodeGen/Passes.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Streams.h" From dpatel at apple.com Wed Nov 19 19:20:42 2008 From: dpatel at apple.com (Devang Patel) Date: Thu, 20 Nov 2008 01:20:42 -0000 Subject: [llvm-commits] [llvm] r59688 - /llvm/trunk/lib/Transforms/IPO/StripSymbols.cpp Message-ID: <200811200120.mAK1KguV000835@zion.cs.uiuc.edu> Author: dpatel Date: Wed Nov 19 19:20:42 2008 New Revision: 59688 URL: http://llvm.org/viewvc/llvm-project?rev=59688&view=rev Log: Do not forget llvm.dbg.declare's first argument while removing debugging information. Modified: llvm/trunk/lib/Transforms/IPO/StripSymbols.cpp Modified: llvm/trunk/lib/Transforms/IPO/StripSymbols.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/StripSymbols.cpp?rev=59688&r1=59687&r2=59688&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/StripSymbols.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/StripSymbols.cpp Wed Nov 19 19:20:42 2008 @@ -99,7 +99,8 @@ GV->eraseFromParent(); } else if (!isa(C)) - C->destroyConstant(); + if (isa(C->getType())) + C->destroyConstant(); // If the constant referenced anything, see if we can delete it as well. for (SmallPtrSet::iterator OI = Operands.begin(), @@ -245,11 +246,18 @@ if (Declare) { while (!Declare->use_empty()) { CallInst *CI = cast(Declare->use_back()); - Value *Arg = CI->getOperand(2); + Value *Arg1 = CI->getOperand(1); + Value *Arg2 = CI->getOperand(2); assert(CI->use_empty() && "llvm.dbg intrinsic should have void result"); CI->eraseFromParent(); - if (Arg->use_empty()) - if (Constant *C = dyn_cast(Arg)) + if (Arg1->use_empty()) { + if (Constant *C = dyn_cast(Arg1)) + DeadConstants.push_back(C); + if (Instruction *I = dyn_cast(Arg1)) + I->eraseFromParent(); + } + if (Arg2->use_empty()) + if (Constant *C = dyn_cast(Arg2)) DeadConstants.push_back(C); } Declare->eraseFromParent(); From gohman at apple.com Wed Nov 19 19:26:25 2008 From: gohman at apple.com (Dan Gohman) Date: Thu, 20 Nov 2008 01:26:25 -0000 Subject: [llvm-commits] [llvm] r59689 - in /llvm/trunk: include/llvm/CodeGen/ScheduleDAG.h lib/CodeGen/PostRASchedulerList.cpp lib/CodeGen/ScheduleDAG.cpp lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Message-ID: <200811200126.mAK1QP53001162@zion.cs.uiuc.edu> Author: djg Date: Wed Nov 19 19:26:25 2008 New Revision: 59689 URL: http://llvm.org/viewvc/llvm-project?rev=59689&view=rev Log: Factor out the code for verifying the work of the scheduler, extend it a bit, and make use of it in all schedulers, to ensure consistent checking. Modified: llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp llvm/trunk/lib/CodeGen/ScheduleDAG.cpp llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Modified: llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h?rev=59689&r1=59688&r2=59689&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h (original) +++ llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h Wed Nov 19 19:26:25 2008 @@ -96,7 +96,7 @@ Latency(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0), NumSuccsLeft(0), isTwoAddress(false), isCommutable(false), hasPhysRegDefs(false), isPending(false), isAvailable(false), isScheduled(false), - CycleBound(0), Cycle(0), Depth(0), Height(0), + CycleBound(0), Cycle(~0u), Depth(0), Height(0), CopyDstRC(NULL), CopySrcRC(NULL) {} /// SUnit - Construct an SUnit for post-regalloc scheduling to represent @@ -106,7 +106,7 @@ Latency(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0), NumSuccsLeft(0), isTwoAddress(false), isCommutable(false), hasPhysRegDefs(false), isPending(false), isAvailable(false), isScheduled(false), - CycleBound(0), Cycle(0), Depth(0), Height(0), + CycleBound(0), Cycle(~0u), Depth(0), Height(0), CopyDstRC(NULL), CopySrcRC(NULL) {} /// setNode - Assign the representative SDNode for this SUnit. @@ -308,6 +308,12 @@ /// the ScheduleDAG. virtual void addCustomGraphFeatures(GraphWriter &GW) const {} +#ifndef NDEBUG + /// VerifySchedule - Verify that all SUnits were scheduled and that + /// their state is consistent. + void VerifySchedule(bool isBottomUp); +#endif + protected: void AddMemOperand(MachineInstr *MI, const MachineMemOperand &MO); Modified: llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp?rev=59689&r1=59688&r2=59689&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp (original) +++ llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Wed Nov 19 19:26:25 2008 @@ -229,18 +229,7 @@ } #ifndef NDEBUG - // Verify that all SUnits were scheduled. - bool AnyNotSched = false; - for (unsigned i = 0, e = SUnits.size(); i != e; ++i) { - if (SUnits[i].NumPredsLeft != 0) { - if (!AnyNotSched) - cerr << "*** List scheduling failed! ***\n"; - SUnits[i].dump(this); - cerr << "has not been scheduled!\n"; - AnyNotSched = true; - } - } - assert(!AnyNotSched); + VerifySchedule(/*isBottomUp=*/false); #endif } Modified: llvm/trunk/lib/CodeGen/ScheduleDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ScheduleDAG.cpp?rev=59689&r1=59688&r2=59689&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/ScheduleDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/ScheduleDAG.cpp Wed Nov 19 19:26:25 2008 @@ -208,3 +208,57 @@ } cerr << "\n"; } + +#ifndef NDEBUG +/// VerifySchedule - Verify that all SUnits were scheduled and that +/// their state is consistent. +/// +void ScheduleDAG::VerifySchedule(bool isBottomUp) { + bool AnyNotSched = false; + unsigned DeadNodes = 0; + unsigned Noops = 0; + for (unsigned i = 0, e = SUnits.size(); i != e; ++i) { + if (!SUnits[i].isScheduled) { + if (SUnits[i].NumPreds == 0 && SUnits[i].NumSuccs == 0) { + ++DeadNodes; + continue; + } + if (!AnyNotSched) + cerr << "*** Scheduling failed! ***\n"; + SUnits[i].dump(this); + cerr << "has not been scheduled!\n"; + AnyNotSched = true; + } + if (SUnits[i].isScheduled && SUnits[i].Cycle > (unsigned)INT_MAX) { + if (!AnyNotSched) + cerr << "*** Scheduling failed! ***\n"; + SUnits[i].dump(this); + cerr << "has an unexpected Cycle value!\n"; + AnyNotSched = true; + } + if (isBottomUp) { + if (SUnits[i].NumSuccsLeft != 0) { + if (!AnyNotSched) + cerr << "*** Scheduling failed! ***\n"; + SUnits[i].dump(this); + cerr << "has successors left!\n"; + AnyNotSched = true; + } + } else { + if (SUnits[i].NumPredsLeft != 0) { + if (!AnyNotSched) + cerr << "*** Scheduling failed! ***\n"; + SUnits[i].dump(this); + cerr << "has predecessors left!\n"; + AnyNotSched = true; + } + } + } + for (unsigned i = 0, e = Sequence.size(); i != e; ++i) + if (!Sequence[i]) + ++Noops; + assert(!AnyNotSched); + assert(Sequence.size() + DeadNodes - Noops == SUnits.size() && + "The number of nodes scheduled doesn't match the expected number!"); +} +#endif Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp?rev=59689&r1=59688&r2=59689&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Wed Nov 19 19:26:25 2008 @@ -260,18 +260,7 @@ } #ifndef NDEBUG - // Verify that all SUnits were scheduled. - bool AnyNotSched = false; - for (unsigned i = 0, e = SUnits.size(); i != e; ++i) { - if (SUnits[i].NumPredsLeft != 0) { - if (!AnyNotSched) - cerr << "*** List scheduling failed! ***\n"; - SUnits[i].dump(this); - cerr << "has not been scheduled!\n"; - AnyNotSched = true; - } - } - assert(!AnyNotSched); + VerifySchedule(/*isBottomUp=*/false); #endif } Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp?rev=59689&r1=59688&r2=59689&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Wed Nov 19 19:26:25 2008 @@ -1069,38 +1069,8 @@ // Reverse the order if it is bottom up. std::reverse(Sequence.begin(), Sequence.end()); - #ifndef NDEBUG - // Verify that all SUnits were scheduled. - bool AnyNotSched = false; - unsigned DeadNodes = 0; - unsigned Noops = 0; - for (unsigned i = 0, e = SUnits.size(); i != e; ++i) { - if (!SUnits[i].isScheduled) { - if (SUnits[i].NumPreds == 0 && SUnits[i].NumSuccs == 0) { - ++DeadNodes; - continue; - } - if (!AnyNotSched) - cerr << "*** List scheduling failed! ***\n"; - SUnits[i].dump(this); - cerr << "has not been scheduled!\n"; - AnyNotSched = true; - } - if (SUnits[i].NumSuccsLeft != 0) { - if (!AnyNotSched) - cerr << "*** List scheduling failed! ***\n"; - SUnits[i].dump(this); - cerr << "has successors left!\n"; - AnyNotSched = true; - } - } - for (unsigned i = 0, e = Sequence.size(); i != e; ++i) - if (!Sequence[i]) - ++Noops; - assert(!AnyNotSched); - assert(Sequence.size() + DeadNodes - Noops == SUnits.size() && - "The number of nodes scheduled doesn't match the expected number!"); + VerifySchedule(isBottomUp); #endif } @@ -1197,43 +1167,12 @@ ++CurCycle; } - #ifndef NDEBUG - // Verify that all SUnits were scheduled. - bool AnyNotSched = false; - unsigned DeadNodes = 0; - unsigned Noops = 0; - for (unsigned i = 0, e = SUnits.size(); i != e; ++i) { - if (!SUnits[i].isScheduled) { - if (SUnits[i].NumPreds == 0 && SUnits[i].NumSuccs == 0) { - ++DeadNodes; - continue; - } - if (!AnyNotSched) - cerr << "*** List scheduling failed! ***\n"; - SUnits[i].dump(this); - cerr << "has not been scheduled!\n"; - AnyNotSched = true; - } - if (SUnits[i].NumPredsLeft != 0) { - if (!AnyNotSched) - cerr << "*** List scheduling failed! ***\n"; - SUnits[i].dump(this); - cerr << "has predecessors left!\n"; - AnyNotSched = true; - } - } - for (unsigned i = 0, e = Sequence.size(); i != e; ++i) - if (!Sequence[i]) - ++Noops; - assert(!AnyNotSched); - assert(Sequence.size() + DeadNodes - Noops == SUnits.size() && - "The number of nodes scheduled doesn't match the expected number!"); + VerifySchedule(isBottomUp); #endif } - //===----------------------------------------------------------------------===// // RegReductionPriorityQueue Implementation //===----------------------------------------------------------------------===// From gohman at apple.com Wed Nov 19 19:41:34 2008 From: gohman at apple.com (Dan Gohman) Date: Thu, 20 Nov 2008 01:41:34 -0000 Subject: [llvm-commits] [llvm] r59692 - /llvm/trunk/lib/CodeGen/ScheduleDAG.cpp Message-ID: <200811200141.mAK1fYMc002197@zion.cs.uiuc.edu> Author: djg Date: Wed Nov 19 19:41:34 2008 New Revision: 59692 URL: http://llvm.org/viewvc/llvm-project?rev=59692&view=rev Log: Add #include to get the definition of INT_MAX. Modified: llvm/trunk/lib/CodeGen/ScheduleDAG.cpp Modified: llvm/trunk/lib/CodeGen/ScheduleDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ScheduleDAG.cpp?rev=59692&r1=59691&r2=59692&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/ScheduleDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/ScheduleDAG.cpp Wed Nov 19 19:41:34 2008 @@ -18,6 +18,7 @@ #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Support/Debug.h" +#include using namespace llvm; ScheduleDAG::ScheduleDAG(SelectionDAG *dag, MachineBasicBlock *bb, From evan.cheng at apple.com Wed Nov 19 20:25:51 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 20 Nov 2008 02:25:51 -0000 Subject: [llvm-commits] [llvm] r59696 - /llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp Message-ID: <200811200225.mAK2PpOG005284@zion.cs.uiuc.edu> Author: evancheng Date: Wed Nov 19 20:25:51 2008 New Revision: 59696 URL: http://llvm.org/viewvc/llvm-project?rev=59696&view=rev Log: Fix a thinko. MO is getOperand(i-1) so we don't have to adjust e. Modified: llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp Modified: llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp?rev=59696&r1=59695&r2=59696&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp Wed Nov 19 20:25:51 2008 @@ -686,9 +686,7 @@ unsigned ARMCodeEmitter::getAddrModeSBit(const MachineInstr &MI, const TargetInstrDesc &TID) const { - unsigned e = TID.getNumOperands(); - if (e) --e; // Looks at the last non-implicit operand as well. - for (unsigned i = MI.getNumOperands(); i != e; --i) { + for (unsigned i = MI.getNumOperands(), e = TID.getNumOperands(); i != e; --i){ const MachineOperand &MO = MI.getOperand(i-1); if (MO.isReg() && MO.isDef() && MO.getReg() == ARM::CPSR) return 1 << ARMII::S_BitShift; From evan.cheng at apple.com Wed Nov 19 20:32:35 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 20 Nov 2008 02:32:35 -0000 Subject: [llvm-commits] [llvm] r59697 - in /llvm/trunk: include/llvm/CodeGen/RegisterScavenging.h lib/CodeGen/RegisterScavenging.cpp test/CodeGen/ARM/2008-11-19-ScavengerAssert.ll Message-ID: <200811200232.mAK2WZfx005822@zion.cs.uiuc.edu> Author: evancheng Date: Wed Nov 19 20:32:35 2008 New Revision: 59697 URL: http://llvm.org/viewvc/llvm-project?rev=59697&view=rev Log: - Register scavenger should use MachineRegisterInfo and internal map to find the first use of a register after a given machine instruction. - When scavenging a register, in addition to the spill, insert a restore before the first use. - Abort if client is looking to scavenge a register even when a previously scavenged register is still live. Added: llvm/trunk/test/CodeGen/ARM/2008-11-19-ScavengerAssert.ll Modified: llvm/trunk/include/llvm/CodeGen/RegisterScavenging.h llvm/trunk/lib/CodeGen/RegisterScavenging.cpp Modified: llvm/trunk/include/llvm/CodeGen/RegisterScavenging.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/RegisterScavenging.h?rev=59697&r1=59696&r2=59697&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/RegisterScavenging.h (original) +++ llvm/trunk/include/llvm/CodeGen/RegisterScavenging.h Wed Nov 19 20:32:35 2008 @@ -19,6 +19,7 @@ #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/ADT/BitVector.h" +#include "llvm/ADT/DenseMap.h" namespace llvm { @@ -28,6 +29,9 @@ class TargetRegisterClass; class RegScavenger { + const TargetRegisterInfo *TRI; + const TargetInstrInfo *TII; + MachineRegisterInfo* MRI; MachineBasicBlock *MBB; MachineBasicBlock::iterator MBBI; unsigned NumPhysRegs; @@ -48,6 +52,18 @@ /// const TargetRegisterClass *ScavengedRC; + /// ScavengeRestore - Instruction that restores the scavenged register from + /// stack. + const MachineInstr *ScavengeRestore; + + /// CalleeSavedrRegs - A bitvector of callee saved registers for the target. + /// + BitVector CalleeSavedRegs; + + /// ReservedRegs - A bitvector of reserved registers. + /// + BitVector ReservedRegs; + /// RegsAvailable - The current state of all the physical registers immediately /// before MBBI. One bit per physical register. If bit is set that means it's /// available, unset means the register is currently being used. @@ -57,6 +73,14 @@ /// implicit_def instructions. That means it can be clobbered at will. BitVector ImplicitDefed; + /// CurrDist - Distance from MBB entry to the current instruction MBBI. + /// + unsigned CurrDist; + + /// DistanceMap - Keep track the distance of a MI from the start of the + /// current basic block. + DenseMap DistanceMap; + public: RegScavenger() : MBB(NULL), NumPhysRegs(0), Tracking(false), @@ -143,21 +167,13 @@ } private: - const TargetRegisterInfo *TRI; - const TargetInstrInfo *TII; - MachineRegisterInfo* MRI; - - /// CalleeSavedrRegs - A bitvector of callee saved registers for the target. - /// - BitVector CalleeSavedRegs; - - /// ReservedRegs - A bitvector of reserved registers. - /// - BitVector ReservedRegs; - /// restoreScavengedReg - Restore scavenged by loading it back from the /// emergency spill slot. Mark it used. void restoreScavengedReg(); + + MachineInstr *findFirstUse(MachineBasicBlock *MBB, + MachineBasicBlock::iterator I, unsigned Reg, + unsigned &Dist); }; } // End llvm namespace Modified: llvm/trunk/lib/CodeGen/RegisterScavenging.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegisterScavenging.cpp?rev=59697&r1=59696&r2=59697&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/RegisterScavenging.cpp (original) +++ llvm/trunk/lib/CodeGen/RegisterScavenging.cpp Wed Nov 19 20:32:35 2008 @@ -109,6 +109,9 @@ MBB = mbb; ScavengedReg = 0; ScavengedRC = NULL; + ScavengeRestore = NULL; + CurrDist = 0; + DistanceMap.clear(); // All registers started out unused. RegsAvailable.set(); @@ -126,9 +129,6 @@ } void RegScavenger::restoreScavengedReg() { - if (!ScavengedReg) - return; - TII->loadRegFromStackSlot(*MBB, MBBI, ScavengedReg, ScavengingFrameIndex, ScavengedRC); MachineBasicBlock::iterator II = prior(MBBI); @@ -183,12 +183,14 @@ } MachineInstr *MI = MBBI; + DistanceMap.insert(std::make_pair(MI, CurrDist++)); const TargetInstrDesc &TID = MI->getDesc(); - // Reaching a terminator instruction. Restore a scavenged register (which - // must be life out. - if (TID.isTerminator()) - restoreScavengedReg(); + if (MI == ScavengeRestore) { + ScavengedReg = 0; + ScavengedRC = NULL; + ScavengeRestore = NULL; + } bool IsImpDef = MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF; @@ -214,13 +216,7 @@ const MachineOperand MO = *UseMOs[i].first; unsigned Reg = MO.getReg(); - if (!isUsed(Reg)) { - // Register has been scavenged. Restore it! - if (Reg == ScavengedReg) - restoreScavengedReg(); - else - assert(false && "Using an undefined register!"); - } + assert(isUsed(Reg) && "Using an undefined register!"); if (MO.isKill() && !isReserved(Reg)) { UseRegs.set(Reg); @@ -282,6 +278,8 @@ MBBI = prior(MBBI); MachineInstr *MI = MBBI; + DistanceMap.erase(MI); + --CurrDist; const TargetInstrDesc &TID = MI->getDesc(); // Separate register operands into 3 classes: uses, defs, earlyclobbers. @@ -383,20 +381,37 @@ return (Reg == -1) ? 0 : Reg; } -/// calcDistanceToUse - Calculate the distance to the first use of the +/// findFirstUse - Calculate the distance to the first use of the /// specified register. -static unsigned calcDistanceToUse(MachineBasicBlock *MBB, - MachineBasicBlock::iterator I, unsigned Reg, - const TargetRegisterInfo *TRI) { - unsigned Dist = 0; - I = next(I); - while (I != MBB->end()) { - Dist++; - if (I->readsRegister(Reg, TRI)) - return Dist; - I = next(I); +MachineInstr* +RegScavenger::findFirstUse(MachineBasicBlock *MBB, + MachineBasicBlock::iterator I, unsigned Reg, + unsigned &Dist) { + MachineInstr *UseMI = 0; + Dist = ~0U; + for (MachineRegisterInfo::reg_iterator RI = MRI->reg_begin(Reg), + RE = MRI->reg_end(); RI != RE; ++RI) { + MachineInstr *UDMI = &*RI; + if (UDMI->getParent() != MBB) + continue; + DenseMap::iterator DI = DistanceMap.find(UDMI); + if (DI == DistanceMap.end()) { + // If it's not in map, it's below current MI, let's initialize the + // map. + I = next(I); + unsigned Dist = CurrDist + 1; + while (I != MBB->end()) { + DistanceMap.insert(std::make_pair(I, Dist++)); + I = next(I); + } + } + DI = DistanceMap.find(UDMI); + if (DI->second > CurrDist && DI->second < Dist) { + Dist = DI->second; + UseMI = UDMI; + } } - return Dist + 1; + return UseMI; } unsigned RegScavenger::scavengeRegister(const TargetRegisterClass *RC, @@ -420,27 +435,42 @@ // Find the register whose use is furthest away. unsigned SReg = 0; unsigned MaxDist = 0; + MachineInstr *MaxUseMI = 0; int Reg = Candidates.find_first(); while (Reg != -1) { - unsigned Dist = calcDistanceToUse(MBB, I, Reg, TRI); + unsigned Dist; + MachineInstr *UseMI = findFirstUse(MBB, I, Reg, Dist); + for (const unsigned *AS = TRI->getAliasSet(Reg); *AS; ++AS) { + unsigned AsDist; + MachineInstr *AsUseMI = findFirstUse(MBB, I, *AS, AsDist); + if (AsDist < Dist) { + Dist = AsDist; + UseMI = AsUseMI; + } + } if (Dist >= MaxDist) { MaxDist = Dist; + MaxUseMI = UseMI; SReg = Reg; } Reg = Candidates.find_next(Reg); } if (ScavengedReg != 0) { - // First restore previously scavenged register. - TII->loadRegFromStackSlot(*MBB, I, ScavengedReg, - ScavengingFrameIndex, ScavengedRC); - MachineBasicBlock::iterator II = prior(I); - TRI->eliminateFrameIndex(II, SPAdj, this); + assert(0 && "Scavenger slot is live, unable to scavenge another register!"); + abort(); } + // Spill the scavenged register before I. TII->storeRegToStackSlot(*MBB, I, SReg, true, ScavengingFrameIndex, RC); MachineBasicBlock::iterator II = prior(I); TRI->eliminateFrameIndex(II, SPAdj, this); + + // Restore the scavenged register before its use (or first terminator). + II = MaxUseMI + ? MachineBasicBlock::iterator(MaxUseMI) : MBB->getFirstTerminator(); + TII->loadRegFromStackSlot(*MBB, II, SReg, ScavengingFrameIndex, RC); + ScavengeRestore = prior(II); ScavengedReg = SReg; ScavengedRC = RC; Added: llvm/trunk/test/CodeGen/ARM/2008-11-19-ScavengerAssert.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/2008-11-19-ScavengerAssert.ll?rev=59697&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/ARM/2008-11-19-ScavengerAssert.ll (added) +++ llvm/trunk/test/CodeGen/ARM/2008-11-19-ScavengerAssert.ll Wed Nov 19 20:32:35 2008 @@ -0,0 +1,414 @@ +; RUN: llvm-as < %s | llc -mtriple=arm-apple-darwin9 + + %"struct.Adv5::Ekin<3>" = type <{ i8 }> + %"struct.Adv5::X::Energyflux<3>" = type { double } + %"struct.BinaryNode >, double, MultiPatchView, 3> >,Field >, double, MultiPatchView, 3> > >" = type { %"struct.Field >,double,MultiPatchView, 3> >", %"struct.Field >,double,MultiPatchView, 3> >" } + %"struct.BinaryNode >, double, Remote >,Field >, double, Remote > >" = type { %"struct.Field >,double,Remote >", %"struct.Field >,double,Remote >" } + %"struct.BinaryNode,BinaryNode >, double, MultiPatchView, 3> >, Field >, double, MultiPatchView, 3> > > >" = type { %"struct.Adv5::X::Energyflux<3>", %"struct.BinaryNode >, double, MultiPatchView, 3> >,Field >, double, MultiPatchView, 3> > >" } + %"struct.BinaryNode,BinaryNode >, double, Remote >, Field >, double, Remote > > >" = type { %"struct.Adv5::X::Energyflux<3>", %"struct.BinaryNode >, double, Remote >,Field >, double, Remote > >" } + %"struct.Centering<3>" = type { i32, i32, %"struct.std::vector,std::allocator > >", %"struct.std::vector,std::allocator > >" } + %"struct.ContextMapper<1>" = type { i32 (...)** } + %"struct.DataBlockController" = type { %"struct.RefBlockController", %"struct.Adv5::Ekin<3>"*, i8, %"struct.SingleObservable", i32 } + %"struct.DataBlockPtr" = type { %"struct.RefCountedBlockPtr >" } + %"struct.Domain<1,DomainTraits > >" = type { %"struct.DomainBase > >" } + %"struct.Domain<1,DomainTraits > >" = type { %"struct.DomainBase > >" } + %"struct.Domain<1,DomainTraits > >" = type { %"struct.DomainBase > >" } + %"struct.Domain<3,DomainTraits > >" = type { %"struct.DomainBase > >" } + %"struct.Domain<3,DomainTraits > >" = type { %"struct.DomainBase > >" } + %"struct.Domain<3,DomainTraits > >" = type { %"struct.DomainBase > >" } + %"struct.DomainBase > >" = type { [2 x i32] } + %"struct.DomainBase > >" = type { [3 x %"struct.WrapNoInit >"] } + %"struct.DomainBase > >" = type { i32 } + %"struct.DomainBase > >" = type { [3 x %"struct.WrapNoInit >"] } + %"struct.DomainBase > >" = type { [3 x i32] } + %"struct.DomainBase > >" = type { [3 x %"struct.WrapNoInit >"] } + %"struct.DomainLayout<3>" = type { %"struct.Node,Interval<3> >" } + %"struct.DomainMap,int>" = type { i32, %"struct.DomainMapNode,int>"*, %"struct.DomainMapIterator,int>" } + %"struct.DomainMapIterator,int>" = type { %"struct.DomainMapNode,int>"*, %"struct.std::_List_const_iterator >" } + %"struct.DomainMapNode,int>" = type { %"struct.Interval<1>", %"struct.DomainMapNode,int>"*, %"struct.DomainMapNode,int>"*, %"struct.DomainMapNode,int>"*, %"struct.std::list,std::allocator > >" } + %"struct.Engine<3,Zero,ConstantFunction>" = type { %"struct.Adv5::Ekin<3>", %"struct.Interval<3>", [3 x i32] } + %"struct.Engine<3,double,Brick>" = type { %"struct.Pooma::BrickBase<3>", %"struct.DataBlockPtr", double* } + %"struct.Engine<3,double,BrickView>" = type { %"struct.Pooma::BrickViewBase<3>", %"struct.DataBlockPtr", double* } + %"struct.Engine<3,double,ConstantFunction>" = type { double, %"struct.Interval<3>", [3 x i32] } + %"struct.Engine<3,double,ExpressionTag, BinaryNode >, double, MultiPatchView, 3> >, Field >, double, MultiPatchView, 3> > > > > >" = type { %"struct.BinaryNode,BinaryNode >, double, MultiPatchView, 3> >, Field >, double, MultiPatchView, 3> > > >", %"struct.Interval<3>" } + %"struct.Engine<3,double,ExpressionTag, BinaryNode >, double, Remote >, Field >, double, Remote > > > > >" = type { %"struct.BinaryNode,BinaryNode >, double, Remote >, Field >, double, Remote > > >", %"struct.Interval<3>" } + %"struct.Engine<3,double,MultiPatch > >" = type { %"struct.ContextMapper<1>", %"struct.GridLayout<3>", %"struct.RefCountedBlockPtr >,false,RefBlockController > > >", i32* } + %"struct.Engine<3,double,MultiPatchView, 3> >" = type { %"struct.GridLayoutView<3,3>", %"struct.Engine<3,double,MultiPatch > >" } + %"struct.Engine<3,double,Remote >" = type { %"struct.Interval<3>", i32, %"struct.RefCountedPtr > >" } + %"struct.Engine<3,double,Remote >" = type { %"struct.Interval<3>", i32, %"struct.RefCountedPtr > >" } + %"struct.Field >,Zero,ConstantFunction>" = type { %"struct.FieldEngine >,Zero,ConstantFunction>" } + %"struct.Field >,double,ConstantFunction>" = type { %"struct.FieldEngine >,double,ConstantFunction>" } + %"struct.Field >,double,ExpressionTag, BinaryNode >, double, MultiPatchView, 3> >, Field >, double, MultiPatchView, 3> > > > > >" = type { %"struct.FieldEngine >,double,ExpressionTag, BinaryNode >, double, MultiPatchView, 3> >, Field >, double, MultiPatchView, 3> > > > > >" } + %"struct.Field >,double,ExpressionTag, BinaryNode >, double, Remote >, Field >, double, Remote > > > > >" = type { %"struct.FieldEngine >,double,ExpressionTag, BinaryNode >, double, Remote >, Field >, double, Remote > > > > >" } + %"struct.Field >,double,MultiPatch > >" = type { %"struct.FieldEngine >,double,MultiPatch > >" } + %"struct.Field >,double,MultiPatchView, 3> >" = type { %"struct.FieldEngine >,double,MultiPatchView, 3> >" } + %"struct.Field >,double,Remote >" = type { %"struct.FieldEngine >,double,Remote >" } + %"struct.FieldEngine >,Zero,ConstantFunction>" = type { i32, %"struct.Centering<3>", i32, %"struct.RefCountedBlockPtr, ConstantFunction>,false,RefBlockController, ConstantFunction> > >", %"struct.Interval<3>", %"struct.GuardLayers<3>", %"struct.UniformRectilinearMesh >" } + %"struct.FieldEngine >,double,ConstantFunction>" = type { i32, %"struct.Centering<3>", i32, %"struct.RefCountedBlockPtr,false,RefBlockController > >", %"struct.Interval<3>", %"struct.GuardLayers<3>", %"struct.UniformRectilinearMesh >" } + %"struct.FieldEngine >,double,ExpressionTag, BinaryNode >, double, MultiPatchView, 3> >, Field >, double, MultiPatchView, 3> > > > > >" = type { %"struct.Engine<3,double,ExpressionTag, BinaryNode >, double, MultiPatchView, 3> >, Field >, double, MultiPatchView, 3> > > > > >", %"struct.Field >,double,MultiPatchView, 3> >"* } + %"struct.FieldEngine >,double,ExpressionTag, BinaryNode >, double, Remote >, Field >, double, Remote > > > > >" = type { %"struct.Engine<3,double,ExpressionTag, BinaryNode >, double, Remote >, Field >, double, Remote > > > > >", %"struct.Field >,double,Remote >"* } + %"struct.FieldEngine >,double,MultiPatch > >" = type { i32, %"struct.Centering<3>", i32, %"struct.RefCountedBlockPtr > >,false,RefBlockController > > > >", %"struct.Interval<3>", %"struct.GuardLayers<3>", %"struct.UniformRectilinearMesh >" } + %"struct.FieldEngine >,double,MultiPatchView, 3> >" = type { i32, %"struct.Centering<3>", i32, %"struct.RefCountedBlockPtr, 3> >,false,RefBlockController, 3> > > >", %"struct.Interval<3>", %"struct.GuardLayers<3>", %"struct.UniformRectilinearMesh >" } + %"struct.FieldEngine >,double,Remote >" = type { i32, %"struct.Centering<3>", i32, %"struct.RefCountedBlockPtr >,false,RefBlockController > > >", %"struct.Interval<3>", %"struct.GuardLayers<3>", %"struct.UniformRectilinearMesh >" } + %"struct.FieldEngineBaseData<3,Zero,ConstantFunction>" = type { %"struct.Engine<3,Zero,ConstantFunction>", %struct.RelationList } + %"struct.FieldEngineBaseData<3,double,ConstantFunction>" = type { %"struct.Engine<3,double,ConstantFunction>", %struct.RelationList } + %"struct.FieldEngineBaseData<3,double,MultiPatch > >" = type { %"struct.Engine<3,double,MultiPatch > >", %struct.RelationList } + %"struct.FieldEngineBaseData<3,double,MultiPatchView, 3> >" = type { %"struct.Engine<3,double,MultiPatchView, 3> >", %struct.RelationList } + %"struct.FieldEngineBaseData<3,double,Remote >" = type { %"struct.Engine<3,double,Remote >", %struct.RelationList } + %struct.GlobalIDDataBase = type { %"struct.std::vector >", %"struct.std::map,std::allocator > >" } + %"struct.GlobalIDDataBase::Pack" = type { i32, i32, i32, i32 } + %"struct.GridLayout<3>" = type { %"struct.ContextMapper<1>", %"struct.LayoutBase<3,GridLayoutData<3> >", %"struct.Observable >" } + %"struct.GridLayoutData<3>" = type { %"struct.LayoutBaseData<3>", %struct.RefCounted, [21 x i8], i8, [3 x i32], [3 x %"struct.DomainMap,int>"], [3 x %"struct.DomainMap,int>"] } + %"struct.GridLayoutView<3,3>" = type { %"struct.LayoutBaseView<3,3,GridLayoutViewData<3, 3> >" } + %"struct.GridLayoutViewData<3,3>" = type { %"struct.LayoutBaseViewData<3,3,GridLayout<3> >", %struct.RefCounted } + %"struct.GuardLayers<3>" = type { [3 x i32], [3 x i32] } + %"struct.INode<3>" = type { %"struct.Interval<3>", %struct.GlobalIDDataBase*, i32 } + %"struct.Interval<1>" = type { %"struct.Domain<1,DomainTraits > >" } + %"struct.Interval<3>" = type { %"struct.Domain<3,DomainTraits > >" } + %"struct.LayoutBase<3,GridLayoutData<3> >" = type { %"struct.RefCountedPtr >" } + %"struct.LayoutBaseData<3>" = type { i32, %"struct.Interval<3>", %"struct.Interval<3>", %"struct.std::vector, Interval<3> >*,std::allocator, Interval<3> >*> >", %"struct.std::vector, Interval<3> >*,std::allocator, Interval<3> >*> >", %"struct.std::vector, Interval<3> >*,std::allocator, Interval<3> >*> >", i8, i8, %"struct.GuardLayers<3>", %"struct.GuardLayers<3>", %"struct.std::vector::GCFillInfo,std::allocator::GCFillInfo> >", [3 x i32], [3 x i32], %"struct.Loc<3>" } + %"struct.LayoutBaseData<3>::GCFillInfo" = type { %"struct.Interval<3>", i32, i32, i32 } + %"struct.LayoutBaseView<3,3,GridLayoutViewData<3, 3> >" = type { %"struct.RefCountedPtr >" } + %"struct.LayoutBaseViewData<3,3,GridLayout<3> >" = type { i32, %"struct.GridLayout<3>", %"struct.GuardLayers<3>", %"struct.GuardLayers<3>", %"struct.ViewIndexer<3,3>", %"struct.std::vector, Interval<3> >*,std::allocator, Interval<3> >*> >", %"struct.std::vector, Interval<3> >*,std::allocator, Interval<3> >*> >", %"struct.std::vector, Interval<3> >*,std::allocator, Interval<3> >*> >", i8 } + %"struct.Loc<1>" = type { %"struct.Domain<1,DomainTraits > >" } + %"struct.Loc<3>" = type { %"struct.Domain<3,DomainTraits > >" } + %"struct.MultiArg6 >, double, MultiPatch > >,Field >, double, MultiPatch > >,Field >, double, MultiPatch > >,Field >, double, MultiPatch > >,Field >, double, ConstantFunction>,Field >, Zero, ConstantFunction> >" = type { %"struct.Field >,double,MultiPatch > >", %! "struct.Field >,double,MultiPatch > >", %"struct.Field >,double,MultiPatch > >", %"struct.Field >,double,MultiPatch > >", %"struct.Field >,double,ConstantFunction>", %"struct.Field >,Zero,ConstantFunction>" } + %"struct.NoMeshData<3>" = type { %struct.RefCounted, %"struct.Interval<3>", %"struct.Interval<3>", %"struct.Interval<3>", %"struct.Interval<3>" } + %"struct.Node,Interval<3> >" = type { %"struct.Interval<3>", %"struct.Interval<3>", i32, i32, i32, i32 } + %"struct.Observable >" = type { %"struct.GridLayout<3>"*, %"struct.std::vector >*,std::allocator >*> >", i32, %"struct.Adv5::Ekin<3>" } + %"struct.Pooma::BrickBase<3>" = type { %"struct.DomainLayout<3>", [3 x i32], [3 x i32], i32, i8 } + %"struct.Pooma::BrickViewBase<3>" = type { %"struct.Interval<3>", [3 x i32], [3 x i32], i32, i8 } + %"struct.Range<1>" = type { %"struct.Domain<1,DomainTraits > >" } + %"struct.Range<3>" = type { %"struct.Domain<3,DomainTraits > >" } + %"struct.RefBlockController > >" = type { %struct.RefCounted, %"struct.Engine<3,double,Remote >"*, %"struct.Engine<3,double,Remote >"*, %"struct.Engine<3,double,Remote >"*, i8 } + %"struct.RefBlockController, ConstantFunction> >" = type { %struct.RefCounted, %"struct.FieldEngineBaseData<3,Zero,ConstantFunction>"*, %"struct.FieldEngineBaseData<3,Zero,ConstantFunction>"*, %"struct.FieldEngineBaseData<3,Zero,ConstantFunction>"*, i8 } + %"struct.RefBlockController >" = type { %struct.RefCounted, %"struct.FieldEngineBaseData<3,double,ConstantFunction>"*, %"struct.FieldEngineBaseData<3,double,ConstantFunction>"*, %"struct.FieldEngineBaseData<3,double,ConstantFunction>"*, i8 } + %"struct.RefBlockController > > >" = type { %struct.RefCounted, %"struct.FieldEngineBaseData<3,double,MultiPatch > >"*, %"struct.FieldEngineBaseData<3,double,MultiPatch > >"*, %"struct.FieldEngineBaseData<3,double,MultiPatch > >"*, i8 } + %"struct.RefBlockController, 3> > >" = type { %struct.RefCounted, %"struct.FieldEngineBaseData<3,double,MultiPatchView, 3> >"*, %"struct.FieldEngineBaseData<3,double,MultiPatchView, 3> >"*, %"struct.FieldEngineBaseData<3,double,MultiPatchView, 3> >"*, i8 } + %"struct.RefBlockController > >" = type { %struct.RefCounted, %"struct.FieldEngineBaseData<3,double,Remote >"*, %"struct.FieldEngineBaseData<3,double,Remote >"*, %"struct.FieldEngineBaseData<3,double,Remote >"*, i8 } + %"struct.RefBlockController" = type { %struct.RefCounted, double*, double*, double*, i8 } + %struct.RefCounted = type { i32, %"struct.Adv5::Ekin<3>" } + %"struct.RefCountedBlockPtr >,false,RefBlockController > > >" = type { i32, %"struct.RefCountedPtr > > >" } + %"struct.RefCountedBlockPtr, ConstantFunction>,false,RefBlockController, ConstantFunction> > >" = type { i32, %"struct.RefCountedPtr, ConstantFunction> > >" } + %"struct.RefCountedBlockPtr,false,RefBlockController > >" = type { i32, %"struct.RefCountedPtr > >" } + %"struct.RefCountedBlockPtr > >,false,RefBlockController > > > >" = type { i32, %"struct.RefCountedPtr > > > >" } + %"struct.RefCountedBlockPtr, 3> >,false,RefBlockController, 3> > > >" = type { i32, %"struct.RefCountedPtr, 3> > > >" } + %"struct.RefCountedBlockPtr >,false,RefBlockController > > >" = type { i32, %"struct.RefCountedPtr > > >" } + %"struct.RefCountedBlockPtr >" = type { i32, %"struct.RefCountedPtr >" } + %"struct.RefCountedPtr >" = type { %"struct.DataBlockController"* } + %"struct.RefCountedPtr >" = type { %"struct.GridLayoutData<3>"* } + %"struct.RefCountedPtr >" = type { %"struct.GridLayoutViewData<3,3>"* } + %"struct.RefCountedPtr > > >" = type { %"struct.RefBlockController > >"* } + %"struct.RefCountedPtr, ConstantFunction> > >" = type { %"struct.RefBlockController, ConstantFunction> >"* } + %"struct.RefCountedPtr > >" = type { %"struct.RefBlockController >"* } + %"struct.RefCountedPtr > > > >" = type { %"struct.RefBlockController > > >"* } + %"struct.RefCountedPtr, 3> > > >" = type { %"struct.RefBlockController, 3> > >"* } + %"struct.RefCountedPtr > > >" = type { %"struct.RefBlockController > >"* } + %"struct.RefCountedPtr" = type { %struct.RelationListData* } + %"struct.RefCountedPtr > >" = type { %"struct.Shared >"* } + %"struct.RefCountedPtr > >" = type { %"struct.Shared >"* } + %"struct.RefCountedPtr > >" = type { %"struct.UniformRectilinearMeshData >"* } + %struct.RelationList = type { %"struct.RefCountedPtr" } + %struct.RelationListData = type { %struct.RefCounted, %"struct.std::vector >" } + %struct.RelationListItem = type { i32 (...)**, i32, i32, i8 } + %"struct.Shared >" = type { %struct.RefCounted, %"struct.Engine<3,double,Brick>" } + %"struct.Shared >" = type { %struct.RefCounted, %"struct.Engine<3,double,BrickView>" } + %"struct.SingleObservable" = type { %"struct.ContextMapper<1>"* } + %"struct.UniformRectilinearMesh >" = type { %"struct.RefCountedPtr > >" } + %"struct.UniformRectilinearMeshData >" = type { %"struct.NoMeshData<3>", %"struct.Vector<3,double,Full>", %"struct.Vector<3,double,Full>" } + %"struct.Vector<3,double,Full>" = type { %"struct.VectorEngine<3,double,Full>" } + %"struct.VectorEngine<3,double,Full>" = type { [3 x double] } + %"struct.ViewIndexer<3,3>" = type { %"struct.Interval<3>", %"struct.Range<3>", [3 x i32], [3 x i32], %"struct.Loc<3>" } + %"struct.WrapNoInit >" = type { %"struct.Interval<1>" } + %"struct.WrapNoInit >" = type { %"struct.Loc<1>" } + %"struct.WrapNoInit >" = type { %"struct.Range<1>" } + %"struct.std::_List_base,std::allocator > >" = type { %"struct.std::_List_base,std::allocator > >::_List_impl" } + %"struct.std::_List_base,std::allocator > >::_List_impl" = type { %"struct.std::_List_node_base" } + %"struct.std::_List_const_iterator >" = type { %"struct.std::_List_node_base"* } + %"struct.std::_List_node_base" = type { %"struct.std::_List_node_base"*, %"struct.std::_List_node_base"* } + %"struct.std::_Rb_tree,std::_Select1st >,std::less,std::allocator > >" = type { %"struct.std::_Rb_tree,std::_Select1st >,std::less,std::allocator > >::_Rb_tree_impl,false>" } + %"struct.std::_Rb_tree,std::_Select1st >,std::less,std::allocator > >::_Rb_tree_impl,false>" = type { %"struct.Adv5::Ekin<3>", %"struct.std::_Rb_tree_node_base", i32 } + %"struct.std::_Rb_tree_node_base" = type { i32, %"struct.std::_Rb_tree_node_base"*, %"struct.std::_Rb_tree_node_base"*, %"struct.std::_Rb_tree_node_base"* } + %"struct.std::_Vector_base >" = type { %"struct.std::_Vector_base >::_Vector_impl" } + %"struct.std::_Vector_base >::_Vector_impl" = type { %"struct.GlobalIDDataBase::Pack"*, %"struct.GlobalIDDataBase::Pack"*, %"struct.GlobalIDDataBase::Pack"* } + %"struct.std::_Vector_base::GCFillInfo,std::allocator::GCFillInfo> >" = type { %"struct.std::_Vector_base::GCFillInfo,std::allocator::GCFillInfo> >::_Vector_impl" } + %"struct.std::_Vector_base::GCFillInfo,std::allocator::GCFillInfo> >::_Vector_impl" = type { %"struct.LayoutBaseData<3>::GCFillInfo"*, %"struct.LayoutBaseData<3>::GCFillInfo"*, %"struct.LayoutBaseData<3>::GCFillInfo"* } + %"struct.std::_Vector_base,std::allocator > >" = type { %"struct.std::_Vector_base,std::allocator > >::_Vector_impl" } + %"struct.std::_Vector_base,std::allocator > >::_Vector_impl" = type { %"struct.Loc<3>"*, %"struct.Loc<3>"*, %"struct.Loc<3>"* } + %"struct.std::_Vector_base, Interval<3> >*,std::allocator, Interval<3> >*> >" = type { %"struct.std::_Vector_base, Interval<3> >*,std::allocator, Interval<3> >*> >::_Vector_impl" } + %"struct.std::_Vector_base, Interval<3> >*,std::allocator, Interval<3> >*> >::_Vector_impl" = type { %"struct.Node,Interval<3> >"**, %"struct.Node,Interval<3> >"**, %"struct.Node,Interval<3> >"** } + %"struct.std::_Vector_base >*,std::allocator >*> >" = type { %"struct.std::_Vector_base >*,std::allocator >*> >::_Vector_impl" } + %"struct.std::_Vector_base >*,std::allocator >*> >::_Vector_impl" = type { %"struct.ContextMapper<1>"**, %"struct.ContextMapper<1>"**, %"struct.ContextMapper<1>"** } + %"struct.std::_Vector_base >" = type { %"struct.std::_Vector_base >::_Vector_impl" } + %"struct.std::_Vector_base >::_Vector_impl" = type { %struct.RelationListItem**, %struct.RelationListItem**, %struct.RelationListItem** } + %"struct.std::_Vector_base,std::allocator > >" = type { %"struct.std::_Vector_base,std::allocator > >::_Vector_impl" } + %"struct.std::_Vector_base,std::allocator > >::_Vector_impl" = type { %"struct.Vector<3,double,Full>"*, %"struct.Vector<3,double,Full>"*, %"struct.Vector<3,double,Full>"* } + %"struct.std::list,std::allocator > >" = type { %"struct.std::_List_base,std::allocator > >" } + %"struct.std::map,std::allocator > >" = type { %"struct.std::_Rb_tree,std::_Select1st >,std::less,std::allocator > >" } + %"struct.std::vector >" = type { %"struct.std::_Vector_base >" } + %"struct.std::vector::GCFillInfo,std::allocator::GCFillInfo> >" = type { %"struct.std::_Vector_base::GCFillInfo,std::allocator::GCFillInfo> >" } + %"struct.std::vector,std::allocator > >" = type { %"struct.std::_Vector_base,std::allocator > >" } + %"struct.std::vector, Interval<3> >*,std::allocator, Interval<3> >*> >" = type { %"struct.std::_Vector_base, Interval<3> >*,std::allocator, Interval<3> >*> >" } + %"struct.std::vector >*,std::allocator >*> >" = type { %"struct.std::_Vector_base >*,std::allocator >*> >" } + %"struct.std::vector >" = type { %"struct.std::_Vector_base >" } + %"struct.std::vector,std::allocator > >" = type { %"struct.std::_Vector_base,std::allocator > >" } + +declare void @llvm.memcpy.i32(i8*, i8*, i32, i32) nounwind + +declare fastcc void @_ZN11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd10MultiPatchI7GridTag6RemoteI5BrickEEEC1ERKSC_(%"struct.FieldEngine >,double,MultiPatch > >"*, %"struct.FieldEngine >,double,MultiPatch > >"*) nounwind + +declare fastcc void @_ZN9CenteringILi3EEC1ERKS0_i(%"struct.Centering<3>"*, %"struct.Centering<3>"*, i32) nounwind + +declare fastcc void @_ZN11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd6RemoteI9BrickViewEED1Ev(%"struct.FieldEngine >,double,Remote >"*) nounwind + +declare fastcc void @_ZN11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd6RemoteI9BrickViewEEC1Id14MultiPatchViewI7GridTagS6_I5BrickELi3EEEERKS_IS5_T_T0_ERK5INodeILi3EE(%"struct.FieldEngine >,double,Remote >"*, %"struct.FieldEngine >,double,MultiPatchView, 3> >"*, %"struct.INode<3>"*) nounwind + +declare fastcc void @_ZN11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd14MultiPatchViewI7GridTag6RemoteI5BrickELi3EEED1Ev(%"struct.FieldEngine >,double,MultiPatchView, 3> >"*) nounwind + +declare fastcc void @_ZN11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd14MultiPatchViewI7GridTag6RemoteI5BrickELi3EEEC1Id10MultiPatchIS7_SA_EEERKS_IS5_T_T0_ERK8IntervalILi3EE(%"struct.FieldEngine >,double,MultiPatchView, 3> >"*, %"struct.FieldEngine >,double,MultiPatch > >"*, %"struct.Interval<3>"*) nounwind + +define fastcc void @t(double %dt, %"struct.Field >,double,MultiPatch > >"* %rh, %"struct.Field >,double,MultiPatch > >"* %T, %"struct.Field >,double,MultiPatch > >"* %v, %"struct.Field >,double,MultiPatch > >"* %pg, %"struct.Field >,double,MultiPatch > >"* %ph, %"struct.Field >,double,MultiPatch > >"* %cs, %"struct.Field >,double,ConstantFunction>"* %cv, %"struct.Field >,Zero,ConstantFunction>"* %dlmdlt, %"struct.Field >,double,ConstantFunction>"* %xmue, %"struct.Field >,double,MultiPatch > >"* %vint, %"struct.Field >,double,MultiPatch > >"* %cent, %"struct.Field >,double,MultiPatch > >"* %fvis, double %c_nr, double %c_av, i8 zeroext %cartvis_f) nounwind { +entry: + %0 = alloca %"struct.Field >,double,ExpressionTag, BinaryNode >, double, Remote >, Field >, double, Remote > > > > >" ; <%"struct.Field >,double,ExpressionTag, BinaryNode >, double, Remote >, Field >, double, Remote > > > > >"*> [#uses=4] + %s.i.i.i.i.i = alloca %"struct.Interval<3>" ; <%"struct.Interval<3>"*> [#uses=0] + %1 = alloca %"struct.BinaryNode,BinaryNode >, double, MultiPatchView, 3> >, Field >, double, MultiPatchView, 3> > > >" ; <%"struct.BinaryNode,BinaryNode >, double, MultiPatchView, 3> >, Field >, double, MultiPatchView, 3> > > >"*> [#uses=2] + %multiArg.i = alloca %"struct.MultiArg6 >, double, MultiPatch > >,Field >, double, MultiPatch > >,Field >, double, MultiPatch > >,Field >, double, MultiPatch > >,Field >, double, ConstantFunction>,Field >, Zero, ConstantFunction> >" ; <%"struct.MultiArg6 >, double, MultiPatch > >,Field >, double, MultiPatch > >,Field >, double, MultiPatch > >,Field >, double, MultiPatch > >,Field >, double, ConstantFunction>,Field >, Zero, ConstantFunction> >"*> [#uses=0] + %2 = alloca %"struct.Field >,double,MultiPatch > >" ; <%"struct.Field >,double,MultiPatch > >"*> [#uses=6] + %3 = alloca %"struct.Field >,double,MultiPatch > >" ; <%"struct.Field >,double,MultiPatch > >"*> [#uses=2] + %4 = alloca %"struct.Field >,double,MultiPatchView, 3> >" ; <%"struct.Field >,double,MultiPatchView, 3> >"*> [#uses=0] + %5 = alloca %"struct.Field >,double,MultiPatch > >" ; <%"struct.Field >,double,MultiPatch > >"*> [#uses=2] + %6 = alloca %"struct.Field >,double,MultiPatchView, 3> >" ; <%"struct.Field >,double,MultiPatchView, 3> >"*> [#uses=0] + %7 = alloca %"struct.Field >,double,MultiPatch > >" ; <%"struct.Field >,double,MultiPatch > >"*> [#uses=0] + %8 = alloca %"struct.Field >,double,MultiPatch > >" ; <%"struct.Field >,double,MultiPatch > >"*> [#uses=0] + %9 = alloca %"struct.Field >,double,MultiPatch > >" ; <%"struct.Field >,double,MultiPatch > >"*> [#uses=0] + %10 = alloca %"struct.Field >,double,MultiPatch > >" ; <%"struct.Field >,double,MultiPatch > >"*> [#uses=0] + %11 = alloca %"struct.Field >,double,MultiPatch > >" ; <%"struct.Field >,double,MultiPatch > >"*> [#uses=0] + %12 = alloca %"struct.Field >,double,MultiPatch > >" ; <%"struct.Field >,double,MultiPatch > >"*> [#uses=0] + %13 = alloca %"struct.Field >,double,MultiPatch > >" ; <%"struct.Field >,double,MultiPatch > >"*> [#uses=0] + %14 = alloca %"struct.Field >,double,MultiPatch > >" ; <%"struct.Field >,double,MultiPatch > >"*> [#uses=0] + %15 = alloca %"struct.Field >,double,MultiPatch > >" ; <%"struct.Field >,double,MultiPatch > >"*> [#uses=0] + %16 = alloca %"struct.Field >,double,MultiPatch > >" ; <%"struct.Field >,double,MultiPatch > >"*> [#uses=0] + %17 = alloca %"struct.Interval<3>" ; <%"struct.Interval<3>"*> [#uses=0] + %18 = alloca %"struct.Field >,double,MultiPatch > >" ; <%"struct.Field >,double,MultiPatch > >"*> [#uses=0] + %19 = alloca double ; [#uses=0] + %20 = alloca %"struct.Field >,double,MultiPatchView, 3> >" ; <%"struct.Field >,double,MultiPatchView, 3> >"*> [#uses=0] + %21 = alloca %"struct.Interval<3>" ; <%"struct.Interval<3>"*> [#uses=0] + %22 = alloca %"struct.Field >,double,MultiPatchView, 3> >" ; <%"struct.Field >,double,MultiPatchView, 3> >"*> [#uses=0] + %23 = alloca %"struct.Field >,double,MultiPatchView, 3> >" ; <%"struct.Field >,double,MultiPatchView, 3> >"*> [#uses=0] + %24 = alloca %"struct.Interval<3>" ; <%"struct.Interval<3>"*> [#uses=0] + %25 = alloca %"struct.Field >,double,MultiPatch > >" ; <%"struct.Field >,double,MultiPatch > >"*> [#uses=0] + %26 = alloca %"struct.Field >,double,MultiPatch > >" ; <%"struct.Field >,double,MultiPatch > >"*> [#uses=0] + %27 = alloca %"struct.Field >,double,MultiPatch > >" ; <%"struct.Field >,double,MultiPatch > >"*> [#uses=0] + %28 = alloca %"struct.Field >,double,MultiPatch > >" ; <%"struct.Field >,double,MultiPatch > >"*> [#uses=0] + %29 = alloca %"struct.Interval<3>" ; <%"struct.Interval<3>"*> [#uses=0] + %30 = alloca %"struct.Field >,double,MultiPatch > >" ; <%"struct.Field >,double,MultiPatch > >"*> [#uses=0] + %31 = alloca %"struct.Field >,double,MultiPatch > >" ; <%"struct.Field >,double,MultiPatch > >"*> [#uses=0] + %32 = alloca %"struct.Field >,double,MultiPatch > >" ; <%"struct.Field >,double,MultiPatch > >"*> [#uses=0] + %33 = alloca %"struct.Field >,double,MultiPatch > >" ; <%"struct.Field >,double,MultiPatch > >"*> [#uses=0] + %34 = alloca %"struct.Field >,double,MultiPatch > >" ; <%"struct.Field >,double,MultiPatch > >"*> [#uses=0] + %35 = alloca %"struct.Interval<3>" ; <%"struct.Interval<3>"*> [#uses=0] + %36 = alloca %"struct.Field >,double,MultiPatch > >" ; <%"struct.Field >,double,MultiPatch > >"*> [#uses=0] + %37 = getelementptr %"struct.Field >,double,MultiPatch > >"* %v, i32 0, i32 0, i32 5 ; <%"struct.GuardLayers<3>"*> [#uses=1] + %38 = bitcast %"struct.GuardLayers<3>"* %37 to i8* ; [#uses=1] + br label %bb.i.i.i.i.i + +bb.i.i.i.i.i: ; preds = %bb.i.i.i.i.i, %entry + %39 = icmp eq i32* null, null ; [#uses=1] + br i1 %39, label %_ZN14ScalarCodeInfoILi3ELi4EEC1Ev.exit.i, label %bb.i.i.i.i.i + +_ZN14ScalarCodeInfoILi3ELi4EEC1Ev.exit.i: ; preds = %bb.i.i.i.i.i + br label %bb.i.i.i35.i.i34 + +bb.i.i.i35.i.i34: ; preds = %bb.i.i.i35.i.i34, %_ZN14ScalarCodeInfoILi3ELi4EEC1Ev.exit.i + %40 = icmp eq i32* null, null ; [#uses=1] + br i1 %40, label %_ZNSt6vectorIbSaIbEEC1EmRKbRKS0_.exit36.i.i37, label %bb.i.i.i35.i.i34 + +_ZNSt6vectorIbSaIbEEC1EmRKbRKS0_.exit36.i.i37: ; preds = %bb.i.i.i35.i.i34 + br label %bb.i.i.i19.i.i47 + +bb.i.i.i19.i.i47: ; preds = %bb.i.i.i19.i.i47, %_ZNSt6vectorIbSaIbEEC1EmRKbRKS0_.exit36.i.i37 + %41 = icmp eq i32* null, null ; [#uses=1] + br i1 %41, label %_ZNSt6vectorIbSaIbEEC1EmRKbRKS0_.exit20.i.i50, label %bb.i.i.i19.i.i47 + +_ZNSt6vectorIbSaIbEEC1EmRKbRKS0_.exit20.i.i50: ; preds = %bb.i.i.i19.i.i47 + %42 = getelementptr %"struct.Field >,double,MultiPatch > >"* %rh, i32 0, i32 0 ; <%"struct.FieldEngine >,double,MultiPatch > >"*> [#uses=1] + br label %bb.i.i.i19.i.i.i + +bb.i.i.i19.i.i.i: ; preds = %bb.i.i.i19.i.i.i, %_ZNSt6vectorIbSaIbEEC1EmRKbRKS0_.exit20.i.i50 + %43 = icmp eq i32* null, null ; [#uses=1] + br i1 %43, label %_ZNSt6vectorIbSaIbEEC1EmRKbRKS0_.exit20.i.i.i, label %bb.i.i.i19.i.i.i + +_ZNSt6vectorIbSaIbEEC1EmRKbRKS0_.exit20.i.i.i: ; preds = %bb.i.i.i19.i.i.i + br label %bb.i.i.i35.i.i433 + +bb.i.i.i35.i.i433: ; preds = %bb.i.i.i35.i.i433, %_ZNSt6vectorIbSaIbEEC1EmRKbRKS0_.exit20.i.i.i + %44 = icmp eq i32* null, null ; [#uses=1] + br i1 %44, label %_ZNSt6vectorIbSaIbEEC1EmRKbRKS0_.exit36.i.i436, label %bb.i.i.i35.i.i433 + +_ZNSt6vectorIbSaIbEEC1EmRKbRKS0_.exit36.i.i436: ; preds = %bb.i.i.i35.i.i433 + br label %bb.i.i.i19.i.i446 + +bb.i.i.i19.i.i446: ; preds = %bb.i.i.i19.i.i446, %_ZNSt6vectorIbSaIbEEC1EmRKbRKS0_.exit36.i.i436 + %45 = icmp eq i32* null, null ; [#uses=1] + br i1 %45, label %_ZNSt6vectorIbSaIbEEC1EmRKbRKS0_.exit20.i.i449, label %bb.i.i.i19.i.i446 + +_ZNSt6vectorIbSaIbEEC1EmRKbRKS0_.exit20.i.i449: ; preds = %bb.i.i.i19.i.i446 + br label %bb.i.i.i.i.i459 + +bb.i.i.i.i.i459: ; preds = %bb.i.i.i.i.i459, %_ZNSt6vectorIbSaIbEEC1EmRKbRKS0_.exit20.i.i449 + %46 = icmp eq i32* null, null ; [#uses=1] + br i1 %46, label %_ZN14ScalarCodeInfoILi3ELi6EEC1Ev.exit.i460, label %bb.i.i.i.i.i459 + +_ZN14ScalarCodeInfoILi3ELi6EEC1Ev.exit.i460: ; preds = %bb.i.i.i.i.i459 + %47 = getelementptr %"struct.Field >,double,MultiPatch > >"* %5, i32 0, i32 0, i32 1 ; <%"struct.Centering<3>"*> [#uses=1] + %48 = getelementptr %"struct.Field >,double,MultiPatch > >"* %vint, i32 0, i32 0, i32 1 ; <%"struct.Centering<3>"*> [#uses=2] + %49 = getelementptr %"struct.Field >,double,MultiPatch > >"* %5, i32 0, i32 0, i32 5 ; <%"struct.GuardLayers<3>"*> [#uses=1] + %50 = bitcast %"struct.GuardLayers<3>"* %49 to i8* ; [#uses=1] + %51 = bitcast %"struct.GuardLayers<3>"* null to i8* ; [#uses=2] + %52 = getelementptr %"struct.Field >,double,MultiPatch > >"* %3, i32 0, i32 0, i32 1 ; <%"struct.Centering<3>"*> [#uses=1] + %53 = getelementptr %"struct.Field >,double,MultiPatch > >"* %3, i32 0, i32 0, i32 5 ; <%"struct.GuardLayers<3>"*> [#uses=1] + %54 = bitcast %"struct.GuardLayers<3>"* %53 to i8* ; [#uses=1] + %55 = getelementptr %"struct.Field >,double,MultiPatch > >"* %2, i32 0, i32 0, i32 1 ; <%"struct.Centering<3>"*> [#uses=1] + %56 = getelementptr %"struct.Field >,double,MultiPatch > >"* %2, i32 0, i32 0, i32 4, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 1 ; [#uses=1] + %57 = getelementptr %"struct.Field >,double,MultiPatch > >"* %2, i32 0, i32 0, i32 4, i32 0, i32 0, i32 0, i32 1, i32 0, i32 0, i32 0, i32 0, i32 1 ; [#uses=1] + %58 = getelementptr %"struct.Field >,double,MultiPatch > >"* %2, i32 0, i32 0, i32 4, i32 0, i32 0, i32 0, i32 2, i32 0, i32 0, i32 0, i32 0, i32 0 ; [#uses=1] + %59 = getelementptr %"struct.Field >,double,MultiPatch > >"* %2, i32 0, i32 0, i32 4, i32 0, i32 0, i32 0, i32 2, i32 0, i32 0, i32 0, i32 0, i32 1 ; [#uses=1] + %60 = getelementptr %"struct.Field >,double,MultiPatch > >"* %2, i32 0, i32 0, i32 5 ; <%"struct.GuardLayers<3>"*> [#uses=1] + %61 = bitcast %"struct.GuardLayers<3>"* %60 to i8* ; [#uses=1] + %62 = getelementptr %"struct.BinaryNode,BinaryNode >, double, MultiPatchView, 3> >, Field >, double, MultiPatchView, 3> > > >"* %1, i32 0, i32 1, i32 0, i32 0 ; <%"struct.FieldEngine >,double,MultiPatchView, 3> >"*> [#uses=1] + %63 = getelementptr %"struct.BinaryNode,BinaryNode >, double, MultiPatchView, 3> >, Field >, double, MultiPatchView, 3> > > >"* %1, i32 0, i32 1, i32 1, i32 0 ; <%"struct.FieldEngine >,double,MultiPatchView, 3> >"*> [#uses=1] + %64 = getelementptr %"struct.Field >,double,ExpressionTag, BinaryNode >, double, MultiPatchView, 3> >, Field >, double, MultiPatchView, 3> > > > > >"* null, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0 ; [#uses=1] + %65 = getelementptr %"struct.Field >,double,ExpressionTag, BinaryNode >, double, Remote >, Field >, double, Remote > > > > >"* %0, i32 0, i32 0, i32 0, i32 0, i32 1, i32 1, i32 0 ; <%"struct.FieldEngine >,double,Remote >"*> [#uses=2] + %66 = getelementptr %"struct.Field >,double,ExpressionTag, BinaryNode >, double, Remote >, Field >, double, Remote > > > > >"* %0, i32 0, i32 0, i32 0, i32 0, i32 1, i32 0, i32 0, i32 4, i32 0, i32 0, i32 0, i32 1, i32 0, i32 0, i32 0, i32 0, i32 0 ; [#uses=1] + %67 = getelementptr %"struct.Field >,double,ExpressionTag, BinaryNode >, double, Remote >, Field >, double, Remote > > > > >"* %0, i32 0, i32 0, i32 0, i32 0, i32 1, i32 0, i32 0, i32 4, i32 0, i32 0, i32 0, i32 1, i32 0, i32 0, i32 0, i32 0, i32 1 ; [#uses=1] + %68 = getelementptr %"struct.Field >,double,ExpressionTag, BinaryNode >, double, Remote >, Field >, double, Remote > > > > >"* %0, i32 0, i32 0, i32 0, i32 0, i32 1, i32 0, i32 0, i32 4, i32 0, i32 0, i32 0, i32 2, i32 0, i32 0, i32 0, i32 0, i32 1 ; [#uses=1] + br label %bb15 + +bb15: ; preds = %_Z6assignI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd14MultiPatchViewI7GridTag6RemoteI5BrickELi3EES5_d13ExpressionTagI10BinaryNodeI10OpMultiply6ScalarIdESD_I5OpAdd9ReferenceI5FieldIS5_dSB_EESL_EEE8OpAssignERKSJ_IT_T0_T1_ESV_RKSJ_IT2_T3_T4_ERKT5_.exit, %_ZN14ScalarCodeInfoILi3ELi6EEC1Ev.exit.i460 + %i.0.reg2mem.0 = phi i32 [ 0, %_ZN14ScalarCodeInfoILi3ELi6EEC1Ev.exit.i460 ], [ %indvar.next, %_Z6assignI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd14MultiPatchViewI7GridTag6RemoteI5BrickELi3EES5_d13ExpressionTagI10BinaryNodeI10OpMultiply6ScalarIdESD_I5OpAdd9ReferenceI5FieldIS5_dSB_EESL_EEE8OpAssignERKSJ_IT_T0_T1_ESV_RKSJ_IT2_T3_T4_ERKT5_.exit ] ; [#uses=4] + call fastcc void @_ZN9CenteringILi3EEC1ERKS0_i(%"struct.Centering<3>"* %47, %"struct.Centering<3>"* %48, i32 %i.0.reg2mem.0) nounwind + call void @llvm.memcpy.i32(i8* %50, i8* %51, i32 24, i32 4) nounwind + call fastcc void @_ZN9CenteringILi3EEC1ERKS0_i(%"struct.Centering<3>"* %52, %"struct.Centering<3>"* %48, i32 %i.0.reg2mem.0) nounwind + call void @llvm.memcpy.i32(i8* %54, i8* %51, i32 24, i32 4) nounwind + br i1 false, label %bb.i940, label %bb4.i943 + +bb.i940: ; preds = %bb15 + br label %_ZNK11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd10MultiPatchI7GridTag6RemoteI5BrickEEE11totalDomainEv.exit944 + +bb4.i943: ; preds = %bb15 + br label %_ZNK11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd10MultiPatchI7GridTag6RemoteI5BrickEEE11totalDomainEv.exit944 + +_ZNK11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd10MultiPatchI7GridTag6RemoteI5BrickEEE11totalDomainEv.exit944: ; preds = %bb4.i943, %bb.i940 + call fastcc void @_ZN11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd14MultiPatchViewI7GridTag6RemoteI5BrickELi3EEEC1Id10MultiPatchIS7_SA_EEERKS_IS5_T_T0_ERK8IntervalILi3EE(%"struct.FieldEngine >,double,MultiPatchView, 3> >"* null, %"struct.FieldEngine >,double,MultiPatch > >"* null, %"struct.Interval<3>"* null) nounwind + call fastcc void @_ZN9CenteringILi3EEC1ERKS0_i(%"struct.Centering<3>"* %55, %"struct.Centering<3>"* null, i32 %i.0.reg2mem.0) nounwind + call void @llvm.memcpy.i32(i8* %61, i8* %38, i32 24, i32 4) nounwind + %69 = load %"struct.Loc<3>"** null, align 4 ; <%"struct.Loc<3>"*> [#uses=1] + %70 = ptrtoint %"struct.Loc<3>"* %69 to i32 ; [#uses=1] + %.off.i911 = sub i32 0, %70 ; [#uses=1] + %71 = icmp ult i32 %.off.i911, 12 ; [#uses=1] + %72 = sub i32 0, 0 ; [#uses=2] + %73 = load i32* %56, align 4 ; [#uses=1] + %74 = add i32 %73, 0 ; [#uses=1] + %75 = sub i32 %74, %72 ; [#uses=1] + %76 = add i32 %75, 0 ; [#uses=1] + %77 = load i32* null, align 8 ; [#uses=2] + %78 = load i32* null, align 4 ; [#uses=1] + %79 = sub i32 %77, %78 ; [#uses=1] + %80 = load i32* %57, align 4 ; [#uses=1] + %81 = load i32* null, align 4 ; [#uses=1] + br i1 %71, label %bb.i912, label %bb4.i915 + +bb.i912: ; preds = %_ZNK11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd10MultiPatchI7GridTag6RemoteI5BrickEEE11totalDomainEv.exit944 + br label %_ZNK11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd10MultiPatchI7GridTag6RemoteI5BrickEEE11totalDomainEv.exit916 + +bb4.i915: ; preds = %_ZNK11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd10MultiPatchI7GridTag6RemoteI5BrickEEE11totalDomainEv.exit944 + %82 = sub i32 %77, %79 ; [#uses=1] + %83 = add i32 %82, %80 ; [#uses=1] + %84 = add i32 %83, %81 ; [#uses=1] + %85 = load i32* %58, align 8 ; [#uses=2] + %86 = load i32* null, align 8 ; [#uses=1] + %87 = sub i32 %85, %86 ; [#uses=2] + %88 = load i32* %59, align 4 ; [#uses=1] + %89 = load i32* null, align 4 ; [#uses=1] + %90 = sub i32 %85, %87 ; [#uses=1] + %91 = add i32 %90, %88 ; [#uses=1] + %92 = add i32 %91, %89 ; [#uses=1] + br label %_ZNK11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd10MultiPatchI7GridTag6RemoteI5BrickEEE11totalDomainEv.exit916 + +_ZNK11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd10MultiPatchI7GridTag6RemoteI5BrickEEE11totalDomainEv.exit916: ; preds = %bb4.i915, %bb.i912 + %.0978.0.0.1.0.0.0.0.1.0 = phi i32 [ %84, %bb4.i915 ], [ 0, %bb.i912 ] ; [#uses=0] + %.0978.0.0.2.0.0.0.0.0.0 = phi i32 [ %87, %bb4.i915 ], [ 0, %bb.i912 ] ; [#uses=1] + %.0978.0.0.2.0.0.0.0.1.0 = phi i32 [ %92, %bb4.i915 ], [ 0, %bb.i912 ] ; [#uses=0] + store i32 %72, i32* null, align 8 + store i32 %76, i32* null, align 4 + store i32 %.0978.0.0.2.0.0.0.0.0.0, i32* null, align 8 + call fastcc void @_ZN11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd14MultiPatchViewI7GridTag6RemoteI5BrickELi3EEEC1Id10MultiPatchIS7_SA_EEERKS_IS5_T_T0_ERK8IntervalILi3EE(%"struct.FieldEngine >,double,MultiPatchView, 3> >"* null, %"struct.FieldEngine >,double,MultiPatch > >"* null, %"struct.Interval<3>"* null) nounwind + %93 = load i32* null, align 8 ; [#uses=1] + %94 = icmp sgt i32 %93, 0 ; [#uses=1] + br i1 %94, label %bb1.i, label %_Z6assignI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd14MultiPatchViewI7GridTag6RemoteI5BrickELi3EES5_d13ExpressionTagI10BinaryNodeI10OpMultiply6ScalarIdESD_I5OpAdd9ReferenceI5FieldIS5_dSB_EESL_EEE8OpAssignERKSJ_IT_T0_T1_ESV_RKSJ_IT2_T3_T4_ERKT5_.exit + +bb1.i: ; preds = %bb3.i23.i.i, %_ZNK11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd10MultiPatchI7GridTag6RemoteI5BrickEEE11totalDomainEv.exit916 + call fastcc void @_ZN11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd14MultiPatchViewI7GridTag6RemoteI5BrickELi3EEED1Ev(%"struct.FieldEngine >,double,MultiPatchView, 3> >"* %63) nounwind + call fastcc void @_ZN11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd14MultiPatchViewI7GridTag6RemoteI5BrickELi3EEED1Ev(%"struct.FieldEngine >,double,MultiPatchView, 3> >"* %62) nounwind + br label %bb.i17.i14.i + +bb.i17.i14.i: ; preds = %_ZNK11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd6RemoteI9BrickViewEE14physicalDomainEv.exit26.i.i.i.i, %bb1.i + %i.0.02.rec.i.i.i = phi i32 [ %.rec.i.i.i641, %_ZNK11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd6RemoteI9BrickViewEE14physicalDomainEv.exit26.i.i.i.i ], [ 0, %bb1.i ] ; [#uses=1] + %95 = load double* %64, align 8 ; [#uses=1] + store double %95, double* null, align 8 + call fastcc void @_ZN11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd6RemoteI9BrickViewEEC1Id14MultiPatchViewI7GridTagS6_I5BrickELi3EEEERKS_IS5_T_T0_ERK5INodeILi3EE(%"struct.FieldEngine >,double,Remote >"* %65, %"struct.FieldEngine >,double,MultiPatchView, 3> >"* null, %"struct.INode<3>"* null) nounwind + %96 = load %"struct.Loc<3>"** null, align 4 ; <%"struct.Loc<3>"*> [#uses=1] + %97 = ptrtoint %"struct.Loc<3>"* %96 to i32 ; [#uses=1] + %.off.i21.i.i.i.i = sub i32 0, %97 ; [#uses=1] + %98 = icmp ult i32 %.off.i21.i.i.i.i, 12 ; [#uses=1] + br i1 %98, label %bb.i22.i.i.i.i, label %bb3.i25.i.i.i.i + +bb.i22.i.i.i.i: ; preds = %bb.i17.i14.i + %99 = load i32* null, align 4 ; [#uses=1] + %100 = icmp eq i32 %99, 1 ; [#uses=1] + %101 = load i32* null, align 4 ; [#uses=1] + br i1 %100, label %_ZNK11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd6RemoteI9BrickViewEE14physicalDomainEv.exit26.i.i.i.i, label %bb6.i.i24.i.i.i.i + +bb6.i.i24.i.i.i.i: ; preds = %bb.i22.i.i.i.i + br label %_ZNK11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd6RemoteI9BrickViewEE14physicalDomainEv.exit26.i.i.i.i + +bb3.i25.i.i.i.i: ; preds = %bb.i17.i14.i + %102 = load i32* %66, align 8 ; [#uses=2] + %103 = load i32* %67, align 4 ; [#uses=1] + %104 = load i32* %68, align 4 ; [#uses=1] + br label %_ZNK11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd6RemoteI9BrickViewEE14physicalDomainEv.exit26.i.i.i.i + +_ZNK11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd6RemoteI9BrickViewEE14physicalDomainEv.exit26.i.i.i.i: ; preds = %bb3.i25.i.i.i.i, %bb6.i.i24.i.i.i.i, %bb.i22.i.i.i.i + %.rle1279 = phi i32 [ 0, %bb3.i25.i.i.i.i ], [ 0, %bb6.i.i24.i.i.i.i ], [ 0, %bb.i22.i.i.i.i ] ; [#uses=1] + %.rle1277 = phi i32 [ %102, %bb3.i25.i.i.i.i ], [ 0, %bb6.i.i24.i.i.i.i ], [ 0, %bb.i22.i.i.i.i ] ; [#uses=1] + %.rle1275 = phi i32 [ 0, %bb3.i25.i.i.i.i ], [ 0, %bb6.i.i24.i.i.i.i ], [ 0, %bb.i22.i.i.i.i ] ; [#uses=1] + %.01034.0.0.2.0.0.0.0.1.0 = phi i32 [ %104, %bb3.i25.i.i.i.i ], [ 0, %bb6.i.i24.i.i.i.i ], [ 0, %bb.i22.i.i.i.i ] ; [#uses=1] + %.01034.0.0.2.0.0.0.0.0.0 = phi i32 [ 0, %bb3.i25.i.i.i.i ], [ 0, %bb6.i.i24.i.i.i.i ], [ 0, %bb.i22.i.i.i.i ] ; [#uses=1] + %.01034.0.0.1.0.0.0.0.1.0 = phi i32 [ %103, %bb3.i25.i.i.i.i ], [ 0, %bb6.i.i24.i.i.i.i ], [ 0, %bb.i22.i.i.i.i ] ; [#uses=1] + %.01034.0.0.1.0.0.0.0.0.0 = phi i32 [ %102, %bb3.i25.i.i.i.i ], [ 0, %bb6.i.i24.i.i.i.i ], [ 0, %bb.i22.i.i.i.i ] ; [#uses=1] + %.01034.0.0.0.0.0.0.0.1.0 = phi i32 [ 0, %bb3.i25.i.i.i.i ], [ 0, %bb6.i.i24.i.i.i.i ], [ %101, %bb.i22.i.i.i.i ] ; [#uses=1] + %.01034.0.0.0.0.0.0.0.0.0 = phi i32 [ 0, %bb3.i25.i.i.i.i ], [ 0, %bb6.i.i24.i.i.i.i ], [ 0, %bb.i22.i.i.i.i ] ; [#uses=1] + %105 = sub i32 %.01034.0.0.0.0.0.0.0.0.0, %.rle1275 ; [#uses=0] + %106 = sub i32 %.01034.0.0.1.0.0.0.0.0.0, %.rle1277 ; [#uses=0] + %107 = sub i32 %.01034.0.0.2.0.0.0.0.0.0, %.rle1279 ; [#uses=0] + store i32 %.01034.0.0.0.0.0.0.0.1.0, i32* null, align 4 + store i32 %.01034.0.0.1.0.0.0.0.1.0, i32* null, align 4 + store i32 %.01034.0.0.2.0.0.0.0.1.0, i32* null, align 4 + call fastcc void @_ZN11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd6RemoteI9BrickViewEED1Ev(%"struct.FieldEngine >,double,Remote >"* %65) nounwind + %.rec.i.i.i641 = add i32 %i.0.02.rec.i.i.i, 1 ; [#uses=1] + %108 = load %"struct.INode<3>"** null, align 4 ; <%"struct.INode<3>"*> [#uses=1] + %109 = icmp eq %"struct.INode<3>"* null, %108 ; [#uses=1] + br i1 %109, label %bb3.i23.i.i, label %bb.i17.i14.i + +bb3.i23.i.i: ; preds = %_ZNK11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd6RemoteI9BrickViewEE14physicalDomainEv.exit26.i.i.i.i + br label %bb1.i + +_Z6assignI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd14MultiPatchViewI7GridTag6RemoteI5BrickELi3EES5_d13ExpressionTagI10BinaryNodeI10OpMultiply6ScalarIdESD_I5OpAdd9ReferenceI5FieldIS5_dSB_EESL_EEE8OpAssignERKSJ_IT_T0_T1_ESV_RKSJ_IT2_T3_T4_ERKT5_.exit: ; preds = %_ZNK11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd10MultiPatchI7GridTag6RemoteI5BrickEEE11totalDomainEv.exit916 + %indvar.next = add i32 %i.0.reg2mem.0, 1 ; [#uses=2] + %exitcond = icmp eq i32 %indvar.next, 3 ; [#uses=1] + br i1 %exitcond, label %bb18, label %bb15 + +bb18: ; preds = %_Z6assignI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd14MultiPatchViewI7GridTag6RemoteI5BrickELi3EES5_d13ExpressionTagI10BinaryNodeI10OpMultiply6ScalarIdESD_I5OpAdd9ReferenceI5FieldIS5_dSB_EESL_EEE8OpAssignERKSJ_IT_T0_T1_ESV_RKSJ_IT2_T3_T4_ERKT5_.exit + call fastcc void @_ZN11FieldEngineI22UniformRectilinearMeshI10MeshTraitsILi3Ed21UniformRectilinearTag12CartesianTagLi3EEEd10MultiPatchI7GridTag6RemoteI5BrickEEEC1ERKSC_(%"struct.FieldEngine >,double,MultiPatch > >"* null, %"struct.FieldEngine >,double,MultiPatch > >"* %42) nounwind + unreachable +} From gohman at apple.com Wed Nov 19 20:45:51 2008 From: gohman at apple.com (Dan Gohman) Date: Thu, 20 Nov 2008 02:45:51 -0000 Subject: [llvm-commits] [llvm] r59698 - /llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Message-ID: <200811200245.mAK2jp52006591@zion.cs.uiuc.edu> Author: djg Date: Wed Nov 19 20:45:51 2008 New Revision: 59698 URL: http://llvm.org/viewvc/llvm-project?rev=59698&view=rev Log: Facter AddPseudoTwoAddrDeps and associated infrasructure out of the list-burr scheduler so that it can be used by the list-tdrr scheduler too. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp?rev=59698&r1=59697&r2=59698&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Wed Nov 19 20:45:51 2008 @@ -1111,7 +1111,6 @@ } } - /// ScheduleNodeTopDown - Add the node to the schedule. Decrement the pending /// count of its successors. If a successor pending count is zero, add it to /// the Available queue. @@ -1294,17 +1293,31 @@ PriorityQueue, SF> Queue; unsigned currentQueueId; + protected: + // SUnits - The SUnits for the current graph. + std::vector *SUnits; + + const TargetInstrInfo *TII; + const TargetRegisterInfo *TRI; + ScheduleDAGRRList *scheduleDAG; + public: - RegReductionPriorityQueue() : - Queue(SF(this)), currentQueueId(0) {} + RegReductionPriorityQueue(const TargetInstrInfo *tii, + const TargetRegisterInfo *tri) : + Queue(SF(this)), currentQueueId(0), + TII(tii), TRI(tri), scheduleDAG(NULL) {} - virtual void initNodes(std::vector &sunits) = 0; + void initNodes(std::vector &sunits) { + SUnits = &sunits; + } virtual void addNode(const SUnit *SU) = 0; virtual void updateNode(const SUnit *SU) = 0; - virtual void releaseState() = 0; + virtual void releaseState() { + SUnits = 0; + } virtual unsigned getNodePriority(const SUnit *SU) const = 0; @@ -1337,27 +1350,28 @@ Queue.erase_one(SU); SU->NodeQueueId = 0; } + + void setScheduleDAG(ScheduleDAGRRList *scheduleDag) { + scheduleDAG = scheduleDag; + } + + protected: + bool canClobber(const SUnit *SU, const SUnit *Op); + void AddPseudoTwoAddrDeps(); }; class VISIBILITY_HIDDEN BURegReductionPriorityQueue : public RegReductionPriorityQueue { - // SUnits - The SUnits for the current graph. - std::vector *SUnits; - // SethiUllmanNumbers - The SethiUllman number for each node. std::vector SethiUllmanNumbers; - const TargetInstrInfo *TII; - const TargetRegisterInfo *TRI; - ScheduleDAGRRList *scheduleDAG; - public: - explicit BURegReductionPriorityQueue(const TargetInstrInfo *tii, - const TargetRegisterInfo *tri) - : TII(tii), TRI(tri), scheduleDAG(NULL) {} + BURegReductionPriorityQueue(const TargetInstrInfo *tii, + const TargetRegisterInfo *tri) + : RegReductionPriorityQueue(tii, tri) {} void initNodes(std::vector &sunits) { - SUnits = &sunits; + RegReductionPriorityQueue::initNodes(sunits); // Add pseudo dependency edges for two-address nodes. AddPseudoTwoAddrDeps(); // Calculate node priorities. @@ -1377,7 +1391,7 @@ } void releaseState() { - SUnits = 0; + RegReductionPriorityQueue::releaseState(); SethiUllmanNumbers.clear(); } @@ -1412,29 +1426,23 @@ return SethiUllmanNumbers[SU->NodeNum]; } - void setScheduleDAG(ScheduleDAGRRList *scheduleDag) { - scheduleDAG = scheduleDag; - } - private: - bool canClobber(const SUnit *SU, const SUnit *Op); - void AddPseudoTwoAddrDeps(); void CalculateSethiUllmanNumbers(); }; class VISIBILITY_HIDDEN BURegReductionFastPriorityQueue : public RegReductionPriorityQueue { - // SUnits - The SUnits for the current graph. - const std::vector *SUnits; - // SethiUllmanNumbers - The SethiUllman number for each node. std::vector SethiUllmanNumbers; + public: - explicit BURegReductionFastPriorityQueue() {} + BURegReductionFastPriorityQueue(const TargetInstrInfo *tii, + const TargetRegisterInfo *tri) + : RegReductionPriorityQueue(tii, tri) {} void initNodes(std::vector &sunits) { - SUnits = &sunits; + RegReductionPriorityQueue::initNodes(sunits); // Calculate node priorities. CalculateSethiUllmanNumbers(); } @@ -1452,7 +1460,7 @@ } void releaseState() { - SUnits = 0; + RegReductionPriorityQueue::releaseState(); SethiUllmanNumbers.clear(); } @@ -1467,17 +1475,18 @@ class VISIBILITY_HIDDEN TDRegReductionPriorityQueue : public RegReductionPriorityQueue { - // SUnits - The SUnits for the current graph. - const std::vector *SUnits; - // SethiUllmanNumbers - The SethiUllman number for each node. std::vector SethiUllmanNumbers; public: - TDRegReductionPriorityQueue() {} + TDRegReductionPriorityQueue(const TargetInstrInfo *tii, + const TargetRegisterInfo *tri) + : RegReductionPriorityQueue(tii, tri) {} void initNodes(std::vector &sunits) { - SUnits = &sunits; + RegReductionPriorityQueue::initNodes(sunits); + // Add pseudo dependency edges for two-address nodes. + AddPseudoTwoAddrDeps(); // Calculate node priorities. CalculateSethiUllmanNumbers(); } @@ -1495,7 +1504,7 @@ } void releaseState() { - SUnits = 0; + RegReductionPriorityQueue::releaseState(); SethiUllmanNumbers.clear(); } @@ -1609,8 +1618,9 @@ return (left->NodeQueueId > right->NodeQueueId); } +template bool -BURegReductionPriorityQueue::canClobber(const SUnit *SU, const SUnit *Op) { +RegReductionPriorityQueue::canClobber(const SUnit *SU, const SUnit *Op) { if (SU->isTwoAddress) { unsigned Opc = SU->getNode()->getMachineOpcode(); const TargetInstrDesc &TID = TII->get(Opc); @@ -1678,7 +1688,8 @@ /// one that has a CopyToReg use (more likely to be a loop induction update). /// If both are two-address, but one is commutable while the other is not /// commutable, favor the one that's not commutable. -void BURegReductionPriorityQueue::AddPseudoTwoAddrDeps() { +template +void RegReductionPriorityQueue::AddPseudoTwoAddrDeps() { for (unsigned i = 0, e = SUnits->size(); i != e; ++i) { SUnit *SU = &(*SUnits)[i]; if (!SU->isTwoAddress) @@ -1833,13 +1844,13 @@ const TargetMachine *TM, MachineBasicBlock *BB, bool Fast) { - if (Fast) - return new ScheduleDAGRRList(DAG, BB, *TM, true, true, - new BURegReductionFastPriorityQueue()); - const TargetInstrInfo *TII = TM->getInstrInfo(); const TargetRegisterInfo *TRI = TM->getRegisterInfo(); + if (Fast) + return new ScheduleDAGRRList(DAG, BB, *TM, true, true, + new BURegReductionFastPriorityQueue(TII, TRI)); + BURegReductionPriorityQueue *PQ = new BURegReductionPriorityQueue(TII, TRI); ScheduleDAGRRList *SD = @@ -1853,6 +1864,12 @@ const TargetMachine *TM, MachineBasicBlock *BB, bool Fast) { - return new ScheduleDAGRRList(DAG, BB, *TM, false, Fast, - new TDRegReductionPriorityQueue()); + const TargetInstrInfo *TII = TM->getInstrInfo(); + const TargetRegisterInfo *TRI = TM->getRegisterInfo(); + + TDRegReductionPriorityQueue *PQ = new TDRegReductionPriorityQueue(TII, TRI); + + ScheduleDAGRRList *SD = new ScheduleDAGRRList(DAG, BB, *TM, false, Fast, PQ); + PQ->setScheduleDAG(SD); + return SD; } From ofv at wanadoo.es Wed Nov 19 21:10:17 2008 From: ofv at wanadoo.es (Oscar Fuentes) Date: Thu, 20 Nov 2008 03:10:17 -0000 Subject: [llvm-commits] [llvm] r59699 - in /llvm/trunk/cmake: config-ix.cmake modules/AddPartiallyLinkedObject.cmake Message-ID: <200811200310.mAK3AHh9007873@zion.cs.uiuc.edu> Author: ofv Date: Wed Nov 19 21:10:17 2008 New Revision: 59699 URL: http://llvm.org/viewvc/llvm-project?rev=59699&view=rev Log: CMake: when building shared libraries, use -fPIC for compiling partially linked objects. Modified: llvm/trunk/cmake/config-ix.cmake llvm/trunk/cmake/modules/AddPartiallyLinkedObject.cmake Modified: llvm/trunk/cmake/config-ix.cmake URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/cmake/config-ix.cmake?rev=59699&r1=59698&r2=59699&view=diff ============================================================================== --- llvm/trunk/cmake/config-ix.cmake (original) +++ llvm/trunk/cmake/config-ix.cmake Wed Nov 19 21:10:17 2008 @@ -52,6 +52,9 @@ check_symbol_exists(pthread_mutex_lock pthread.h HAVE_PTHREAD_MUTEX_LOCK) check_symbol_exists(strtoll stdlib.h HAVE_STRTOLL) +include(CheckCXXCompilerFlag) +check_cxx_compiler_flag("-fPIC" SUPPORTS_FPIC_FLAG) + include(GetTargetTriple) get_target_triple(LLVM_HOSTTRIPLE) message(STATUS "LLVM_HOSTTRIPLE: ${LLVM_HOSTTRIPLE}") Modified: llvm/trunk/cmake/modules/AddPartiallyLinkedObject.cmake URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/cmake/modules/AddPartiallyLinkedObject.cmake?rev=59699&r1=59698&r2=59699&view=diff ============================================================================== --- llvm/trunk/cmake/modules/AddPartiallyLinkedObject.cmake (original) +++ llvm/trunk/cmake/modules/AddPartiallyLinkedObject.cmake Wed Nov 19 21:10:17 2008 @@ -17,6 +17,9 @@ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/temp_lib) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/temp_lib) llvm_process_sources( ALL_FILES ${ARGN} ) + if( BUILD_SHARED_LIBS AND SUPPORTS_FPIC_FLAG ) + add_definitions(-fPIC) + endif() add_library( ${lib} STATIC ${ALL_FILES}) if( LLVM_COMMON_DEPENDS ) add_dependencies( ${lib} ${LLVM_COMMON_DEPENDS} ) From gohman at apple.com Wed Nov 19 21:11:19 2008 From: gohman at apple.com (Dan Gohman) Date: Thu, 20 Nov 2008 03:11:19 -0000 Subject: [llvm-commits] [llvm] r59700 - in /llvm/trunk/lib/CodeGen/SelectionDAG: ScheduleDAGRRList.cpp SelectionDAGISel.cpp Message-ID: <200811200311.mAK3BJKB007957@zion.cs.uiuc.edu> Author: djg Date: Wed Nov 19 21:11:19 2008 New Revision: 59700 URL: http://llvm.org/viewvc/llvm-project?rev=59700&view=rev Log: Remove the "fast" form of the list-burr scheduler, and use the dedicated "fast" scheduler in -fast mode instead, which is faster. This speeds up llc -fast by a few percent on some testcases -- the speedup only happens for code not handled by fast-isel. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp?rev=59700&r1=59699&r2=59700&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Wed Nov 19 21:11:19 2008 @@ -59,10 +59,6 @@ /// it is top-down. bool isBottomUp; - /// Fast - True if we are performing fast scheduling. - /// - bool Fast; - /// AvailableQueue - The priority queue to use for the available SUnits. SchedulingPriorityQueue *AvailableQueue; @@ -75,9 +71,9 @@ public: ScheduleDAGRRList(SelectionDAG *dag, MachineBasicBlock *bb, - const TargetMachine &tm, bool isbottomup, bool f, + const TargetMachine &tm, bool isbottomup, SchedulingPriorityQueue *availqueue) - : ScheduleDAGSDNodes(dag, bb, tm), isBottomUp(isbottomup), Fast(f), + : ScheduleDAGSDNodes(dag, bb, tm), isBottomUp(isbottomup), AvailableQueue(availqueue) { } @@ -187,10 +183,8 @@ DEBUG(for (unsigned su = 0, e = SUnits.size(); su != e; ++su) SUnits[su].dumpAll(this)); - if (!Fast) { - CalculateDepths(); - CalculateHeights(); - } + CalculateDepths(); + CalculateHeights(); InitDAGTopologicalSorting(); AvailableQueue->initNodes(SUnits); @@ -203,8 +197,7 @@ AvailableQueue->releaseState(); - if (!Fast) - CommuteNodesToReducePressure(); + CommuteNodesToReducePressure(); } /// CommuteNodesToReducePressure - If a node is two-address and commutable, and @@ -1431,48 +1424,6 @@ }; - class VISIBILITY_HIDDEN BURegReductionFastPriorityQueue - : public RegReductionPriorityQueue { - // SethiUllmanNumbers - The SethiUllman number for each node. - std::vector SethiUllmanNumbers; - - public: - BURegReductionFastPriorityQueue(const TargetInstrInfo *tii, - const TargetRegisterInfo *tri) - : RegReductionPriorityQueue(tii, tri) {} - - void initNodes(std::vector &sunits) { - RegReductionPriorityQueue::initNodes(sunits); - // Calculate node priorities. - CalculateSethiUllmanNumbers(); - } - - void addNode(const SUnit *SU) { - unsigned SUSize = SethiUllmanNumbers.size(); - if (SUnits->size() > SUSize) - SethiUllmanNumbers.resize(SUSize*2, 0); - CalcNodeBUSethiUllmanNumber(SU, SethiUllmanNumbers); - } - - void updateNode(const SUnit *SU) { - SethiUllmanNumbers[SU->NodeNum] = 0; - CalcNodeBUSethiUllmanNumber(SU, SethiUllmanNumbers); - } - - void releaseState() { - RegReductionPriorityQueue::releaseState(); - SethiUllmanNumbers.clear(); - } - - unsigned getNodePriority(const SUnit *SU) const { - return SethiUllmanNumbers[SU->NodeNum]; - } - - private: - void CalculateSethiUllmanNumbers(); - }; - - class VISIBILITY_HIDDEN TDRegReductionPriorityQueue : public RegReductionPriorityQueue { // SethiUllmanNumbers - The SethiUllman number for each node. @@ -1756,12 +1707,6 @@ for (unsigned i = 0, e = SUnits->size(); i != e; ++i) CalcNodeBUSethiUllmanNumber(&(*SUnits)[i], SethiUllmanNumbers); } -void BURegReductionFastPriorityQueue::CalculateSethiUllmanNumbers() { - SethiUllmanNumbers.assign(SUnits->size(), 0); - - for (unsigned i = 0, e = SUnits->size(); i != e; ++i) - CalcNodeBUSethiUllmanNumber(&(*SUnits)[i], SethiUllmanNumbers); -} /// LimitedSumOfUnscheduledPredsOfSuccs - Compute the sum of the unscheduled /// predecessors of the successors of the SUnit SU. Stop when the provided @@ -1843,18 +1788,14 @@ SelectionDAG *DAG, const TargetMachine *TM, MachineBasicBlock *BB, - bool Fast) { + bool) { const TargetInstrInfo *TII = TM->getInstrInfo(); const TargetRegisterInfo *TRI = TM->getRegisterInfo(); - if (Fast) - return new ScheduleDAGRRList(DAG, BB, *TM, true, true, - new BURegReductionFastPriorityQueue(TII, TRI)); - BURegReductionPriorityQueue *PQ = new BURegReductionPriorityQueue(TII, TRI); ScheduleDAGRRList *SD = - new ScheduleDAGRRList(DAG, BB, *TM, true, false, PQ); + new ScheduleDAGRRList(DAG, BB, *TM, true, PQ); PQ->setScheduleDAG(SD); return SD; } @@ -1863,13 +1804,13 @@ SelectionDAG *DAG, const TargetMachine *TM, MachineBasicBlock *BB, - bool Fast) { + bool) { const TargetInstrInfo *TII = TM->getInstrInfo(); const TargetRegisterInfo *TRI = TM->getRegisterInfo(); TDRegReductionPriorityQueue *PQ = new TDRegReductionPriorityQueue(TII, TRI); - ScheduleDAGRRList *SD = new ScheduleDAGRRList(DAG, BB, *TM, false, Fast, PQ); + ScheduleDAGRRList *SD = new ScheduleDAGRRList(DAG, BB, *TM, false, PQ); PQ->setScheduleDAG(SD); return SD; } Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=59700&r1=59699&r2=59700&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Wed Nov 19 21:11:19 2008 @@ -138,13 +138,13 @@ bool Fast) { TargetLowering &TLI = IS->getTargetLowering(); - if (TLI.getSchedulingPreference() == TargetLowering::SchedulingForLatency) { + if (Fast) + return createFastDAGScheduler(IS, DAG, TM, BB, Fast); + if (TLI.getSchedulingPreference() == TargetLowering::SchedulingForLatency) return createTDListDAGScheduler(IS, DAG, TM, BB, Fast); - } else { - assert(TLI.getSchedulingPreference() == - TargetLowering::SchedulingForRegPressure && "Unknown sched type!"); - return createBURRListDAGScheduler(IS, DAG, TM, BB, Fast); - } + assert(TLI.getSchedulingPreference() == + TargetLowering::SchedulingForRegPressure && "Unknown sched type!"); + return createBURRListDAGScheduler(IS, DAG, TM, BB, Fast); } } From gohman at apple.com Wed Nov 19 21:30:38 2008 From: gohman at apple.com (Dan Gohman) Date: Thu, 20 Nov 2008 03:30:38 -0000 Subject: [llvm-commits] [llvm] r59701 - /llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Message-ID: <200811200330.mAK3UcRG009007@zion.cs.uiuc.edu> Author: djg Date: Wed Nov 19 21:30:37 2008 New Revision: 59701 URL: http://llvm.org/viewvc/llvm-project?rev=59701&view=rev Log: Factor out the SethiUllman numbering logic from the list-burr and list-tdrr schedulers into a common base class. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp?rev=59701&r1=59700&r2=59701&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Wed Nov 19 21:30:37 2008 @@ -1209,10 +1209,10 @@ N->getOperand(N->getNumOperands()-1).getValueType() != MVT::Flag; } -/// CalcNodeBUSethiUllmanNumber - Compute Sethi Ullman number for bottom up -/// scheduling. Smaller number is the higher priority. +/// CalcNodeSethiUllmanNumber - Compute Sethi Ullman number. +/// Smaller number is the higher priority. static unsigned -CalcNodeBUSethiUllmanNumber(const SUnit *SU, std::vector &SUNumbers) { +CalcNodeSethiUllmanNumber(const SUnit *SU, std::vector &SUNumbers) { unsigned &SethiUllmanNumber = SUNumbers[SU->NodeNum]; if (SethiUllmanNumber != 0) return SethiUllmanNumber; @@ -1222,7 +1222,7 @@ I != E; ++I) { if (I->isCtrl) continue; // ignore chain preds SUnit *PredSU = I->Dep; - unsigned PredSethiUllman = CalcNodeBUSethiUllmanNumber(PredSU, SUNumbers); + unsigned PredSethiUllman = CalcNodeSethiUllmanNumber(PredSU, SUNumbers); if (PredSethiUllman > SethiUllmanNumber) { SethiUllmanNumber = PredSethiUllman; Extra = 0; @@ -1238,47 +1238,6 @@ return SethiUllmanNumber; } -/// CalcNodeTDSethiUllmanNumber - Compute Sethi Ullman number for top down -/// scheduling. Smaller number is the higher priority. -static unsigned -CalcNodeTDSethiUllmanNumber(const SUnit *SU, std::vector &SUNumbers) { - unsigned &SethiUllmanNumber = SUNumbers[SU->NodeNum]; - if (SethiUllmanNumber != 0) - return SethiUllmanNumber; - - unsigned Opc = SU->getNode() ? SU->getNode()->getOpcode() : 0; - if (Opc == ISD::TokenFactor || Opc == ISD::CopyToReg) - SethiUllmanNumber = 0xffff; - else if (SU->NumSuccsLeft == 0) - // If SU does not have a use, i.e. it doesn't produce a value that would - // be consumed (e.g. store), then it terminates a chain of computation. - // Give it a small SethiUllman number so it will be scheduled right before - // its predecessors that it doesn't lengthen their live ranges. - SethiUllmanNumber = 0; - else if (SU->NumPredsLeft == 0 && - (Opc != ISD::CopyFromReg || isCopyFromLiveIn(SU))) - SethiUllmanNumber = 0xffff; - else { - int Extra = 0; - for (SUnit::const_pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); - I != E; ++I) { - if (I->isCtrl) continue; // ignore chain preds - SUnit *PredSU = I->Dep; - unsigned PredSethiUllman = CalcNodeTDSethiUllmanNumber(PredSU, SUNumbers); - if (PredSethiUllman > SethiUllmanNumber) { - SethiUllmanNumber = PredSethiUllman; - Extra = 0; - } else if (PredSethiUllman == SethiUllmanNumber && !I->isCtrl) - ++Extra; - } - - SethiUllmanNumber += Extra; - } - - return SethiUllmanNumber; -} - - namespace { template class VISIBILITY_HIDDEN RegReductionPriorityQueue @@ -1294,6 +1253,9 @@ const TargetRegisterInfo *TRI; ScheduleDAGRRList *scheduleDAG; + // SethiUllmanNumbers - The SethiUllman number for each node. + std::vector SethiUllmanNumbers; + public: RegReductionPriorityQueue(const TargetInstrInfo *tii, const TargetRegisterInfo *tri) : @@ -1302,69 +1264,6 @@ void initNodes(std::vector &sunits) { SUnits = &sunits; - } - - virtual void addNode(const SUnit *SU) = 0; - - virtual void updateNode(const SUnit *SU) = 0; - - virtual void releaseState() { - SUnits = 0; - } - - virtual unsigned getNodePriority(const SUnit *SU) const = 0; - - unsigned size() const { return Queue.size(); } - - bool empty() const { return Queue.empty(); } - - void push(SUnit *U) { - assert(!U->NodeQueueId && "Node in the queue already"); - U->NodeQueueId = ++currentQueueId; - Queue.push(U); - } - - void push_all(const std::vector &Nodes) { - for (unsigned i = 0, e = Nodes.size(); i != e; ++i) - push(Nodes[i]); - } - - SUnit *pop() { - if (empty()) return NULL; - SUnit *V = Queue.top(); - Queue.pop(); - V->NodeQueueId = 0; - return V; - } - - void remove(SUnit *SU) { - assert(!Queue.empty() && "Queue is empty!"); - assert(SU->NodeQueueId != 0 && "Not in queue!"); - Queue.erase_one(SU); - SU->NodeQueueId = 0; - } - - void setScheduleDAG(ScheduleDAGRRList *scheduleDag) { - scheduleDAG = scheduleDag; - } - - protected: - bool canClobber(const SUnit *SU, const SUnit *Op); - void AddPseudoTwoAddrDeps(); - }; - - class VISIBILITY_HIDDEN BURegReductionPriorityQueue - : public RegReductionPriorityQueue { - // SethiUllmanNumbers - The SethiUllman number for each node. - std::vector SethiUllmanNumbers; - - public: - BURegReductionPriorityQueue(const TargetInstrInfo *tii, - const TargetRegisterInfo *tri) - : RegReductionPriorityQueue(tii, tri) {} - - void initNodes(std::vector &sunits) { - RegReductionPriorityQueue::initNodes(sunits); // Add pseudo dependency edges for two-address nodes. AddPseudoTwoAddrDeps(); // Calculate node priorities. @@ -1375,16 +1274,16 @@ unsigned SUSize = SethiUllmanNumbers.size(); if (SUnits->size() > SUSize) SethiUllmanNumbers.resize(SUSize*2, 0); - CalcNodeBUSethiUllmanNumber(SU, SethiUllmanNumbers); + CalcNodeSethiUllmanNumber(SU, SethiUllmanNumbers); } void updateNode(const SUnit *SU) { SethiUllmanNumbers[SU->NodeNum] = 0; - CalcNodeBUSethiUllmanNumber(SU, SethiUllmanNumbers); + CalcNodeSethiUllmanNumber(SU, SethiUllmanNumbers); } void releaseState() { - RegReductionPriorityQueue::releaseState(); + SUnits = 0; SethiUllmanNumbers.clear(); } @@ -1418,55 +1317,52 @@ else return SethiUllmanNumbers[SU->NodeNum]; } + + unsigned size() const { return Queue.size(); } - private: - void CalculateSethiUllmanNumbers(); - }; - - - class VISIBILITY_HIDDEN TDRegReductionPriorityQueue - : public RegReductionPriorityQueue { - // SethiUllmanNumbers - The SethiUllman number for each node. - std::vector SethiUllmanNumbers; - - public: - TDRegReductionPriorityQueue(const TargetInstrInfo *tii, - const TargetRegisterInfo *tri) - : RegReductionPriorityQueue(tii, tri) {} - - void initNodes(std::vector &sunits) { - RegReductionPriorityQueue::initNodes(sunits); - // Add pseudo dependency edges for two-address nodes. - AddPseudoTwoAddrDeps(); - // Calculate node priorities. - CalculateSethiUllmanNumbers(); + bool empty() const { return Queue.empty(); } + + void push(SUnit *U) { + assert(!U->NodeQueueId && "Node in the queue already"); + U->NodeQueueId = ++currentQueueId; + Queue.push(U); } - void addNode(const SUnit *SU) { - unsigned SUSize = SethiUllmanNumbers.size(); - if (SUnits->size() > SUSize) - SethiUllmanNumbers.resize(SUSize*2, 0); - CalcNodeTDSethiUllmanNumber(SU, SethiUllmanNumbers); + void push_all(const std::vector &Nodes) { + for (unsigned i = 0, e = Nodes.size(); i != e; ++i) + push(Nodes[i]); } - - void updateNode(const SUnit *SU) { - SethiUllmanNumbers[SU->NodeNum] = 0; - CalcNodeTDSethiUllmanNumber(SU, SethiUllmanNumbers); + + SUnit *pop() { + if (empty()) return NULL; + SUnit *V = Queue.top(); + Queue.pop(); + V->NodeQueueId = 0; + return V; } - void releaseState() { - RegReductionPriorityQueue::releaseState(); - SethiUllmanNumbers.clear(); + void remove(SUnit *SU) { + assert(!Queue.empty() && "Queue is empty!"); + assert(SU->NodeQueueId != 0 && "Not in queue!"); + Queue.erase_one(SU); + SU->NodeQueueId = 0; } - unsigned getNodePriority(const SUnit *SU) const { - assert(SU->NodeNum < SethiUllmanNumbers.size()); - return SethiUllmanNumbers[SU->NodeNum]; + void setScheduleDAG(ScheduleDAGRRList *scheduleDag) { + scheduleDAG = scheduleDag; } - private: + protected: + bool canClobber(const SUnit *SU, const SUnit *Op); + void AddPseudoTwoAddrDeps(); void CalculateSethiUllmanNumbers(); }; + + typedef RegReductionPriorityQueue + BURegReductionPriorityQueue; + + typedef RegReductionPriorityQueue + TDRegReductionPriorityQueue; } /// closestSucc - Returns the scheduled cycle of the successor which is @@ -1701,11 +1597,12 @@ /// CalculateSethiUllmanNumbers - Calculate Sethi-Ullman numbers of all /// scheduling units. -void BURegReductionPriorityQueue::CalculateSethiUllmanNumbers() { +template +void RegReductionPriorityQueue::CalculateSethiUllmanNumbers() { SethiUllmanNumbers.assign(SUnits->size(), 0); for (unsigned i = 0, e = SUnits->size(); i != e; ++i) - CalcNodeBUSethiUllmanNumber(&(*SUnits)[i], SethiUllmanNumbers); + CalcNodeSethiUllmanNumber(&(*SUnits)[i], SethiUllmanNumbers); } /// LimitedSumOfUnscheduledPredsOfSuccs - Compute the sum of the unscheduled @@ -1771,15 +1668,6 @@ return (left->NodeQueueId > right->NodeQueueId); } -/// CalculateSethiUllmanNumbers - Calculate Sethi-Ullman numbers of all -/// scheduling units. -void TDRegReductionPriorityQueue::CalculateSethiUllmanNumbers() { - SethiUllmanNumbers.assign(SUnits->size(), 0); - - for (unsigned i = 0, e = SUnits->size(); i != e; ++i) - CalcNodeTDSethiUllmanNumber(&(*SUnits)[i], SethiUllmanNumbers); -} - //===----------------------------------------------------------------------===// // Public Constructor Functions //===----------------------------------------------------------------------===// From gohman at apple.com Wed Nov 19 21:32:45 2008 From: gohman at apple.com (Dan Gohman) Date: Thu, 20 Nov 2008 03:32:45 -0000 Subject: [llvm-commits] [llvm] r59702 - /llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Message-ID: <200811200332.mAK3Wjdh009079@zion.cs.uiuc.edu> Author: djg Date: Wed Nov 19 21:32:45 2008 New Revision: 59702 URL: http://llvm.org/viewvc/llvm-project?rev=59702&view=rev Log: Remove a remnant of list-burr's fast mode. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp?rev=59702&r1=59701&r2=59702&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Wed Nov 19 21:32:45 2008 @@ -1185,15 +1185,6 @@ bool operator()(const SUnit* left, const SUnit* right) const; }; - struct bu_ls_rr_fast_sort : public std::binary_function{ - RegReductionPriorityQueue *SPQ; - bu_ls_rr_fast_sort(RegReductionPriorityQueue *spq) - : SPQ(spq) {} - bu_ls_rr_fast_sort(const bu_ls_rr_fast_sort &RHS) : SPQ(RHS.SPQ) {} - - bool operator()(const SUnit* left, const SUnit* right) const; - }; - struct td_ls_rr_sort : public std::binary_function { RegReductionPriorityQueue *SPQ; td_ls_rr_sort(RegReductionPriorityQueue *spq) : SPQ(spq) {} @@ -1454,17 +1445,6 @@ return (left->NodeQueueId > right->NodeQueueId); } -bool -bu_ls_rr_fast_sort::operator()(const SUnit *left, const SUnit *right) const { - unsigned LPriority = SPQ->getNodePriority(left); - unsigned RPriority = SPQ->getNodePriority(right); - if (LPriority != RPriority) - return LPriority > RPriority; - assert(left->NodeQueueId && right->NodeQueueId && - "NodeQueueId cannot be zero"); - return (left->NodeQueueId > right->NodeQueueId); -} - template bool RegReductionPriorityQueue::canClobber(const SUnit *SU, const SUnit *Op) { From scottm at aero.org Wed Nov 19 22:26:26 2008 From: scottm at aero.org (Scott Michel) Date: Thu, 20 Nov 2008 04:26:26 -0000 Subject: [llvm-commits] [llvm] r59703 - in /llvm/trunk: autoconf/AutoRegen.sh lib/Target/CellSPU/SPUISelLowering.cpp Message-ID: <200811200426.mAK4QQO2012333@zion.cs.uiuc.edu> Author: pingbak Date: Wed Nov 19 22:26:21 2008 New Revision: 59703 URL: http://llvm.org/viewvc/llvm-project?rev=59703&view=rev Log: CellSPU: Adjust spacing/tabulation Modified: llvm/trunk/autoconf/AutoRegen.sh llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp Modified: llvm/trunk/autoconf/AutoRegen.sh URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/autoconf/AutoRegen.sh?rev=59703&r1=59702&r2=59703&view=diff ============================================================================== --- llvm/trunk/autoconf/AutoRegen.sh (original) +++ llvm/trunk/autoconf/AutoRegen.sh Wed Nov 19 22:26:21 2008 @@ -7,7 +7,7 @@ ### NOTE: ############################################################" ### The below two variables specify the auto* versions ### periods should be escaped with backslash, for use by grep -want_autoconf_version='2\.60' +want_autoconf_version='2\.6[01]' want_autoheader_version=$want_autoconf_version ### END NOTE #########################################################" @@ -22,7 +22,7 @@ test -f $configfile || die "Can't find 'autoconf' dir; please cd into it first" autoconf --version | grep $want_autoconf_version > /dev/null test $? -eq 0 || die "Your autoconf was not detected as being $want_autoconf_version_clean" -aclocal --version | grep '^aclocal.*1\.9\.6' > /dev/null +aclocal --version | grep '^aclocal.*\(1\.9\.6\|1\.10\)' > /dev/null test $? -eq 0 || die "Your aclocal was not detected as being 1.9.6" autoheader --version | grep '^autoheader.*'$want_autoheader_version > /dev/null test $? -eq 0 || die "Your autoheader was not detected as being $want_autoheader_version_clean" Modified: llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp?rev=59703&r1=59702&r2=59703&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp (original) +++ llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp Wed Nov 19 22:26:21 2008 @@ -135,19 +135,19 @@ setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote); setLoadExtAction(ISD::ZEXTLOAD, MVT::i1, Promote); setTruncStoreAction(MVT::i8, MVT::i1, Promote); - setTruncStoreAction(MVT::i16 , MVT::i1, Custom); - setTruncStoreAction(MVT::i32 , MVT::i1, Custom); - setTruncStoreAction(MVT::i64 , MVT::i1, Custom); + setTruncStoreAction(MVT::i16, MVT::i1, Custom); + setTruncStoreAction(MVT::i32, MVT::i1, Custom); + setTruncStoreAction(MVT::i64, MVT::i1, Custom); setTruncStoreAction(MVT::i128, MVT::i1, Custom); setLoadExtAction(ISD::EXTLOAD, MVT::i8, Custom); setLoadExtAction(ISD::SEXTLOAD, MVT::i8, Custom); setLoadExtAction(ISD::ZEXTLOAD, MVT::i8, Custom); - setTruncStoreAction(MVT::i8 , MVT::i8, Custom); - setTruncStoreAction(MVT::i16 , MVT::i8, Custom); - setTruncStoreAction(MVT::i32 , MVT::i8, Custom); - setTruncStoreAction(MVT::i64 , MVT::i8, Custom); - setTruncStoreAction(MVT::i128, MVT::i8, Custom); + setTruncStoreAction(MVT::i8, MVT::i8, Custom); + setTruncStoreAction(MVT::i16, MVT::i8, Custom); + setTruncStoreAction(MVT::i32, MVT::i8, Custom); + setTruncStoreAction(MVT::i64, MVT::i8, Custom); + setTruncStoreAction(MVT::i128, MVT::i8, Custom); setLoadExtAction(ISD::EXTLOAD, MVT::i16, Custom); setLoadExtAction(ISD::SEXTLOAD, MVT::i16, Custom); From scottm at aero.org Wed Nov 19 22:28:09 2008 From: scottm at aero.org (Scott Michel) Date: Thu, 20 Nov 2008 04:28:09 -0000 Subject: [llvm-commits] [llvm] r59704 - /llvm/trunk/autoconf/AutoRegen.sh Message-ID: <200811200428.mAK4S9S9012503@zion.cs.uiuc.edu> Author: pingbak Date: Wed Nov 19 22:28:08 2008 New Revision: 59704 URL: http://llvm.org/viewvc/llvm-project?rev=59704&view=rev Log: Revert accidental last patch Modified: llvm/trunk/autoconf/AutoRegen.sh Modified: llvm/trunk/autoconf/AutoRegen.sh URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/autoconf/AutoRegen.sh?rev=59704&r1=59703&r2=59704&view=diff ============================================================================== --- llvm/trunk/autoconf/AutoRegen.sh (original) +++ llvm/trunk/autoconf/AutoRegen.sh Wed Nov 19 22:28:08 2008 @@ -7,7 +7,7 @@ ### NOTE: ############################################################" ### The below two variables specify the auto* versions ### periods should be escaped with backslash, for use by grep -want_autoconf_version='2\.6[01]' +want_autoconf_version='2\.60' want_autoheader_version=$want_autoconf_version ### END NOTE #########################################################" @@ -22,7 +22,7 @@ test -f $configfile || die "Can't find 'autoconf' dir; please cd into it first" autoconf --version | grep $want_autoconf_version > /dev/null test $? -eq 0 || die "Your autoconf was not detected as being $want_autoconf_version_clean" -aclocal --version | grep '^aclocal.*\(1\.9\.6\|1\.10\)' > /dev/null +aclocal --version | grep '^aclocal.*1\.9\.6' > /dev/null test $? -eq 0 || die "Your aclocal was not detected as being 1.9.6" autoheader --version | grep '^autoheader.*'$want_autoheader_version > /dev/null test $? -eq 0 || die "Your autoheader was not detected as being $want_autoheader_version_clean" From nicholas at mxc.ca Wed Nov 19 22:36:14 2008 From: nicholas at mxc.ca (Nick Lewycky) Date: Thu, 20 Nov 2008 04:36:14 -0000 Subject: [llvm-commits] [llvm] r59705 - /llvm/trunk/lib/Analysis/ConstantFolding.cpp Message-ID: <200811200436.mAK4aEpA013107@zion.cs.uiuc.edu> Author: nicholas Date: Wed Nov 19 22:36:13 2008 New Revision: 59705 URL: http://llvm.org/viewvc/llvm-project?rev=59705&view=rev Log: undef beats zero. Fix this missed optimization opportunity. Patch by Matt Elder! Modified: llvm/trunk/lib/Analysis/ConstantFolding.cpp Modified: llvm/trunk/lib/Analysis/ConstantFolding.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ConstantFolding.cpp?rev=59705&r1=59704&r2=59705&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ConstantFolding.cpp (original) +++ llvm/trunk/lib/Analysis/ConstantFolding.cpp Wed Nov 19 22:36:13 2008 @@ -281,7 +281,7 @@ Constant *llvm::ConstantFoldInstruction(Instruction *I, const TargetData *TD) { if (PHINode *PN = dyn_cast(I)) { if (PN->getNumIncomingValues() == 0) - return Constant::getNullValue(PN->getType()); + return UndefValue::get(PN->getType()); Constant *Result = dyn_cast(PN->getIncomingValue(0)); if (Result == 0) return 0; From nicholas at mxc.ca Wed Nov 19 22:36:28 2008 From: nicholas at mxc.ca (Nick Lewycky) Date: Wed, 19 Nov 2008 20:36:28 -0800 Subject: [llvm-commits] Patch to lib/Analysis/ConstantFolding.cpp In-Reply-To: <492257EC.80205@cs.wisc.edu> References: <492257EC.80205@cs.wisc.edu> Message-ID: <4924E94C.6070605@mxc.ca> Matt Elder wrote: > Probably a small error in ConstantFoldInstruction(). Patch attached. I've applied your patch in r59705. Thanks! Nick From nicholas at mxc.ca Wed Nov 19 22:41:09 2008 From: nicholas at mxc.ca (Nick Lewycky) Date: Wed, 19 Nov 2008 20:41:09 -0800 Subject: [llvm-commits] [llvm] r59528 - in /llvm/trunk: lib/Analysis/ScalarEvolution.cpp test/Analysis/ScalarEvolution/2008-11-18-LessThanOrEqual.ll test/Analysis/ScalarEvolution/2008-11-18-Stride1.ll test/Analysis/ScalarEvolution/2008-11-18-Stride2.ll In-Reply-To: <520D57A2-6CB1-48F1-B5DB-9523121F3058@apple.com> References: <200811181510.mAIFAtVS001882@zion.cs.uiuc.edu> <4C90C36A-77D6-4006-9F3F-19002F2E561A@apple.com> <49238A20.3010803@mxc.ca> <520D57A2-6CB1-48F1-B5DB-9523121F3058@apple.com> Message-ID: <4924EA65.5050300@mxc.ca> Evan Cheng wrote: > On Nov 18, 2008, at 7:38 PM, Nick Lewycky wrote: > >> Evan Cheng wrote: >>> Hi Nicholas, >>> >>> What does "trueWhenEqual" mean? Should it default to true / false? >> Like isSigned, it defines whether the comparison is true when equal, >> ie., it's an SLT/ULT vs. SLE/ULE. There is no default, but the old >> version only knew how to handle trueWhenEqual=false (ie., SLT/ULT). > > Can you make the default false? That way old code that use it (which > may not be part of the tree) won't have to change. These are all private methods in the ScalarEvolutionsImpl class (which is VISIBILITY_HIDDEN in an anonymous namespace). The public interface in llvm/include/Analysis/ScalarEvolution.h hasn't changed. Nick > Thanks, > > Evan > >> >> Nick >> >>> Thanks, >>> >>> Evan >>> >>> On Nov 18, 2008, at 7:10 AM, Nick Lewycky wrote: >>> >>>> Author: nicholas >>>> Date: Tue Nov 18 09:10:54 2008 >>>> New Revision: 59528 >>>> >>>> URL: http://llvm.org/viewvc/llvm-project?rev=59528&view=rev >>>> Log: >>>> Add a utility function that detects whether a loop is guaranteed to >>>> be finite. >>>> >>>> Use it to safely handle less-than-or-equals-to exit conditions in >>>> loops. These >>>> also occur when the loop exit branch is exit on true because SCEV >>>> inverses the >>>> icmp predicate. >>>> >>>> Use it again to handle non-zero strides, but only with an unsigned >>>> comparison >>>> in the exit condition. >>>> >>>> Added: >>>> llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18- >>>> LessThanOrEqual.ll >>>> llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride1.ll >>>> llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride2.ll >>>> Modified: >>>> llvm/trunk/lib/Analysis/ScalarEvolution.cpp >>>> >>>> Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp >>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=59528&r1=59527&r2=59528&view=diff >>>> >>>> = >>>> = >>>> = >>>> = >>>> = >>>> = >>>> = >>>> = >>>> = >>>> = >>>> ==================================================================== >>>> --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original) >>>> +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Tue Nov 18 09:10:54 >>>> 2008 >>>> @@ -1477,7 +1477,7 @@ >>>> /// specified less-than comparison will execute. If not >>>> computable, return >>>> /// UnknownValue. isSigned specifies whether the less-than is >>>> signed. >>>> SCEVHandle HowManyLessThans(SCEV *LHS, SCEV *RHS, const Loop *L, >>>> - bool isSigned); >>>> + bool isSigned, bool trueWhenEqual); >>>> >>>> /// getPredecessorWithUniqueSuccessorForBB - Return a >>>> predecessor of BB >>>> /// (which may not be an immediate predecessor) which has >>>> exactly one >>>> @@ -1487,7 +1487,13 @@ >>>> >>>> /// executesAtLeastOnce - Test whether entry to the loop is >>>> protected by >>>> /// a conditional between LHS and RHS. >>>> - bool executesAtLeastOnce(const Loop *L, bool isSigned, SCEV >>>> *LHS, SCEV *RHS); >>>> + bool executesAtLeastOnce(const Loop *L, bool isSigned, bool >>>> trueWhenEqual, >>>> + SCEV *LHS, SCEV *RHS); >>>> + >>>> + /// potentialInfiniteLoop - Test whether the loop might jump >>>> over the exit value >>>> + /// due to wrapping. >>>> + bool potentialInfiniteLoop(SCEV *Stride, SCEV *RHS, bool >>>> isSigned, >>>> + bool trueWhenEqual); >>>> >>>> /// getConstantEvolutionLoopExitValue - If we know that the >>>> specified Phi is >>>> /// in the header of its containing loop, we know the loop >>>> executes a >>>> @@ -2025,24 +2031,46 @@ >>>> break; >>>> } >>>> case ICmpInst::ICMP_SLT: { >>>> - SCEVHandle TC = HowManyLessThans(LHS, RHS, L, true); >>>> + SCEVHandle TC = HowManyLessThans(LHS, RHS, L, true, false); >>>> if (!isa(TC)) return TC; >>>> break; >>>> } >>>> case ICmpInst::ICMP_SGT: { >>>> SCEVHandle TC = HowManyLessThans(SE.getNotSCEV(LHS), >>>> - SE.getNotSCEV(RHS), L, true); >>>> + SE.getNotSCEV(RHS), L, true, >>>> false); >>>> if (!isa(TC)) return TC; >>>> break; >>>> } >>>> case ICmpInst::ICMP_ULT: { >>>> - SCEVHandle TC = HowManyLessThans(LHS, RHS, L, false); >>>> + SCEVHandle TC = HowManyLessThans(LHS, RHS, L, false, false); >>>> if (!isa(TC)) return TC; >>>> break; >>>> } >>>> case ICmpInst::ICMP_UGT: { >>>> SCEVHandle TC = HowManyLessThans(SE.getNotSCEV(LHS), >>>> - SE.getNotSCEV(RHS), L, false); >>>> + SE.getNotSCEV(RHS), L, false, >>>> false); >>>> + if (!isa(TC)) return TC; >>>> + break; >>>> + } >>>> + case ICmpInst::ICMP_SLE: { >>>> + SCEVHandle TC = HowManyLessThans(LHS, RHS, L, true, true); >>>> + if (!isa(TC)) return TC; >>>> + break; >>>> + } >>>> + case ICmpInst::ICMP_SGE: { >>>> + SCEVHandle TC = HowManyLessThans(SE.getNotSCEV(LHS), >>>> + SE.getNotSCEV(RHS), L, true, >>>> true); >>>> + if (!isa(TC)) return TC; >>>> + break; >>>> + } >>>> + case ICmpInst::ICMP_ULE: { >>>> + SCEVHandle TC = HowManyLessThans(LHS, RHS, L, false, true); >>>> + if (!isa(TC)) return TC; >>>> + break; >>>> + } >>>> + case ICmpInst::ICMP_UGE: { >>>> + SCEVHandle TC = HowManyLessThans(SE.getNotSCEV(LHS), >>>> + SE.getNotSCEV(RHS), L, false, >>>> true); >>>> if (!isa(TC)) return TC; >>>> break; >>>> } >>>> @@ -2738,6 +2766,7 @@ >>>> /// executesAtLeastOnce - Test whether entry to the loop is >>>> protected by >>>> /// a conditional between LHS and RHS. >>>> bool ScalarEvolutionsImpl::executesAtLeastOnce(const Loop *L, bool >>>> isSigned, >>>> + bool trueWhenEqual, >>>> SCEV *LHS, SCEV >>>> *RHS) { >>>> BasicBlock *Preheader = L->getLoopPreheader(); >>>> BasicBlock *PreheaderDest = L->getHeader(); >>>> @@ -2770,20 +2799,36 @@ >>>> >>>> switch (Cond) { >>>> case ICmpInst::ICMP_UGT: >>>> - if (isSigned) continue; >>>> + if (isSigned || trueWhenEqual) continue; >>>> std::swap(PreCondLHS, PreCondRHS); >>>> Cond = ICmpInst::ICMP_ULT; >>>> break; >>>> case ICmpInst::ICMP_SGT: >>>> - if (!isSigned) continue; >>>> + if (!isSigned || trueWhenEqual) continue; >>>> std::swap(PreCondLHS, PreCondRHS); >>>> Cond = ICmpInst::ICMP_SLT; >>>> break; >>>> case ICmpInst::ICMP_ULT: >>>> - if (isSigned) continue; >>>> + if (isSigned || trueWhenEqual) continue; >>>> break; >>>> case ICmpInst::ICMP_SLT: >>>> - if (!isSigned) continue; >>>> + if (!isSigned || trueWhenEqual) continue; >>>> + break; >>>> + case ICmpInst::ICMP_UGE: >>>> + if (isSigned || !trueWhenEqual) continue; >>>> + std::swap(PreCondLHS, PreCondRHS); >>>> + Cond = ICmpInst::ICMP_ULE; >>>> + break; >>>> + case ICmpInst::ICMP_SGE: >>>> + if (!isSigned || !trueWhenEqual) continue; >>>> + std::swap(PreCondLHS, PreCondRHS); >>>> + Cond = ICmpInst::ICMP_SLE; >>>> + break; >>>> + case ICmpInst::ICMP_ULE: >>>> + if (isSigned || !trueWhenEqual) continue; >>>> + break; >>>> + case ICmpInst::ICMP_SLE: >>>> + if (!isSigned || !trueWhenEqual) continue; >>>> break; >>>> default: >>>> continue; >>>> @@ -2802,11 +2847,46 @@ >>>> return false; >>>> } >>>> >>>> +/// potentialInfiniteLoop - Test whether the loop might jump over >>>> the exit value >>>> +/// due to wrapping around 2^n. >>>> +bool ScalarEvolutionsImpl::potentialInfiniteLoop(SCEV *Stride, SCEV >>>> *RHS, >>>> + bool isSigned, >>>> bool trueWhenEqual) { >>>> + // Return true when the distance from RHS to maxint > Stride. >>>> + >>>> + if (!isa(Stride)) >>>> + return true; >>>> + SCEVConstant *SC = cast(Stride); >>>> + >>>> + if (SC->getValue()->isZero()) >>>> + return true; >>>> + if (!trueWhenEqual && SC->getValue()->isOne()) >>>> + return false; >>>> + >>>> + if (!isa(RHS)) >>>> + return true; >>>> + SCEVConstant *R = cast(RHS); >>>> + >>>> + if (isSigned) >>>> + return true; // XXX: because we don't have an sdiv scev. >>>> + >>>> + // If negative, it wraps around every iteration, but we don't >>>> care about that. >>>> + APInt S = SC->getValue()->getValue().abs(); >>>> + >>>> + APInt Dist = APInt::getMaxValue(R->getValue()->getBitWidth()) - >>>> + R->getValue()->getValue(); >>>> + >>>> + if (trueWhenEqual) >>>> + return !S.ult(Dist); >>>> + else >>>> + return !S.ule(Dist); >>>> +} >>>> + >>>> /// HowManyLessThans - Return the number of times a backedge >>>> containing the >>>> /// specified less-than comparison will execute. If not computable, >>>> return >>>> /// UnknownValue. >>>> SCEVHandle ScalarEvolutionsImpl:: >>>> -HowManyLessThans(SCEV *LHS, SCEV *RHS, const Loop *L, bool >>>> isSigned) { >>>> +HowManyLessThans(SCEV *LHS, SCEV *RHS, const Loop *L, >>>> + bool isSigned, bool trueWhenEqual) { >>>> // Only handle: "ADDREC < LoopInvariant". >>>> if (!RHS->isLoopInvariant(L)) return UnknownValue; >>>> >>>> @@ -2815,34 +2895,50 @@ >>>> return UnknownValue; >>>> >>>> if (AddRec->isAffine()) { >>>> - // FORNOW: We only support unit strides. >>>> - SCEVHandle One = SE.getIntegerSCEV(1, RHS->getType()); >>>> - if (AddRec->getOperand(1) != One) >>>> + SCEVHandle Stride = AddRec->getOperand(1); >>>> + if (potentialInfiniteLoop(Stride, RHS, isSigned, >>>> trueWhenEqual)) >>>> return UnknownValue; >>>> >>>> - // We know the LHS is of the form {n,+,1} and the RHS is some >>>> loop-invariant >>>> - // m. So, we count the number of iterations in which {n,+,1} < >>>> m is true. >>>> - // Note that we cannot simply return max(m-n,0) because it's >>>> not safe to >>>> + // We know the LHS is of the form {n,+,s} and the RHS is some >>>> loop-invariant >>>> + // m. So, we count the number of iterations in which {n,+,s} < >>>> m is true. >>>> + // Note that we cannot simply return max(m-n,0)/s because it's >>>> not safe to >>>> // treat m-n as signed nor unsigned due to overflow possibility. >>>> >>>> // First, we get the value of the LHS in the first iteration: n >>>> SCEVHandle Start = AddRec->getOperand(0); >>>> >>>> - if (executesAtLeastOnce(L, isSigned, >>>> - SE.getMinusSCEV(AddRec->getOperand(0), >>>> One), RHS)) { >>>> - // Since we know that the condition is true in order to enter >>>> the loop, >>>> - // we know that it will run exactly m-n times. >>>> - return SE.getMinusSCEV(RHS, Start); >>>> - } else { >>>> - // Then, we get the value of the LHS in the first iteration >>>> in which the >>>> - // above condition doesn't hold. This equals to max(m,n). >>>> - SCEVHandle End = isSigned ? SE.getSMaxExpr(RHS, Start) >>>> - : SE.getUMaxExpr(RHS, Start); >>>> - >>>> - // Finally, we subtract these two values to get the number of >>>> times the >>>> - // backedge is executed: max(m,n)-n. >>>> - return SE.getMinusSCEV(End, Start); >>>> + SCEVHandle One = SE.getIntegerSCEV(1, RHS->getType()); >>>> + >>>> + // Assuming that the loop will run at least once, we know that >>>> it will >>>> + // run (m-n)/s times. >>>> + SCEVHandle End = RHS; >>>> + >>>> + if (!executesAtLeastOnce(L, isSigned, trueWhenEqual, >>>> + SE.getMinusSCEV(Start, One), RHS)) { >>>> + // If not, we get the value of the LHS in the first iteration >>>> in which >>>> + // the above condition doesn't hold. This equals to >>>> max(m,n). >>>> + End = isSigned ? SE.getSMaxExpr(RHS, Start) >>>> + : SE.getUMaxExpr(RHS, Start); >>>> } >>>> + >>>> + // If the expression is less-than-or-equal to, we need to >>>> extend the >>>> + // loop by one iteration. >>>> + // >>>> + // The loop won't actually run (m-n)/s times because the loop >>>> iterations >>>> + // won't divide evenly. For example, if you have {2,+,5} u< 10 >>>> the >>>> + // division would equal one, but the loop runs twice putting >>>> the >>>> + // induction variable at 12. >>>> + >>>> + if (!trueWhenEqual) >>>> + // (Stride - 1) is correct only because we know it's >>>> unsigned. >>>> + // What we really want is to decrease the magnitude of Stride >>>> by one. >>>> + Start = SE.getMinusSCEV(Start, SE.getMinusSCEV(Stride, One)); >>>> + else >>>> + Start = SE.getMinusSCEV(Start, Stride); >>>> + >>>> + // Finally, we subtract these two values to get the number of >>>> times the >>>> + // backedge is executed: max(m,n)-n. >>>> + return SE.getUDivExpr(SE.getMinusSCEV(End, Start), Stride); >>>> } >>>> >>>> return UnknownValue; >>>> >>>> Added: llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18- >>>> LessThanOrEqual.ll >>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-LessThanOrEqual.ll?rev=59528&view=auto >>>> >>>> = >>>> = >>>> = >>>> = >>>> = >>>> = >>>> = >>>> = >>>> = >>>> = >>>> ==================================================================== >>>> --- llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18- >>>> LessThanOrEqual.ll (added) >>>> +++ llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18- >>>> LessThanOrEqual.ll Tue Nov 18 09:10:54 2008 >>>> @@ -0,0 +1,31 @@ >>>> +; RUN: llvm-as < %s | opt -analyze -scalar-evolution |& \ >>>> +; RUN: grep {Loop bb: (7 + (-1 \\* %argc)) iterations!} >>>> + >>>> +define i32 @main(i32 %argc, i8** %argv) nounwind { >>>> +entry: >>>> + %0 = icmp ugt i32 %argc, 7 ; [#uses=1] >>>> + br i1 %0, label %bb2, label %bb.nph >>>> + >>>> +bb.nph: ; preds = %entry >>>> + br label %bb >>>> + >>>> +bb: ; preds = %bb.nph, %bb1 >>>> + %indvar = phi i32 [ 0, %bb.nph ], [ %indvar.next, %bb1 ] ; >>>> [#uses=2] >>>> + %argc_addr.04 = add i32 %indvar, %argc ; [#uses=1] >>>> + tail call void (...)* @Test() nounwind >>>> + %1 = add i32 %argc_addr.04, 1 ; [#uses=1] >>>> + br label %bb1 >>>> + >>>> +bb1: ; preds = %bb >>>> + %phitmp = icmp ugt i32 %1, 7 ; [#uses=1] >>>> + %indvar.next = add i32 %indvar, 1 ; [#uses=1] >>>> + br i1 %phitmp, label %bb1.bb2_crit_edge, label %bb >>>> + >>>> +bb1.bb2_crit_edge: ; preds = %bb1 >>>> + br label %bb2 >>>> + >>>> +bb2: ; preds = %bb1.bb2_crit_edge, %entry >>>> + ret i32 0 >>>> +} >>>> + >>>> +declare void @Test(...) >>>> >>>> Added: llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18- >>>> Stride1.ll >>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride1.ll?rev=59528&view=auto >>>> >>>> = >>>> = >>>> = >>>> = >>>> = >>>> = >>>> = >>>> = >>>> = >>>> = >>>> ==================================================================== >>>> --- llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride1.ll >>>> (added) >>>> +++ llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride1.ll >>>> Tue Nov 18 09:10:54 2008 >>>> @@ -0,0 +1,30 @@ >>>> +; RUN: llvm-as < %s | opt -analyze -scalar-evolution |& grep {/u 3} >>>> + >>>> +define i32 @f(i32 %x) nounwind readnone { >>>> +entry: >>>> + %0 = icmp ugt i32 %x, 4 ; [#uses=1] >>>> + br i1 %0, label %bb.nph, label %bb2 >>>> + >>>> +bb.nph: ; preds = %entry >>>> + br label %bb >>>> + >>>> +bb: ; preds = %bb.nph, %bb1 >>>> + %indvar = phi i32 [ 0, %bb.nph ], [ %indvar.next, %bb1 ] ; >>>> [#uses=2] >>>> + %tmp = mul i32 %indvar, -3 ; [#uses=1] >>>> + %x_addr.04 = add i32 %tmp, %x ; [#uses=1] >>>> + %1 = add i32 %x_addr.04, -3 ; [#uses=2] >>>> + br label %bb1 >>>> + >>>> +bb1: ; preds = %bb >>>> + %2 = icmp ugt i32 %1, 4 ; [#uses=1] >>>> + %indvar.next = add i32 %indvar, 1 ; [#uses=1] >>>> + br i1 %2, label %bb, label %bb1.bb2_crit_edge >>>> + >>>> +bb1.bb2_crit_edge: ; preds = %bb1 >>>> + %.lcssa = phi i32 [ %1, %bb1 ] ; [#uses=1] >>>> + br label %bb2 >>>> + >>>> +bb2: ; preds = %bb1.bb2_crit_edge, %entry >>>> + %x_addr.0.lcssa = phi i32 [ %.lcssa, %bb1.bb2_crit_edge ], [ %x, >>>> %entry ] ; [#uses=1] >>>> + ret i32 %x_addr.0.lcssa >>>> +} >>>> >>>> Added: llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18- >>>> Stride2.ll >>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride2.ll?rev=59528&view=auto >>>> >>>> = >>>> = >>>> = >>>> = >>>> = >>>> = >>>> = >>>> = >>>> = >>>> = >>>> ==================================================================== >>>> --- llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride2.ll >>>> (added) >>>> +++ llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride2.ll >>>> Tue Nov 18 09:10:54 2008 >>>> @@ -0,0 +1,30 @@ >>>> +; RUN: llvm-as < %s | opt -analyze -scalar-evolution |& grep {/u 3} >>>> + >>>> +define i32 @f(i32 %x) nounwind readnone { >>>> +entry: >>>> + %0 = icmp ugt i32 %x, 999 ; [#uses=1] >>>> + br i1 %0, label %bb2, label %bb.nph >>>> + >>>> +bb.nph: ; preds = %entry >>>> + br label %bb >>>> + >>>> +bb: ; preds = %bb.nph, %bb1 >>>> + %indvar = phi i32 [ 0, %bb.nph ], [ %indvar.next, %bb1 ] ; >>>> [#uses=2] >>>> + %tmp = mul i32 %indvar, 3 ; [#uses=1] >>>> + %x_addr.04 = add i32 %tmp, %x ; [#uses=1] >>>> + %1 = add i32 %x_addr.04, 3 ; [#uses=2] >>>> + br label %bb1 >>>> + >>>> +bb1: ; preds = %bb >>>> + %2 = icmp ugt i32 %1, 999 ; [#uses=1] >>>> + %indvar.next = add i32 %indvar, 1 ; [#uses=1] >>>> + br i1 %2, label %bb1.bb2_crit_edge, label %bb >>>> + >>>> +bb1.bb2_crit_edge: ; preds = %bb1 >>>> + %.lcssa = phi i32 [ %1, %bb1 ] ; [#uses=1] >>>> + br label %bb2 >>>> + >>>> +bb2: ; preds = %bb1.bb2_crit_edge, %entry >>>> + %x_addr.0.lcssa = phi i32 [ %.lcssa, %bb1.bb2_crit_edge ], [ %x, >>>> %entry ] ; [#uses=1] >>>> + ret i32 %x_addr.0.lcssa >>>> +} >>>> >>>> >>>> _______________________________________________ >>>> llvm-commits mailing list >>>> llvm-commits at cs.uiuc.edu >>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits >>> _______________________________________________ >>> llvm-commits mailing list >>> llvm-commits at cs.uiuc.edu >>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits >>> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From sanjiv.gupta at microchip.com Wed Nov 19 22:52:43 2008 From: sanjiv.gupta at microchip.com (sanjiv gupta) Date: Thu, 20 Nov 2008 10:22:43 +0530 Subject: [llvm-commits] [llvm] r59612 - /llvm/trunk/include/llvm/Intrinsics.td In-Reply-To: <6DCEFC35-FD82-4F89-B1AB-6434042D1B10@apple.com> References: <200811190850.mAJ8oJY4015533@zion.cs.uiuc.edu> <6DCEFC35-FD82-4F89-B1AB-6434042D1B10@apple.com> Message-ID: <1227156763.2966.1.camel@idc-lt-i00171.microchip.com> On Wed, 2008-11-19 at 09:52 -0800, Chris Lattner wrote: > On Nov 19, 2008, at 12:50 AM, Sanjiv Gupta wrote: > > > Author: sgupta > > Date: Wed Nov 19 02:50:17 2008 > > New Revision: 59612 > > > > URL: http://llvm.org/viewvc/llvm-project?rev=59612&view=rev > > Log: > > Int type for PIC16 is i16. Added i16 intrinsics for memmove, memcpy > > and memset. > > hi Sangiv, > > The alignment argument should always be an i32. Note that the i64 > version uses an i32 for the alignment. > Makes sense. I will do that change. > It would also be better to just go ahead and make these intrisnsics > type generic on the size argument, like the ctpop intrinsics etc are. > That would allow memcpy with a size of i42 if someone wanted it :) > Ok. Let me dig more into it. > -Chris > > > > > > > Modified: > > llvm/trunk/include/llvm/Intrinsics.td > > > > Modified: llvm/trunk/include/llvm/Intrinsics.td > > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Intrinsics.td?rev=59612&r1=59611&r2=59612&view=diff > > > > = > > = > > = > > = > > = > > = > > = > > = > > ====================================================================== > > --- llvm/trunk/include/llvm/Intrinsics.td (original) > > +++ llvm/trunk/include/llvm/Intrinsics.td Wed Nov 19 02:50:17 2008 > > @@ -190,18 +190,27 @@ > > // > > > > let Properties = [IntrWriteArgMem] in { > > + def int_memcpy_i16 : Intrinsic<[llvm_void_ty], > > + [llvm_ptr_ty, llvm_ptr_ty, > > + llvm_i16_ty, llvm_i16_ty]>; > > def int_memcpy_i32 : Intrinsic<[llvm_void_ty], > > [llvm_ptr_ty, llvm_ptr_ty, > > llvm_i32_ty, llvm_i32_ty]>; > > def int_memcpy_i64 : Intrinsic<[llvm_void_ty], > > [llvm_ptr_ty, llvm_ptr_ty, > > llvm_i64_ty, llvm_i32_ty]>; > > + def int_memmove_i16 : Intrinsic<[llvm_void_ty], > > + [llvm_ptr_ty, llvm_ptr_ty, > > + llvm_i16_ty, llvm_i16_ty]>; > > def int_memmove_i32 : Intrinsic<[llvm_void_ty], > > [llvm_ptr_ty, llvm_ptr_ty, > > llvm_i32_ty, llvm_i32_ty]>; > > def int_memmove_i64 : Intrinsic<[llvm_void_ty], > > [llvm_ptr_ty, llvm_ptr_ty, > > llvm_i64_ty, llvm_i32_ty]>; > > + def int_memset_i16 : Intrinsic<[llvm_void_ty], > > + [llvm_ptr_ty, llvm_i8_ty, > > + llvm_i16_ty, llvm_i16_ty]>; > > def int_memset_i32 : Intrinsic<[llvm_void_ty], > > [llvm_ptr_ty, llvm_i8_ty, > > llvm_i32_ty, llvm_i32_ty]>; > > > > > > _______________________________________________ > > llvm-commits mailing list > > llvm-commits at cs.uiuc.edu > > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From scottm at aero.org Wed Nov 19 23:01:09 2008 From: scottm at aero.org (Scott Michel) Date: Thu, 20 Nov 2008 05:01:09 -0000 Subject: [llvm-commits] [llvm] r59707 - in /llvm/trunk/lib/Target/CellSPU: AsmPrinter/SPUAsmPrinter.cpp SPUISelLowering.cpp Message-ID: <200811200501.mAK519x1014609@zion.cs.uiuc.edu> Author: pingbak Date: Wed Nov 19 23:01:09 2008 New Revision: 59707 URL: http://llvm.org/viewvc/llvm-project?rev=59707&view=rev Log: CellSPU: Custom lower truncating stores of i8 to i1 (should not have been promote), fix signed conversion of indexed offsets. Modified: llvm/trunk/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp Modified: llvm/trunk/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp?rev=59707&r1=59706&r2=59707&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp Wed Nov 19 23:01:09 2008 @@ -189,9 +189,10 @@ assert(MO.isImm() && "printMemRegImmS10 first operand is not immedate"); int64_t value = int64_t(MI->getOperand(OpNo).getImm()); - assert((value >= -(1 << (9+4)) && value <= (1 << (9+4)) - 1) + int16_t value16 = int16_t(value); + assert((value16 >= -(1 << (9+4)) && value16 <= (1 << (9+4)) - 1) && "Invalid dform s10 offset argument"); - O << value << "("; + O << value16 << "("; printOperand(MI, OpNo+1); O << ")"; } Modified: llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp?rev=59707&r1=59706&r2=59707&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp (original) +++ llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp Wed Nov 19 23:01:09 2008 @@ -134,7 +134,7 @@ setLoadExtAction(ISD::EXTLOAD, MVT::i1, Promote); setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote); setLoadExtAction(ISD::ZEXTLOAD, MVT::i1, Promote); - setTruncStoreAction(MVT::i8, MVT::i1, Promote); + setTruncStoreAction(MVT::i8, MVT::i1, Custom); setTruncStoreAction(MVT::i16, MVT::i1, Custom); setTruncStoreAction(MVT::i32, MVT::i1, Custom); setTruncStoreAction(MVT::i64, MVT::i1, Custom); From sabre at nondot.org Thu Nov 20 01:09:17 2008 From: sabre at nondot.org (Chris Lattner) Date: Thu, 20 Nov 2008 07:09:17 -0000 Subject: [llvm-commits] [llvm] r59715 - /llvm/trunk/include/llvm/ADT/SmallString.h Message-ID: <200811200709.mAK79Hfr021478@zion.cs.uiuc.edu> Author: lattner Date: Thu Nov 20 01:09:17 2008 New Revision: 59715 URL: http://llvm.org/viewvc/llvm-project?rev=59715&view=rev Log: add an operator= to assign to smallstring. Modified: llvm/trunk/include/llvm/ADT/SmallString.h Modified: llvm/trunk/include/llvm/ADT/SmallString.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/SmallString.h?rev=59715&r1=59714&r2=59715&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/SmallString.h (original) +++ llvm/trunk/include/llvm/ADT/SmallString.h Thu Nov 20 01:09:17 2008 @@ -46,6 +46,11 @@ } // Extra operators. + const SmallString &operator=(const char *RHS) { + this->clear(); + return *this += RHS; + } + SmallString &operator+=(const char *RHS) { this->append(RHS, RHS+strlen(RHS)); return *this; From isanbard at gmail.com Thu Nov 20 01:23:34 2008 From: isanbard at gmail.com (Bill Wendling) Date: Thu, 20 Nov 2008 07:23:34 -0000 Subject: [llvm-commits] [llvm] r59717 - /llvm/trunk/include/llvm/Intrinsics.td Message-ID: <200811200723.mAK7NYkB022147@zion.cs.uiuc.edu> Author: void Date: Thu Nov 20 01:23:34 2008 New Revision: 59717 URL: http://llvm.org/viewvc/llvm-project?rev=59717&view=rev Log: Reformatting. No functionality change. Modified: llvm/trunk/include/llvm/Intrinsics.td Modified: llvm/trunk/include/llvm/Intrinsics.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Intrinsics.td?rev=59717&r1=59716&r2=59717&view=diff ============================================================================== --- llvm/trunk/include/llvm/Intrinsics.td (original) +++ llvm/trunk/include/llvm/Intrinsics.td Thu Nov 20 01:23:34 2008 @@ -152,11 +152,14 @@ //===------------------- Garbage Collection Intrinsics --------------------===// // -def int_gcroot : Intrinsic<[llvm_void_ty], [llvm_ptrptr_ty, llvm_ptr_ty]>; -def int_gcread : Intrinsic<[llvm_ptr_ty], [llvm_ptr_ty, llvm_ptrptr_ty], +def int_gcroot : Intrinsic<[llvm_void_ty], + [llvm_ptrptr_ty, llvm_ptr_ty]>; +def int_gcread : Intrinsic<[llvm_ptr_ty], + [llvm_ptr_ty, llvm_ptrptr_ty], [IntrReadArgMem]>; -def int_gcwrite : Intrinsic<[llvm_void_ty], [llvm_ptr_ty, llvm_ptr_ty, - llvm_ptrptr_ty], [IntrWriteArgMem]>; +def int_gcwrite : Intrinsic<[llvm_void_ty], + [llvm_ptr_ty, llvm_ptr_ty, llvm_ptrptr_ty], + [IntrWriteArgMem]>; //===--------------------- Code Generator Intrinsics ----------------------===// // @@ -251,11 +254,11 @@ def int_ctpop: Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>]>; def int_ctlz : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>]>; def int_cttz : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>]>; - def int_part_select : - Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, llvm_i32_ty, llvm_i32_ty]>; - def int_part_set : - Intrinsic<[llvm_anyint_ty], - [LLVMMatchType<0>, llvm_anyint_ty, llvm_i32_ty, llvm_i32_ty]>; + def int_part_select : Intrinsic<[llvm_anyint_ty], + [LLVMMatchType<0>, llvm_i32_ty, llvm_i32_ty]>; + def int_part_set : Intrinsic<[llvm_anyint_ty], + [LLVMMatchType<0>, llvm_anyint_ty, + llvm_i32_ty, llvm_i32_ty]>; } //===------------------------ Debugger Intrinsics -------------------------===// @@ -294,7 +297,7 @@ def int_var_annotation : Intrinsic<[llvm_void_ty], [llvm_ptr_ty, llvm_ptr_ty, llvm_ptr_ty, llvm_i32_ty], - [], "llvm.var.annotation">; + [], "llvm.var.annotation">; def int_ptr_annotation : Intrinsic<[LLVMAnyPointerType], [LLVMMatchType<0>, llvm_ptr_ty, llvm_ptr_ty, llvm_i32_ty], @@ -313,7 +316,8 @@ //===------------------------- Atomic Intrinsics --------------------------===// // -def int_memory_barrier : Intrinsic<[llvm_void_ty], [llvm_i1_ty, llvm_i1_ty, +def int_memory_barrier : Intrinsic<[llvm_void_ty], + [llvm_i1_ty, llvm_i1_ty, llvm_i1_ty, llvm_i1_ty, llvm_i1_ty], []>, GCCBuiltin<"__builtin_llvm_memory_barrier">; From isanbard at gmail.com Thu Nov 20 01:24:30 2008 From: isanbard at gmail.com (Bill Wendling) Date: Thu, 20 Nov 2008 07:24:30 -0000 Subject: [llvm-commits] [llvm] r59718 - /llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Message-ID: <200811200724.mAK7OU3G022192@zion.cs.uiuc.edu> Author: void Date: Thu Nov 20 01:24:30 2008 New Revision: 59718 URL: http://llvm.org/viewvc/llvm-project?rev=59718&view=rev Log: 80-column violation. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp?rev=59718&r1=59717&r2=59718&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Thu Nov 20 01:24:30 2008 @@ -2549,8 +2549,10 @@ // Copy out the selected value(s). for (unsigned i = LinearIndex; i != LinearIndex + NumValValues; ++i) Values[i - LinearIndex] = - OutOfUndef ? DAG.getNode(ISD::UNDEF, Agg.getNode()->getValueType(Agg.getResNo() + i)) : - SDValue(Agg.getNode(), Agg.getResNo() + i); + OutOfUndef ? + DAG.getNode(ISD::UNDEF, + Agg.getNode()->getValueType(Agg.getResNo() + i)) : + SDValue(Agg.getNode(), Agg.getResNo() + i); setValue(&I, DAG.getMergeValues(DAG.getVTList(&ValValueVTs[0], NumValValues), &Values[0], NumValValues)); From tonic at nondot.org Thu Nov 20 01:42:32 2008 From: tonic at nondot.org (Tanya Lattner) Date: Thu, 20 Nov 2008 07:42:32 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r59719 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Message-ID: <200811200742.mAK7gWPX022856@zion.cs.uiuc.edu> Author: tbrethou Date: Thu Nov 20 01:42:31 2008 New Revision: 59719 URL: http://llvm.org/viewvc/llvm-project?rev=59719&view=rev Log: Fix indentation. Cast struct field to i8* before calling intrinsic. Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=59719&r1=59718&r2=59719&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Thu Nov 20 01:42:31 2008 @@ -5991,11 +5991,11 @@ LValue TreeToLLVM::EmitLV_COMPONENT_REF(tree exp) { LValue StructAddrLV = EmitLV(TREE_OPERAND(exp, 0)); tree FieldDecl = TREE_OPERAND(exp, 1); - + assert((TREE_CODE(DECL_CONTEXT(FieldDecl)) == RECORD_TYPE || TREE_CODE(DECL_CONTEXT(FieldDecl)) == UNION_TYPE || TREE_CODE(DECL_CONTEXT(FieldDecl)) == QUAL_UNION_TYPE)); - + // Ensure that the struct type has been converted, so that the fielddecls // are laid out. Note that we convert to the context of the Field, not to the // type of Operand #0, because GCC doesn't always have the field match up with @@ -6004,11 +6004,11 @@ assert((!StructAddrLV.isBitfield() || StructAddrLV.BitStart == 0) && "structs cannot be bitfields!"); - + StructAddrLV.Ptr = BitCastToType(StructAddrLV.Ptr, PointerType::getUnqual(StructTy)); const Type *FieldTy = ConvertType(getDeclaredType(FieldDecl)); - + // BitStart - This is the actual offset of the field from the start of the // struct, in bits. For bitfields this may be on a non-byte boundary. unsigned BitStart = getComponentRefOffsetInBits(exp); @@ -6021,65 +6021,68 @@ assert(MemberIndex < StructTy->getNumContainedTypes() && "Field Idx out of range!"); FieldPtr = Builder.CreateStructGEP(StructAddrLV.Ptr, MemberIndex); - + // Now that we did an offset from the start of the struct, subtract off // the offset from BitStart. if (MemberIndex) { const StructLayout *SL = TD.getStructLayout(cast(StructTy)); BitStart -= SL->getElementOffset(MemberIndex) * 8; } - + // If the FIELD_DECL has an annotate attribute on it, emit it. - + // Handle annotate attribute on global. if (tree AnnotateAttr = lookup_attribute("annotate", DECL_ATTRIBUTES(FieldDecl))) { + + const Type *OrigPtrTy = FieldPtr->getType(); + const Type *SBP = PointerType::getUnqual(Type::Int8Ty); + + Function *Fn = Intrinsic::getDeclaration(TheModule, + Intrinsic::ptr_annotation, + &SBP, 1); + + // Get file and line number. FIXME: Should this be for the decl or the + // use. Is there a location info for the use? + Constant *LineNo = ConstantInt::get(Type::Int32Ty, + DECL_SOURCE_LINE(FieldDecl)); + Constant *File = ConvertMetadataStringToGV(DECL_SOURCE_FILE(FieldDecl)); + + File = TheFolder->CreateBitCast(File, SBP); + + // There may be multiple annotate attributes. Pass return of lookup_attr + // to successive lookups. + while (AnnotateAttr) { + // Each annotate attribute is a tree list. + // Get value of list which is our linked list of args. + tree args = TREE_VALUE(AnnotateAttr); - const Type *OrigPtrTy = FieldPtr->getType(); - - Function *Fn = Intrinsic::getDeclaration(TheModule, - Intrinsic::ptr_annotation, - &OrigPtrTy, 1); - - // Get file and line number. FIXME: Should this be for the decl or the - // use. Is there a location info for the use? - Constant *LineNo = ConstantInt::get(Type::Int32Ty, - DECL_SOURCE_LINE(FieldDecl)); - Constant *File = ConvertMetadataStringToGV(DECL_SOURCE_FILE(FieldDecl)); - const Type *SBP = PointerType::getUnqual(Type::Int8Ty); - File = TheFolder->CreateBitCast(File, SBP); - - // There may be multiple annotate attributes. Pass return of lookup_attr - // to successive lookups. - while (AnnotateAttr) { - // Each annotate attribute is a tree list. - // Get value of list which is our linked list of args. - tree args = TREE_VALUE(AnnotateAttr); - - // Each annotate attribute may have multiple args. - // Treat each arg as if it were a separate annotate attribute. - for (tree a = args; a; a = TREE_CHAIN(a)) { - // Each element of the arg list is a tree list, so get value - tree val = TREE_VALUE(a); - - // Assert its a string, and then get that string. - assert(TREE_CODE(val) == STRING_CST && - "Annotate attribute arg should always be a string"); - - const Type *SBP = PointerType::getUnqual(Type::Int8Ty); - Constant *strGV = TreeConstantToLLVM::EmitLV_STRING_CST(val); - Value *Ops[4] = { - FieldPtr, BitCastToType(strGV, SBP), File, LineNo - }; - - FieldPtr = Builder.CreateCall(Fn, Ops, Ops+4); - } - - // Get next annotate attribute. - AnnotateAttr = TREE_CHAIN(AnnotateAttr); - if (AnnotateAttr) - AnnotateAttr = lookup_attribute("annotate", AnnotateAttr); + // Each annotate attribute may have multiple args. + // Treat each arg as if it were a separate annotate attribute. + for (tree a = args; a; a = TREE_CHAIN(a)) { + // Each element of the arg list is a tree list, so get value + tree val = TREE_VALUE(a); + + // Assert its a string, and then get that string. + assert(TREE_CODE(val) == STRING_CST && + "Annotate attribute arg should always be a string"); + + Constant *strGV = TreeConstantToLLVM::EmitLV_STRING_CST(val); + Value *Ops[4] = { + BitCastToType(FieldPtr, SBP), BitCastToType(strGV, SBP), + File, LineNo + }; + + const Type* FieldPtrType = FieldPtr->getType(); + FieldPtr = Builder.CreateCall(Fn, Ops, Ops+4); + FieldPtr = BitCastToType(FieldPtr, FieldPtrType); } + + // Get next annotate attribute. + AnnotateAttr = TREE_CHAIN(AnnotateAttr); + if (AnnotateAttr) + AnnotateAttr = lookup_attribute("annotate", AnnotateAttr); + } } } else { Value *Offset = Emit(field_offset, 0); From wangmp at apple.com Thu Nov 20 01:48:19 2008 From: wangmp at apple.com (Mon P Wang) Date: Thu, 20 Nov 2008 07:48:19 -0000 Subject: [llvm-commits] [llvm] r59720 - /llvm/trunk/lib/Target/X86/X86CallingConv.td Message-ID: <200811200748.mAK7mJRo023092@zion.cs.uiuc.edu> Author: wangmp Date: Thu Nov 20 01:48:19 2008 New Revision: 59720 URL: http://llvm.org/viewvc/llvm-project?rev=59720&view=rev Log: Allow XMM2 and XMM3 to be used for non ABI compliant code. Modified: llvm/trunk/lib/Target/X86/X86CallingConv.td Modified: llvm/trunk/lib/Target/X86/X86CallingConv.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86CallingConv.td?rev=59720&r1=59719&r2=59720&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86CallingConv.td (original) +++ llvm/trunk/lib/Target/X86/X86CallingConv.td Thu Nov 20 01:48:19 2008 @@ -28,10 +28,11 @@ CCIfType<[i32], CCAssignToReg<[EAX, EDX]>>, CCIfType<[i64], CCAssignToReg<[RAX, RDX]>>, - // Vector types are returned in XMM0 and XMM1, when they fit. If the target - // doesn't have XMM registers, it won't have vector types. + // Vector types are returned in XMM0 and XMM1, when they fit. XMMM2 and XMM3 + // can only be used by ABI non-compliant code. If the target doesn't have XMM + // registers, it won't have vector types. CCIfType<[v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], - CCAssignToReg<[XMM0,XMM1]>>, + CCAssignToReg<[XMM0,XMM1,XMM2,XMM3]>>, // MMX vector types are always returned in MM0. If the target doesn't have // MM0, it doesn't support these vector types. From baldrick at free.fr Thu Nov 20 03:06:15 2008 From: baldrick at free.fr (Duncan Sands) Date: Thu, 20 Nov 2008 10:06:15 +0100 Subject: [llvm-commits] Patch: Widening in LegalizeType In-Reply-To: <78927E77-7EDF-41BD-98E7-4FC8C725E216@apple.com> References: <78927E77-7EDF-41BD-98E7-4FC8C725E216@apple.com> Message-ID: <200811201006.16268.baldrick@free.fr> Hi Mon Ping, > @@ -233,6 +233,11 @@ > JoinIntegers(Lo, Hi)); > return DAG.getNode(ISD::BIT_CONVERT, OutVT, InOp); > } > + case WidenVector: > + if (OutVT.bitsEq(TLI.getWidenVectorType(InVT))) You should be able to use NInVT rather than TLI.getWidenVectorType. That is because TLI.getTypeToTransformTo should return the same thing as TLI.getWidenVectorType (I think TLI.getWidenVectorType should be eliminated; I intend to say more about this in a later email). > + case ISD::SCALAR_TO_VECTOR: Res = ExpandIntOp_SCALAR_TO_VECTOR(N); break; ... > +SDValue DAGTypeLegalizer::ExpandIntOp_SCALAR_TO_VECTOR(SDNode *N) { > + // Create a vector sized/aligned stack slot, store the value to element #0, > + // then load the whole vector back out. > + return CreateStackStoreLoad(N->getOperand(0), N->getValueType(0)); > +} It seems a pity to just give up and use a stack store load. Maybe there are some tricks... How about using BUILD_VECTOR on the expanded pieces? > + case ISD::AND: > + case ISD::OR: > + case ISD::XOR: > + case ISD::ADD: > + case ISD::SUB: > + case ISD::FPOW: > + case ISD::FPOWI: > + case ISD::MUL: > + case ISD::MULHS: > + case ISD::MULHU: > + case ISD::FADD: > + case ISD::FSUB: > + case ISD::FMUL: > + case ISD::SDIV: > + case ISD::SREM: > + case ISD::FDIV: > + case ISD::FREM: > + case ISD::FCOPYSIGN: > + case ISD::UDIV: > + case ISD::UREM: > + case ISD::BSWAP: Res = WidenVecRes_Binary(N); break; Can you please put these in alphabetical order. > +SDValue DAGTypeLegalizer::WidenVecRes_Binary(SDNode *N) { > + // Binary op widening Missing full stop at end of comment. > + MVT WidenVT = TLI.getWidenVectorType(N->getValueType(0)); > + SDValue InOp1 = GetWidenedVector(N->getOperand(0)); > + SDValue InOp2 = GetWidenedVector(N->getOperand(1)); > + assert(InOp1.getValueType() == WidenVT && InOp2.getValueType() == WidenVT); > + return DAG.getNode(N->getOpcode(), WidenVT, InOp1, InOp2); Please eliminate this assert. If you want to do this kind of checking, best to do it systematically in SetWidenedVector. WidenVT can be obtained as the type of InOp1. > +SDValue DAGTypeLegalizer::WidenVecRes_Convert(SDNode *N) { This routine is identical to WidenVecRes_Unary (except for the asserts). These conversions are just unary operations, so please use WidenVecRes_Unary. See below for some more comments. > +SDValue DAGTypeLegalizer::WidenVecRes_Shift(SDNode *N) { > + // Unary op widening > + MVT WidenVT = TLI.getWidenVectorType(N->getValueType(0)); > + SDValue InOp = GetWidenedVector(N->getOperand(0)); > + assert(InOp.getValueType() == WidenVT); I think you should drop this assertion. It can only fail if the original node was invalid (SelectionDAG.cpp should check that the two types are the same - if it doesn't then that should be fixed). That also means that the creation of the new node will assert if the types are different. You can get WidenVT as the type of InOp (more efficient). > +SDValue DAGTypeLegalizer::WidenVecRes_Unary(SDNode *N) { > + // Unary op widening > + MVT WidenVT = TLI.getWidenVectorType(N->getValueType(0)); > + SDValue InOp = GetWidenedVector(N->getOperand(0)); > + assert(InOp.getValueType() == WidenVT); I think you should allow for the case when the operand and result have different vector types. Like FP_TO_UINT. So you should have a more general check here. i.e. I think you should fold WidenVecRes_Convert into this routine. By the way, notice a logical consequence: for this routine to always work, you more or less have to require **that whether a vector is widened or not, and to what width it is widened depends only on the number of elements and not the element type**. So I think it is important to decide whether you want to require this property or not. If not, then the logic for this routine needs to be made more complicated. If you do want to require this property (I think this would be wise) then probably it should be built in fundamentally, in places like TargetLowering. I mean that the underlying routines should only be passed the number of vector elements, and not the element type - that way the above property is necessarily satisfied. > +SDValue DAGTypeLegalizer::WidenVecRes_BIT_CONVERT(SDNode *N) { > + SDValue InOp = N->getOperand(0); > + MVT InVT = InOp.getValueType(); > + MVT VT = N->getValueType(0); > + MVT WidenVT = TLI.getWidenVectorType(VT); Please use TLI.getTypeToTransformTo. This keeps everything uniform with other legalization methods. > + case WidenVector: > + if (WidenVT.bitsEq(TLI.getWidenVectorType(InVT))) Likewise (I won't mention this again). > + // Otherwise, do the convert and then widen. > + SmallVector Ops; > + if (WidenVT.getSizeInBits() % VT.getSizeInBits()) { Isn't this test inverted? > + unsigned NumConcat = WidenVT.getSizeInBits() / VT.getSizeInBits(); > + SDValue UndefVal = DAG.getNode(ISD::UNDEF, VT); > + Ops.push_back(SDValue(N,0)); ^ Isn't this going to lead to an infinite type legalization loop? You can just reuse the node in a different context, you have to change it, you have to make progress towards legalization of N. > + SDValue CvtOp = SDValue(N,0); Likewise. I guess I must be confused since you surely tested this, but I don't see how this can possibly work. Anyway, if I'm not confused then I think you should do the following: case (a). The input is a scalar (i.e. not a vector). Try to use scalar_to_vector to build a vector with the same bitwidth as WidenVT out of InOp. Return a bitconvert of this vector to the WidenVT. This may not always be possible. If not, you may have to go to the stack, see case (b) below. case (b). The input is a vector. Here is where an "extend by undef" operation for vectors would be extremely useful (analogue of scalar_to_vector) :) Lacking that, I suggest you create a stack temporary of the size of WidenVT, store InOp to it, and load it out as WidenVT. That said, there are probably a few cases you can handle more optimally. > + SmallVector NewOps(N->op_begin(), N->op_end()); Since you know the final size, you can reserve space in the vector, to avoid reallocations. > +SDValue DAGTypeLegalizer::WidenVecRes_CONCAT_VECTORS(SDNode *N) { > + // We currently support concatenating a multiple of the incoming vector. We > + // could easily support widening an arbitrary amount using extract/build but > + // I want to see a use case before we do so. I'm not sure I understand this comment. I guess what you are trying to say is that v6i32 = CONCAT(v3i32, v3i32), widens to v8i32, is not supported yet? > + SmallVector Ops; You can reserve space. > + Ops.push_back(SDValue(N,0)); Shouldn't you be pushing back the operands of N?! > + for (unsigned i = 1; i != NumConcat; ++i) { > + Ops.push_back(UndefVal); > + } Shouldn't you be pushing back NumConcat - N->getNumOperands() - 1 copies of undef? Also, the braces {} are redundant. > +SDValue DAGTypeLegalizer::WidenVecRes_CONVERT_RNDSAT(SDNode *N) { I didn't review this function. At this point I got tired and went to bed! I will take a look at the rest some other time. Ciao, Duncan. From baldrick at free.fr Thu Nov 20 03:36:38 2008 From: baldrick at free.fr (Duncan Sands) Date: Thu, 20 Nov 2008 10:36:38 +0100 Subject: [llvm-commits] [llvm] r59648 - /llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp In-Reply-To: <200811191745.mAJHj80C010882@zion.cs.uiuc.edu> References: <200811191745.mAJHj80C010882@zion.cs.uiuc.edu> Message-ID: <200811201036.38364.baldrick@free.fr> Hi Scott, > + setTruncStoreAction(MVT::i8, MVT::i1, Promote); > + setTruncStoreAction(MVT::i16 , MVT::i1, Custom); > + setTruncStoreAction(MVT::i32 , MVT::i1, Custom); > + setTruncStoreAction(MVT::i64 , MVT::i1, Custom); > + setTruncStoreAction(MVT::i128, MVT::i1, Custom); I don't think you need these. In fact I'm fairly sure that they will never even be queried. For extending loads the situation is slightly different: you probably want to set the extending load action to promote (see the comments in LegalizeDAG.cpp, lines 2098 to 2104). Even there you probably only need to set it for the extending load of i1 to i8 case. Ciao, Duncan. From sanjiv.gupta at microchip.com Thu Nov 20 04:21:05 2008 From: sanjiv.gupta at microchip.com (sanjiv gupta) Date: Thu, 20 Nov 2008 15:51:05 +0530 Subject: [llvm-commits] [llvm] r59612 - /llvm/trunk/include/llvm/Intrinsics.td In-Reply-To: <6DCEFC35-FD82-4F89-B1AB-6434042D1B10@apple.com> References: <200811190850.mAJ8oJY4015533@zion.cs.uiuc.edu> <6DCEFC35-FD82-4F89-B1AB-6434042D1B10@apple.com> Message-ID: <1227176465.3373.5.camel@idc-lt-i00171.microchip.com> Please find the attached patch. Let me know if it looks okay. -Sanjiv On Wed, 2008-11-19 at 09:52 -0800, Chris Lattner wrote: > On Nov 19, 2008, at 12:50 AM, Sanjiv Gupta wrote: > > > Author: sgupta > > Date: Wed Nov 19 02:50:17 2008 > > New Revision: 59612 > > > > URL: http://llvm.org/viewvc/llvm-project?rev=59612&view=rev > > Log: > > Int type for PIC16 is i16. Added i16 intrinsics for memmove, memcpy > > and memset. > > hi Sangiv, > > The alignment argument should always be an i32. Note that the i64 > version uses an i32 for the alignment. > > It would also be better to just go ahead and make these intrisnsics > type generic on the size argument, like the ctpop intrinsics etc are. > That would allow memcpy with a size of i42 if someone wanted it :) > > -Chris > > > > > > > Modified: > > llvm/trunk/include/llvm/Intrinsics.td > > > > Modified: llvm/trunk/include/llvm/Intrinsics.td > > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Intrinsics.td?rev=59612&r1=59611&r2=59612&view=diff > > > > = > > = > > = > > = > > = > > = > > = > > = > > ====================================================================== > > --- llvm/trunk/include/llvm/Intrinsics.td (original) > > +++ llvm/trunk/include/llvm/Intrinsics.td Wed Nov 19 02:50:17 2008 > > @@ -190,18 +190,27 @@ > > // > > > > let Properties = [IntrWriteArgMem] in { > > + def int_memcpy_i16 : Intrinsic<[llvm_void_ty], > > + [llvm_ptr_ty, llvm_ptr_ty, > > + llvm_i16_ty, llvm_i16_ty]>; > > def int_memcpy_i32 : Intrinsic<[llvm_void_ty], > > [llvm_ptr_ty, llvm_ptr_ty, > > llvm_i32_ty, llvm_i32_ty]>; > > def int_memcpy_i64 : Intrinsic<[llvm_void_ty], > > [llvm_ptr_ty, llvm_ptr_ty, > > llvm_i64_ty, llvm_i32_ty]>; > > + def int_memmove_i16 : Intrinsic<[llvm_void_ty], > > + [llvm_ptr_ty, llvm_ptr_ty, > > + llvm_i16_ty, llvm_i16_ty]>; > > def int_memmove_i32 : Intrinsic<[llvm_void_ty], > > [llvm_ptr_ty, llvm_ptr_ty, > > llvm_i32_ty, llvm_i32_ty]>; > > def int_memmove_i64 : Intrinsic<[llvm_void_ty], > > [llvm_ptr_ty, llvm_ptr_ty, > > llvm_i64_ty, llvm_i32_ty]>; > > + def int_memset_i16 : Intrinsic<[llvm_void_ty], > > + [llvm_ptr_ty, llvm_i8_ty, > > + llvm_i16_ty, llvm_i16_ty]>; > > def int_memset_i32 : Intrinsic<[llvm_void_ty], > > [llvm_ptr_ty, llvm_i8_ty, > > llvm_i32_ty, llvm_i32_ty]>; > > > > > > _______________________________________________ > > llvm-commits mailing list > > llvm-commits at cs.uiuc.edu > > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > -------------- next part -------------- A non-text attachment was scrubbed... Name: patch-MemIntrinsics.txt Type: text/x-patch Size: 16370 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20081120/9eb44348/attachment.bin From baldrick at free.fr Thu Nov 20 04:34:44 2008 From: baldrick at free.fr (Duncan Sands) Date: Thu, 20 Nov 2008 10:34:44 -0000 Subject: [llvm-commits] [llvm] r59727 - /llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h Message-ID: <200811201034.mAKAYi1f010118@zion.cs.uiuc.edu> Author: baldrick Date: Thu Nov 20 04:34:43 2008 New Revision: 59727 URL: http://llvm.org/viewvc/llvm-project?rev=59727&view=rev Log: Add some documentation. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h?rev=59727&r1=59726&r2=59727&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h Thu Nov 20 04:34:43 2008 @@ -206,7 +206,7 @@ //===--------------------------------------------------------------------===// /// GetPromotedInteger - Given a processed operand Op which was promoted to a - /// larger integer type, this returns the promoted value. The bits of the + /// larger integer type, this returns the promoted value. The low bits of the /// promoted value corresponding to the original type are exactly equal to Op. /// The extra bits contain rubbish, so the promoted value may need to be zero- /// or sign-extended from the original type before it is usable (the helpers @@ -297,6 +297,12 @@ // Integer Expansion Support: LegalizeIntegerTypes.cpp //===--------------------------------------------------------------------===// + /// GetExpandedInteger - Given a processed operand Op which was expanded into + /// two integers of half the size, this returns the two halves. The low bits + /// of Op are exactly equal to the bits of Lo; the high bits exactly equal Hi. + /// For example, if Op is an i64 which was expanded into two i32's, then this + /// method returns the two i32's, with Lo being equal to the lower 32 bits of + /// Op, and Hi being equal to the upper 32 bits. void GetExpandedInteger(SDValue Op, SDValue &Lo, SDValue &Hi); void SetExpandedInteger(SDValue Op, SDValue Lo, SDValue Hi); @@ -353,6 +359,11 @@ // Float to Integer Conversion Support: LegalizeFloatTypes.cpp //===--------------------------------------------------------------------===// + /// GetSoftenedFloat - Given a processed operand Op which was converted to an + /// integer of the same size, this returns the integer. The integer contains + /// exactly the same bits as Op - only the type changed. For example, if Op + /// is an f32 which was softened to an i32, then this method returns an i32, + /// the bits of which coincide with those of Op. SDValue GetSoftenedFloat(SDValue Op) { SDValue &SoftenedOp = SoftenedFloats[Op]; RemapValue(SoftenedOp); @@ -413,6 +424,12 @@ // Float Expansion Support: LegalizeFloatTypes.cpp //===--------------------------------------------------------------------===// + /// GetExpandedFloat - Given a processed operand Op which was expanded into + /// two floating point values of half the size, this returns the two halves. + /// The low bits of Op are exactly equal to the bits of Lo; the high bits + /// exactly equal Hi. For example, if Op is a ppcf128 which was expanded + /// into two f64's, then this method returns the two f64's, with Lo being + /// equal to the lower 64 bits of Op, and Hi to the upper 64 bits. void GetExpandedFloat(SDValue Op, SDValue &Lo, SDValue &Hi); void SetExpandedFloat(SDValue Op, SDValue Lo, SDValue Hi); @@ -461,6 +478,9 @@ // Scalarization Support: LegalizeVectorTypes.cpp //===--------------------------------------------------------------------===// + /// GetScalarizedVector - Given a processed one-element vector Op which was + /// scalarized to its element type, this returns the element. For example, + /// if Op is a v1i32, Op = < i32 val >, this method returns val, an i32. SDValue GetScalarizedVector(SDValue Op) { SDValue &ScalarizedOp = ScalarizedVectors[Op]; RemapValue(ScalarizedOp); @@ -498,6 +518,13 @@ // Vector Splitting Support: LegalizeVectorTypes.cpp //===--------------------------------------------------------------------===// + /// GetSplitVector - Given a processed vector Op which was split into smaller + /// vectors, this method returns the smaller vectors. The first elements of + /// Op coincide with the elements of Lo; the remaining elements of Op coincide + /// with the elements of Hi: Op is what you would get by concatenating Lo and + /// Hi. For example, if Op is a v8i32 that was split into two v4i32's, then + /// this method returns the two v4i32's, with Lo corresponding to the first 4 + /// elements of Op, and Hi to the last 4 elements. void GetSplitVector(SDValue Op, SDValue &Lo, SDValue &Hi); void SetSplitVector(SDValue Op, SDValue Lo, SDValue Hi); From sanjiv.gupta at microchip.com Thu Nov 20 05:45:28 2008 From: sanjiv.gupta at microchip.com (sanjiv gupta) Date: Thu, 20 Nov 2008 17:15:28 +0530 Subject: [llvm-commits] [llvm] r59612 - /llvm/trunk/include/llvm/Intrinsics.td In-Reply-To: <1227176465.3373.5.camel@idc-lt-i00171.microchip.com> References: <200811190850.mAJ8oJY4015533@zion.cs.uiuc.edu> <6DCEFC35-FD82-4F89-B1AB-6434042D1B10@apple.com> <1227176465.3373.5.camel@idc-lt-i00171.microchip.com> Message-ID: <1227181528.3373.11.camel@idc-lt-i00171.microchip.com> I just ran the dejagnu tests. opt is failing in getDeclaration () for these intrinsics. In Intrinsics.gen the Tys[0] being passed is NULL, so it SEGV there. Any idea where things are going wrong? case Intrinsic::memset: // llvm.memset ResultTy = Type::VoidTy; ArgTys.push_back(PointerType::getUnqual(IntegerType::get(8))); ArgTys.push_back(IntegerType::get(8)); ArgTys.push_back(Tys[0]); ArgTys.push_back(IntegerType::get(32)); break; On Thu, 2008-11-20 at 15:51 +0530, sanjiv gupta wrote: > Please find the attached patch. Let me know if it looks okay. > > -Sanjiv > > On Wed, 2008-11-19 at 09:52 -0800, Chris Lattner wrote: > > On Nov 19, 2008, at 12:50 AM, Sanjiv Gupta wrote: > > > > > Author: sgupta > > > Date: Wed Nov 19 02:50:17 2008 > > > New Revision: 59612 > > > > > > URL: http://llvm.org/viewvc/llvm-project?rev=59612&view=rev > > > Log: > > > Int type for PIC16 is i16. Added i16 intrinsics for memmove, memcpy > > > and memset. > > > > hi Sangiv, > > > > The alignment argument should always be an i32. Note that the i64 > > version uses an i32 for the alignment. > > > > It would also be better to just go ahead and make these intrisnsics > > type generic on the size argument, like the ctpop intrinsics etc are. > > That would allow memcpy with a size of i42 if someone wanted it :) > > > > -Chris > > > > > > > > > > > Modified: > > > llvm/trunk/include/llvm/Intrinsics.td > > > > > > Modified: llvm/trunk/include/llvm/Intrinsics.td > > > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Intrinsics.td?rev=59612&r1=59611&r2=59612&view=diff > > > > > > = > > > = > > > = > > > = > > > = > > > = > > > = > > > = > > > ====================================================================== > > > --- llvm/trunk/include/llvm/Intrinsics.td (original) > > > +++ llvm/trunk/include/llvm/Intrinsics.td Wed Nov 19 02:50:17 2008 > > > @@ -190,18 +190,27 @@ > > > // > > > > > > let Properties = [IntrWriteArgMem] in { > > > + def int_memcpy_i16 : Intrinsic<[llvm_void_ty], > > > + [llvm_ptr_ty, llvm_ptr_ty, > > > + llvm_i16_ty, llvm_i16_ty]>; > > > def int_memcpy_i32 : Intrinsic<[llvm_void_ty], > > > [llvm_ptr_ty, llvm_ptr_ty, > > > llvm_i32_ty, llvm_i32_ty]>; > > > def int_memcpy_i64 : Intrinsic<[llvm_void_ty], > > > [llvm_ptr_ty, llvm_ptr_ty, > > > llvm_i64_ty, llvm_i32_ty]>; > > > + def int_memmove_i16 : Intrinsic<[llvm_void_ty], > > > + [llvm_ptr_ty, llvm_ptr_ty, > > > + llvm_i16_ty, llvm_i16_ty]>; > > > def int_memmove_i32 : Intrinsic<[llvm_void_ty], > > > [llvm_ptr_ty, llvm_ptr_ty, > > > llvm_i32_ty, llvm_i32_ty]>; > > > def int_memmove_i64 : Intrinsic<[llvm_void_ty], > > > [llvm_ptr_ty, llvm_ptr_ty, > > > llvm_i64_ty, llvm_i32_ty]>; > > > + def int_memset_i16 : Intrinsic<[llvm_void_ty], > > > + [llvm_ptr_ty, llvm_i8_ty, > > > + llvm_i16_ty, llvm_i16_ty]>; > > > def int_memset_i32 : Intrinsic<[llvm_void_ty], > > > [llvm_ptr_ty, llvm_i8_ty, > > > llvm_i32_ty, llvm_i32_ty]>; > > > > > > > > > _______________________________________________ > > > llvm-commits mailing list > > > llvm-commits at cs.uiuc.edu > > > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From scottm at aero.org Thu Nov 20 10:36:33 2008 From: scottm at aero.org (Scott Michel) Date: Thu, 20 Nov 2008 16:36:33 -0000 Subject: [llvm-commits] [llvm] r59734 - in /llvm/trunk/lib/Target/CellSPU: SPUAsmPrinter.cpp SPUISelLowering.cpp Message-ID: <200811201636.mAKGaX93028216@zion.cs.uiuc.edu> Author: pingbak Date: Thu Nov 20 10:36:33 2008 New Revision: 59734 URL: http://llvm.org/viewvc/llvm-project?rev=59734&view=rev Log: CellSPU: (a) Remove moved file (SPUAsmPrinter.cpp) to make svn happy. (b) Remove truncated stores that will never be used. (c) Add initial support for __muldi3 as a libcall. Removed: llvm/trunk/lib/Target/CellSPU/SPUAsmPrinter.cpp Modified: llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp Removed: llvm/trunk/lib/Target/CellSPU/SPUAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUAsmPrinter.cpp?rev=59733&view=auto ============================================================================== (empty) Modified: llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp?rev=59734&r1=59733&r2=59734&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp (original) +++ llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp Thu Nov 20 10:36:33 2008 @@ -130,15 +130,13 @@ addRegisterClass(MVT::f64, SPU::R64FPRegisterClass); addRegisterClass(MVT::i128, SPU::GPRCRegisterClass); + // Initialize libcalls: + setLibcallName(RTLIB::MUL_I64, "__muldi3"); + // SPU has no sign or zero extended loads for i1, i8, i16: setLoadExtAction(ISD::EXTLOAD, MVT::i1, Promote); setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote); setLoadExtAction(ISD::ZEXTLOAD, MVT::i1, Promote); - setTruncStoreAction(MVT::i8, MVT::i1, Custom); - setTruncStoreAction(MVT::i16, MVT::i1, Custom); - setTruncStoreAction(MVT::i32, MVT::i1, Custom); - setTruncStoreAction(MVT::i64, MVT::i1, Custom); - setTruncStoreAction(MVT::i128, MVT::i1, Custom); setLoadExtAction(ISD::EXTLOAD, MVT::i8, Custom); setLoadExtAction(ISD::SEXTLOAD, MVT::i8, Custom); @@ -212,6 +210,7 @@ setOperationAction(ISD::ROTL, MVT::i32, Legal); setOperationAction(ISD::ROTL, MVT::i16, Legal); setOperationAction(ISD::ROTL, MVT::i8, Custom); + // SPU has no native version of shift left/right for i8 setOperationAction(ISD::SHL, MVT::i8, Custom); setOperationAction(ISD::SRL, MVT::i8, Custom); @@ -224,7 +223,7 @@ // Custom lower i8, i32 and i64 multiplications setOperationAction(ISD::MUL, MVT::i8, Custom); setOperationAction(ISD::MUL, MVT::i32, Custom); - setOperationAction(ISD::MUL, MVT::i64, Custom); + setOperationAction(ISD::MUL, MVT::i64, Expand); // Need to custom handle (some) common i8, i64 math ops setOperationAction(ISD::ADD, MVT::i64, Custom); From echeng at apple.com Thu Nov 20 10:54:32 2008 From: echeng at apple.com (Evan Cheng) Date: Thu, 20 Nov 2008 08:54:32 -0800 Subject: [llvm-commits] [llvm] r59528 - in /llvm/trunk: lib/Analysis/ScalarEvolution.cpp test/Analysis/ScalarEvolution/2008-11-18-LessThanOrEqual.ll test/Analysis/ScalarEvolution/2008-11-18-Stride1.ll test/Analysis/ScalarEvolution/2008-11-18-Stride2.ll In-Reply-To: <4924EA65.5050300@mxc.ca> References: <200811181510.mAIFAtVS001882@zion.cs.uiuc.edu> <4C90C36A-77D6-4006-9F3F-19002F2E561A@apple.com> <49238A20.3010803@mxc.ca> <520D57A2-6CB1-48F1-B5DB-9523121F3058@apple.com> <4924EA65.5050300@mxc.ca> Message-ID: Ah ok. Thanks. Evan On Nov 19, 2008, at 8:41 PM, Nick Lewycky wrote: > Evan Cheng wrote: >> On Nov 18, 2008, at 7:38 PM, Nick Lewycky wrote: >> >>> Evan Cheng wrote: >>>> Hi Nicholas, >>>> >>>> What does "trueWhenEqual" mean? Should it default to true / false? >>> Like isSigned, it defines whether the comparison is true when equal, >>> ie., it's an SLT/ULT vs. SLE/ULE. There is no default, but the old >>> version only knew how to handle trueWhenEqual=false (ie., SLT/ULT). >> >> Can you make the default false? That way old code that use it (which >> may not be part of the tree) won't have to change. > > These are all private methods in the ScalarEvolutionsImpl class (which > is VISIBILITY_HIDDEN in an anonymous namespace). The public > interface in > llvm/include/Analysis/ScalarEvolution.h hasn't changed. > > Nick > >> Thanks, >> >> Evan >> >>> >>> Nick >>> >>>> Thanks, >>>> >>>> Evan >>>> >>>> On Nov 18, 2008, at 7:10 AM, Nick Lewycky wrote: >>>> >>>>> Author: nicholas >>>>> Date: Tue Nov 18 09:10:54 2008 >>>>> New Revision: 59528 >>>>> >>>>> URL: http://llvm.org/viewvc/llvm-project?rev=59528&view=rev >>>>> Log: >>>>> Add a utility function that detects whether a loop is guaranteed >>>>> to >>>>> be finite. >>>>> >>>>> Use it to safely handle less-than-or-equals-to exit conditions in >>>>> loops. These >>>>> also occur when the loop exit branch is exit on true because SCEV >>>>> inverses the >>>>> icmp predicate. >>>>> >>>>> Use it again to handle non-zero strides, but only with an unsigned >>>>> comparison >>>>> in the exit condition. >>>>> >>>>> Added: >>>>> llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18- >>>>> LessThanOrEqual.ll >>>>> llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride1.ll >>>>> llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride2.ll >>>>> Modified: >>>>> llvm/trunk/lib/Analysis/ScalarEvolution.cpp >>>>> >>>>> Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp >>>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=59528&r1=59527&r2=59528&view=diff >>>>> >>>>> = >>>>> = >>>>> = >>>>> = >>>>> = >>>>> = >>>>> = >>>>> = >>>>> = >>>>> = >>>>> = >>>>> = >>>>> ================================================================== >>>>> --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original) >>>>> +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Tue Nov 18 >>>>> 09:10:54 >>>>> 2008 >>>>> @@ -1477,7 +1477,7 @@ >>>>> /// specified less-than comparison will execute. If not >>>>> computable, return >>>>> /// UnknownValue. isSigned specifies whether the less-than is >>>>> signed. >>>>> SCEVHandle HowManyLessThans(SCEV *LHS, SCEV *RHS, const Loop *L, >>>>> - bool isSigned); >>>>> + bool isSigned, bool >>>>> trueWhenEqual); >>>>> >>>>> /// getPredecessorWithUniqueSuccessorForBB - Return a >>>>> predecessor of BB >>>>> /// (which may not be an immediate predecessor) which has >>>>> exactly one >>>>> @@ -1487,7 +1487,13 @@ >>>>> >>>>> /// executesAtLeastOnce - Test whether entry to the loop is >>>>> protected by >>>>> /// a conditional between LHS and RHS. >>>>> - bool executesAtLeastOnce(const Loop *L, bool isSigned, SCEV >>>>> *LHS, SCEV *RHS); >>>>> + bool executesAtLeastOnce(const Loop *L, bool isSigned, bool >>>>> trueWhenEqual, >>>>> + SCEV *LHS, SCEV *RHS); >>>>> + >>>>> + /// potentialInfiniteLoop - Test whether the loop might jump >>>>> over the exit value >>>>> + /// due to wrapping. >>>>> + bool potentialInfiniteLoop(SCEV *Stride, SCEV *RHS, bool >>>>> isSigned, >>>>> + bool trueWhenEqual); >>>>> >>>>> /// getConstantEvolutionLoopExitValue - If we know that the >>>>> specified Phi is >>>>> /// in the header of its containing loop, we know the loop >>>>> executes a >>>>> @@ -2025,24 +2031,46 @@ >>>>> break; >>>>> } >>>>> case ICmpInst::ICMP_SLT: { >>>>> - SCEVHandle TC = HowManyLessThans(LHS, RHS, L, true); >>>>> + SCEVHandle TC = HowManyLessThans(LHS, RHS, L, true, false); >>>>> if (!isa(TC)) return TC; >>>>> break; >>>>> } >>>>> case ICmpInst::ICMP_SGT: { >>>>> SCEVHandle TC = HowManyLessThans(SE.getNotSCEV(LHS), >>>>> - SE.getNotSCEV(RHS), L, >>>>> true); >>>>> + SE.getNotSCEV(RHS), L, true, >>>>> false); >>>>> if (!isa(TC)) return TC; >>>>> break; >>>>> } >>>>> case ICmpInst::ICMP_ULT: { >>>>> - SCEVHandle TC = HowManyLessThans(LHS, RHS, L, false); >>>>> + SCEVHandle TC = HowManyLessThans(LHS, RHS, L, false, false); >>>>> if (!isa(TC)) return TC; >>>>> break; >>>>> } >>>>> case ICmpInst::ICMP_UGT: { >>>>> SCEVHandle TC = HowManyLessThans(SE.getNotSCEV(LHS), >>>>> - SE.getNotSCEV(RHS), L, >>>>> false); >>>>> + SE.getNotSCEV(RHS), L, >>>>> false, >>>>> false); >>>>> + if (!isa(TC)) return TC; >>>>> + break; >>>>> + } >>>>> + case ICmpInst::ICMP_SLE: { >>>>> + SCEVHandle TC = HowManyLessThans(LHS, RHS, L, true, true); >>>>> + if (!isa(TC)) return TC; >>>>> + break; >>>>> + } >>>>> + case ICmpInst::ICMP_SGE: { >>>>> + SCEVHandle TC = HowManyLessThans(SE.getNotSCEV(LHS), >>>>> + SE.getNotSCEV(RHS), L, true, >>>>> true); >>>>> + if (!isa(TC)) return TC; >>>>> + break; >>>>> + } >>>>> + case ICmpInst::ICMP_ULE: { >>>>> + SCEVHandle TC = HowManyLessThans(LHS, RHS, L, false, true); >>>>> + if (!isa(TC)) return TC; >>>>> + break; >>>>> + } >>>>> + case ICmpInst::ICMP_UGE: { >>>>> + SCEVHandle TC = HowManyLessThans(SE.getNotSCEV(LHS), >>>>> + SE.getNotSCEV(RHS), L, >>>>> false, >>>>> true); >>>>> if (!isa(TC)) return TC; >>>>> break; >>>>> } >>>>> @@ -2738,6 +2766,7 @@ >>>>> /// executesAtLeastOnce - Test whether entry to the loop is >>>>> protected by >>>>> /// a conditional between LHS and RHS. >>>>> bool ScalarEvolutionsImpl::executesAtLeastOnce(const Loop *L, bool >>>>> isSigned, >>>>> + bool >>>>> trueWhenEqual, >>>>> SCEV *LHS, SCEV >>>>> *RHS) { >>>>> BasicBlock *Preheader = L->getLoopPreheader(); >>>>> BasicBlock *PreheaderDest = L->getHeader(); >>>>> @@ -2770,20 +2799,36 @@ >>>>> >>>>> switch (Cond) { >>>>> case ICmpInst::ICMP_UGT: >>>>> - if (isSigned) continue; >>>>> + if (isSigned || trueWhenEqual) continue; >>>>> std::swap(PreCondLHS, PreCondRHS); >>>>> Cond = ICmpInst::ICMP_ULT; >>>>> break; >>>>> case ICmpInst::ICMP_SGT: >>>>> - if (!isSigned) continue; >>>>> + if (!isSigned || trueWhenEqual) continue; >>>>> std::swap(PreCondLHS, PreCondRHS); >>>>> Cond = ICmpInst::ICMP_SLT; >>>>> break; >>>>> case ICmpInst::ICMP_ULT: >>>>> - if (isSigned) continue; >>>>> + if (isSigned || trueWhenEqual) continue; >>>>> break; >>>>> case ICmpInst::ICMP_SLT: >>>>> - if (!isSigned) continue; >>>>> + if (!isSigned || trueWhenEqual) continue; >>>>> + break; >>>>> + case ICmpInst::ICMP_UGE: >>>>> + if (isSigned || !trueWhenEqual) continue; >>>>> + std::swap(PreCondLHS, PreCondRHS); >>>>> + Cond = ICmpInst::ICMP_ULE; >>>>> + break; >>>>> + case ICmpInst::ICMP_SGE: >>>>> + if (!isSigned || !trueWhenEqual) continue; >>>>> + std::swap(PreCondLHS, PreCondRHS); >>>>> + Cond = ICmpInst::ICMP_SLE; >>>>> + break; >>>>> + case ICmpInst::ICMP_ULE: >>>>> + if (isSigned || !trueWhenEqual) continue; >>>>> + break; >>>>> + case ICmpInst::ICMP_SLE: >>>>> + if (!isSigned || !trueWhenEqual) continue; >>>>> break; >>>>> default: >>>>> continue; >>>>> @@ -2802,11 +2847,46 @@ >>>>> return false; >>>>> } >>>>> >>>>> +/// potentialInfiniteLoop - Test whether the loop might jump over >>>>> the exit value >>>>> +/// due to wrapping around 2^n. >>>>> +bool ScalarEvolutionsImpl::potentialInfiniteLoop(SCEV *Stride, >>>>> SCEV >>>>> *RHS, >>>>> + bool isSigned, >>>>> bool trueWhenEqual) { >>>>> + // Return true when the distance from RHS to maxint > Stride. >>>>> + >>>>> + if (!isa(Stride)) >>>>> + return true; >>>>> + SCEVConstant *SC = cast(Stride); >>>>> + >>>>> + if (SC->getValue()->isZero()) >>>>> + return true; >>>>> + if (!trueWhenEqual && SC->getValue()->isOne()) >>>>> + return false; >>>>> + >>>>> + if (!isa(RHS)) >>>>> + return true; >>>>> + SCEVConstant *R = cast(RHS); >>>>> + >>>>> + if (isSigned) >>>>> + return true; // XXX: because we don't have an sdiv scev. >>>>> + >>>>> + // If negative, it wraps around every iteration, but we don't >>>>> care about that. >>>>> + APInt S = SC->getValue()->getValue().abs(); >>>>> + >>>>> + APInt Dist = APInt::getMaxValue(R->getValue()->getBitWidth()) - >>>>> + R->getValue()->getValue(); >>>>> + >>>>> + if (trueWhenEqual) >>>>> + return !S.ult(Dist); >>>>> + else >>>>> + return !S.ule(Dist); >>>>> +} >>>>> + >>>>> /// HowManyLessThans - Return the number of times a backedge >>>>> containing the >>>>> /// specified less-than comparison will execute. If not >>>>> computable, >>>>> return >>>>> /// UnknownValue. >>>>> SCEVHandle ScalarEvolutionsImpl:: >>>>> -HowManyLessThans(SCEV *LHS, SCEV *RHS, const Loop *L, bool >>>>> isSigned) { >>>>> +HowManyLessThans(SCEV *LHS, SCEV *RHS, const Loop *L, >>>>> + bool isSigned, bool trueWhenEqual) { >>>>> // Only handle: "ADDREC < LoopInvariant". >>>>> if (!RHS->isLoopInvariant(L)) return UnknownValue; >>>>> >>>>> @@ -2815,34 +2895,50 @@ >>>>> return UnknownValue; >>>>> >>>>> if (AddRec->isAffine()) { >>>>> - // FORNOW: We only support unit strides. >>>>> - SCEVHandle One = SE.getIntegerSCEV(1, RHS->getType()); >>>>> - if (AddRec->getOperand(1) != One) >>>>> + SCEVHandle Stride = AddRec->getOperand(1); >>>>> + if (potentialInfiniteLoop(Stride, RHS, isSigned, >>>>> trueWhenEqual)) >>>>> return UnknownValue; >>>>> >>>>> - // We know the LHS is of the form {n,+,1} and the RHS is some >>>>> loop-invariant >>>>> - // m. So, we count the number of iterations in which {n,+, >>>>> 1} < >>>>> m is true. >>>>> - // Note that we cannot simply return max(m-n,0) because it's >>>>> not safe to >>>>> + // We know the LHS is of the form {n,+,s} and the RHS is some >>>>> loop-invariant >>>>> + // m. So, we count the number of iterations in which {n, >>>>> +,s} < >>>>> m is true. >>>>> + // Note that we cannot simply return max(m-n,0)/s because >>>>> it's >>>>> not safe to >>>>> // treat m-n as signed nor unsigned due to overflow possibility. >>>>> >>>>> // First, we get the value of the LHS in the first iteration: n >>>>> SCEVHandle Start = AddRec->getOperand(0); >>>>> >>>>> - if (executesAtLeastOnce(L, isSigned, >>>>> - SE.getMinusSCEV(AddRec- >>>>> >getOperand(0), >>>>> One), RHS)) { >>>>> - // Since we know that the condition is true in order to >>>>> enter >>>>> the loop, >>>>> - // we know that it will run exactly m-n times. >>>>> - return SE.getMinusSCEV(RHS, Start); >>>>> - } else { >>>>> - // Then, we get the value of the LHS in the first iteration >>>>> in which the >>>>> - // above condition doesn't hold. This equals to max(m,n). >>>>> - SCEVHandle End = isSigned ? SE.getSMaxExpr(RHS, Start) >>>>> - : SE.getUMaxExpr(RHS, Start); >>>>> - >>>>> - // Finally, we subtract these two values to get the >>>>> number of >>>>> times the >>>>> - // backedge is executed: max(m,n)-n. >>>>> - return SE.getMinusSCEV(End, Start); >>>>> + SCEVHandle One = SE.getIntegerSCEV(1, RHS->getType()); >>>>> + >>>>> + // Assuming that the loop will run at least once, we know >>>>> that >>>>> it will >>>>> + // run (m-n)/s times. >>>>> + SCEVHandle End = RHS; >>>>> + >>>>> + if (!executesAtLeastOnce(L, isSigned, trueWhenEqual, >>>>> + SE.getMinusSCEV(Start, One), RHS)) { >>>>> + // If not, we get the value of the LHS in the first >>>>> iteration >>>>> in which >>>>> + // the above condition doesn't hold. This equals to >>>>> max(m,n). >>>>> + End = isSigned ? SE.getSMaxExpr(RHS, Start) >>>>> + : SE.getUMaxExpr(RHS, Start); >>>>> } >>>>> + >>>>> + // If the expression is less-than-or-equal to, we need to >>>>> extend the >>>>> + // loop by one iteration. >>>>> + // >>>>> + // The loop won't actually run (m-n)/s times because the loop >>>>> iterations >>>>> + // won't divide evenly. For example, if you have {2,+,5} u< >>>>> 10 >>>>> the >>>>> + // division would equal one, but the loop runs twice putting >>>>> the >>>>> + // induction variable at 12. >>>>> + >>>>> + if (!trueWhenEqual) >>>>> + // (Stride - 1) is correct only because we know it's >>>>> unsigned. >>>>> + // What we really want is to decrease the magnitude of >>>>> Stride >>>>> by one. >>>>> + Start = SE.getMinusSCEV(Start, SE.getMinusSCEV(Stride, >>>>> One)); >>>>> + else >>>>> + Start = SE.getMinusSCEV(Start, Stride); >>>>> + >>>>> + // Finally, we subtract these two values to get the number of >>>>> times the >>>>> + // backedge is executed: max(m,n)-n. >>>>> + return SE.getUDivExpr(SE.getMinusSCEV(End, Start), Stride); >>>>> } >>>>> >>>>> return UnknownValue; >>>>> >>>>> Added: llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18- >>>>> LessThanOrEqual.ll >>>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-LessThanOrEqual.ll?rev=59528&view=auto >>>>> >>>>> = >>>>> = >>>>> = >>>>> = >>>>> = >>>>> = >>>>> = >>>>> = >>>>> = >>>>> = >>>>> = >>>>> = >>>>> ================================================================== >>>>> --- llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18- >>>>> LessThanOrEqual.ll (added) >>>>> +++ llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18- >>>>> LessThanOrEqual.ll Tue Nov 18 09:10:54 2008 >>>>> @@ -0,0 +1,31 @@ >>>>> +; RUN: llvm-as < %s | opt -analyze -scalar-evolution |& \ >>>>> +; RUN: grep {Loop bb: (7 + (-1 \\* %argc)) iterations!} >>>>> + >>>>> +define i32 @main(i32 %argc, i8** %argv) nounwind { >>>>> +entry: >>>>> + %0 = icmp ugt i32 %argc, 7 ; [#uses=1] >>>>> + br i1 %0, label %bb2, label %bb.nph >>>>> + >>>>> +bb.nph: ; preds = %entry >>>>> + br label %bb >>>>> + >>>>> +bb: ; preds = %bb.nph, %bb1 >>>>> + %indvar = phi i32 [ 0, %bb.nph ], [ %indvar.next, %bb1 ] ; >>>>> >>>>> [#uses=2] >>>>> + %argc_addr.04 = add i32 %indvar, %argc ; [#uses=1] >>>>> + tail call void (...)* @Test() nounwind >>>>> + %1 = add i32 %argc_addr.04, 1 ; [#uses=1] >>>>> + br label %bb1 >>>>> + >>>>> +bb1: ; preds = %bb >>>>> + %phitmp = icmp ugt i32 %1, 7 ; [#uses=1] >>>>> + %indvar.next = add i32 %indvar, 1 ; [#uses=1] >>>>> + br i1 %phitmp, label %bb1.bb2_crit_edge, label %bb >>>>> + >>>>> +bb1.bb2_crit_edge: ; preds = %bb1 >>>>> + br label %bb2 >>>>> + >>>>> +bb2: ; preds = %bb1.bb2_crit_edge, %entry >>>>> + ret i32 0 >>>>> +} >>>>> + >>>>> +declare void @Test(...) >>>>> >>>>> Added: llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18- >>>>> Stride1.ll >>>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride1.ll?rev=59528&view=auto >>>>> >>>>> = >>>>> = >>>>> = >>>>> = >>>>> = >>>>> = >>>>> = >>>>> = >>>>> = >>>>> = >>>>> = >>>>> = >>>>> ================================================================== >>>>> --- llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride1.ll >>>>> (added) >>>>> +++ llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride1.ll >>>>> Tue Nov 18 09:10:54 2008 >>>>> @@ -0,0 +1,30 @@ >>>>> +; RUN: llvm-as < %s | opt -analyze -scalar-evolution |& grep {/ >>>>> u 3} >>>>> + >>>>> +define i32 @f(i32 %x) nounwind readnone { >>>>> +entry: >>>>> + %0 = icmp ugt i32 %x, 4 ; [#uses=1] >>>>> + br i1 %0, label %bb.nph, label %bb2 >>>>> + >>>>> +bb.nph: ; preds = %entry >>>>> + br label %bb >>>>> + >>>>> +bb: ; preds = %bb.nph, %bb1 >>>>> + %indvar = phi i32 [ 0, %bb.nph ], [ %indvar.next, %bb1 ] ; >>>>> >>>>> [#uses=2] >>>>> + %tmp = mul i32 %indvar, -3 ; [#uses=1] >>>>> + %x_addr.04 = add i32 %tmp, %x ; [#uses=1] >>>>> + %1 = add i32 %x_addr.04, -3 ; [#uses=2] >>>>> + br label %bb1 >>>>> + >>>>> +bb1: ; preds = %bb >>>>> + %2 = icmp ugt i32 %1, 4 ; [#uses=1] >>>>> + %indvar.next = add i32 %indvar, 1 ; [#uses=1] >>>>> + br i1 %2, label %bb, label %bb1.bb2_crit_edge >>>>> + >>>>> +bb1.bb2_crit_edge: ; preds = %bb1 >>>>> + %.lcssa = phi i32 [ %1, %bb1 ] ; [#uses=1] >>>>> + br label %bb2 >>>>> + >>>>> +bb2: ; preds = %bb1.bb2_crit_edge, %entry >>>>> + %x_addr.0.lcssa = phi i32 [ %.lcssa, %bb1.bb2_crit_edge ], [ %x, >>>>> %entry ] ; [#uses=1] >>>>> + ret i32 %x_addr.0.lcssa >>>>> +} >>>>> >>>>> Added: llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18- >>>>> Stride2.ll >>>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride2.ll?rev=59528&view=auto >>>>> >>>>> = >>>>> = >>>>> = >>>>> = >>>>> = >>>>> = >>>>> = >>>>> = >>>>> = >>>>> = >>>>> = >>>>> = >>>>> ================================================================== >>>>> --- llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride2.ll >>>>> (added) >>>>> +++ llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride2.ll >>>>> Tue Nov 18 09:10:54 2008 >>>>> @@ -0,0 +1,30 @@ >>>>> +; RUN: llvm-as < %s | opt -analyze -scalar-evolution |& grep {/ >>>>> u 3} >>>>> + >>>>> +define i32 @f(i32 %x) nounwind readnone { >>>>> +entry: >>>>> + %0 = icmp ugt i32 %x, 999 ; [#uses=1] >>>>> + br i1 %0, label %bb2, label %bb.nph >>>>> + >>>>> +bb.nph: ; preds = %entry >>>>> + br label %bb >>>>> + >>>>> +bb: ; preds = %bb.nph, %bb1 >>>>> + %indvar = phi i32 [ 0, %bb.nph ], [ %indvar.next, %bb1 ] ; >>>>> >>>>> [#uses=2] >>>>> + %tmp = mul i32 %indvar, 3 ; [#uses=1] >>>>> + %x_addr.04 = add i32 %tmp, %x ; [#uses=1] >>>>> + %1 = add i32 %x_addr.04, 3 ; [#uses=2] >>>>> + br label %bb1 >>>>> + >>>>> +bb1: ; preds = %bb >>>>> + %2 = icmp ugt i32 %1, 999 ; [#uses=1] >>>>> + %indvar.next = add i32 %indvar, 1 ; [#uses=1] >>>>> + br i1 %2, label %bb1.bb2_crit_edge, label %bb >>>>> + >>>>> +bb1.bb2_crit_edge: ; preds = %bb1 >>>>> + %.lcssa = phi i32 [ %1, %bb1 ] ; [#uses=1] >>>>> + br label %bb2 >>>>> + >>>>> +bb2: ; preds = %bb1.bb2_crit_edge, %entry >>>>> + %x_addr.0.lcssa = phi i32 [ %.lcssa, %bb1.bb2_crit_edge ], [ %x, >>>>> %entry ] ; [#uses=1] >>>>> + ret i32 %x_addr.0.lcssa >>>>> +} >>>>> >>>>> >>>>> _______________________________________________ >>>>> llvm-commits mailing list >>>>> llvm-commits at cs.uiuc.edu >>>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits >>>> _______________________________________________ >>>> llvm-commits mailing list >>>> llvm-commits at cs.uiuc.edu >>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits >>>> >>> _______________________________________________ >>> llvm-commits mailing list >>> llvm-commits at cs.uiuc.edu >>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits >> > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From gordonhenriksen at mac.com Thu Nov 20 10:56:57 2008 From: gordonhenriksen at mac.com (Gordon Henriksen) Date: Thu, 20 Nov 2008 16:56:57 -0000 Subject: [llvm-commits] [llvm] r59737 - /llvm/trunk/tools/llvmc2/ Message-ID: <200811201656.mAKGuw12028987@zion.cs.uiuc.edu> Author: gordon Date: Thu Nov 20 10:56:53 2008 New Revision: 59737 URL: http://llvm.org/viewvc/llvm-project?rev=59737&view=rev Log: Updating ignore lists. Modified: llvm/trunk/tools/llvmc2/ (props changed) Propchange: llvm/trunk/tools/llvmc2/ ------------------------------------------------------------------------------ --- svn:ignore (added) +++ svn:ignore Thu Nov 20 10:56:53 2008 @@ -0,0 +1,3 @@ +*.inc +Debug +Release From clattner at apple.com Thu Nov 20 12:45:52 2008 From: clattner at apple.com (Chris Lattner) Date: Thu, 20 Nov 2008 10:45:52 -0800 Subject: [llvm-commits] [llvm] r59612 - /llvm/trunk/include/llvm/Intrinsics.td In-Reply-To: <1227176465.3373.5.camel@idc-lt-i00171.microchip.com> References: <200811190850.mAJ8oJY4015533@zion.cs.uiuc.edu> <6DCEFC35-FD82-4F89-B1AB-6434042D1B10@apple.com> <1227176465.3373.5.camel@idc-lt-i00171.microchip.com> Message-ID: <8A4858E1-37B5-442F-8DBC-1D695AC351F4@apple.com> On Nov 20, 2008, at 2:21 AM, sanjiv gupta wrote: > Please find the attached patch. Let me know if it looks okay. Very nice, this is a great cleanup. One minor bug: +++ lib/Transforms/Utils/InlineFunction.cpp (working copy) @@ -258,7 +258,7 @@ Caller->begin()->begin()); // Emit a memcpy. Function *MemCpyFn = Intrinsic::getDeclaration(Caller- >getParent(), + Intrinsic::memcpy); This needs to pass in Int64Ty to getDeclaration. Something like this should work: const Type *Tys[] = { Type::Int64Ty }; ... Intrinsic::getDeclaration(Caller->getParent(), Intrinsic::memcpy, Tys, 1); +++ lib/Transforms/Scalar/InstructionCombining.cpp (working copy) @@ -9177,11 +9177,7 @@ if (GlobalVariable *GVSrc = dyn_cast(MMI- >getSource())) if (GVSrc->isConstant()) { Module *M = CI.getParent()->getParent()->getParent(); + Intrinsic::ID MemCpyID = Intrinsic::memcpy; CI.setOperand(0, Intrinsic::getDeclaration(M, MemCpyID)); Likewise, this needs to pass in CI.getOperand(3)->getType(). +++ lib/Transforms/Scalar/SimplifyLibCalls.cpp (working copy) @@ -130,8 +130,7 @@ Value *LibCallOptimization::EmitMemCpy(Value *Dst, Value *Src, Value *Len, unsigned Align, IRBuilder<> &B) { Module *M = Caller->getParent(); - Intrinsic::ID IID = Len->getType() == Type::Int32Ty ? - Intrinsic::memcpy_i32 : Intrinsic::memcpy_i64; + Intrinsic::ID IID = Intrinsic::memcpy; Value *MemCpy = Intrinsic::getDeclaration(M, IID); return B.CreateCall4(MemCpy, CastToCStr(Dst, B), CastToCStr(Src, B), Len, ConstantInt::get(Type::Int32Ty, Align)); This needs to pass in Len->getType() +++ lib/Transforms/Scalar/MemCpyOptimizer.cpp (working copy) @@ -429,7 +429,7 @@ if (MemSetF == 0) MemSetF = Intrinsic::getDeclaration(SI->getParent()->getParent() - ->getParent(), Intrinsic::memset_i64); + ->getParent(), Intrinsic::memset); This needs Int64_t. =================================================================== --- examples/BrainF/BrainF.cpp (revision 59621) +++ examples/BrainF/BrainF.cpp (working copy) @@ -53,7 +53,7 @@ //Function prototypes //declare void @llvm.memset.i32(i8 *, i8, i32, i32) - Function *memset_func = Intrinsic::getDeclaration(module, Intrinsic::memset_i32); + Function *memset_func = Intrinsic::getDeclaration(module, Intrinsic::memset); This needs Int32Ty. From ofv at wanadoo.es Thu Nov 20 13:13:56 2008 From: ofv at wanadoo.es (Oscar Fuentes) Date: Thu, 20 Nov 2008 19:13:56 -0000 Subject: [llvm-commits] [llvm] r59739 - /llvm/trunk/CMakeLists.txt Message-ID: <200811201913.mAKJDukK003304@zion.cs.uiuc.edu> Author: ofv Date: Thu Nov 20 13:13:51 2008 New Revision: 59739 URL: http://llvm.org/viewvc/llvm-project?rev=59739&view=rev Log: CMake: Option for building with -fPIC. Modified: llvm/trunk/CMakeLists.txt Modified: llvm/trunk/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/CMakeLists.txt?rev=59739&r1=59738&r2=59739&view=diff ============================================================================== --- llvm/trunk/CMakeLists.txt (original) +++ llvm/trunk/CMakeLists.txt Thu Nov 20 13:13:51 2008 @@ -104,6 +104,17 @@ include(config-ix) +option(LLVM_ENABLE_PIC "Build Position-Independent Code" OFF) + +if( LLVM_ENABLE_PIC ) + if( SUPPORTS_FPIC_FLAG ) + message(STATUS "Building with -fPIC") + add_definitions(-fPIC) + else( SUPPORTS_FPIC_FLAG ) + message(STATUS "Warning: -fPIC not supported.") + endif() +endif() + set( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${LLVM_TOOLS_BINARY_DIR} ) set( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${LLVM_BINARY_DIR}/lib ) set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${LLVM_BINARY_DIR}/lib ) From gohman at apple.com Thu Nov 20 13:26:09 2008 From: gohman at apple.com (Dan Gohman) Date: Thu, 20 Nov 2008 19:26:09 -0000 Subject: [llvm-commits] [llvm] r59741 - /llvm/trunk/test/CodeGen/Generic/2006-07-03-schedulers.ll Message-ID: <200811201926.mAKJQ9Sl003851@zion.cs.uiuc.edu> Author: djg Date: Thu Nov 20 13:26:04 2008 New Revision: 59741 URL: http://llvm.org/viewvc/llvm-project?rev=59741&view=rev Log: Test -pre-RA-sched=fast too, for completeness. Modified: llvm/trunk/test/CodeGen/Generic/2006-07-03-schedulers.ll Modified: llvm/trunk/test/CodeGen/Generic/2006-07-03-schedulers.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Generic/2006-07-03-schedulers.ll?rev=59741&r1=59740&r2=59741&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/Generic/2006-07-03-schedulers.ll (original) +++ llvm/trunk/test/CodeGen/Generic/2006-07-03-schedulers.ll Thu Nov 20 13:26:04 2008 @@ -2,6 +2,7 @@ ; RUN: llvm-as < %s | llc -pre-RA-sched=list-td ; RUN: llvm-as < %s | llc -pre-RA-sched=list-tdrr ; RUN: llvm-as < %s | llc -pre-RA-sched=list-burr +; RUN: llvm-as < %s | llc -pre-RA-sched=fast ; PR859 declare i32 @printf(i8*, i32, float) From tonic at nondot.org Thu Nov 20 13:34:41 2008 From: tonic at nondot.org (Tanya Lattner) Date: Thu, 20 Nov 2008 19:34:41 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r59742 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Message-ID: <200811201934.mAKJYfW4004312@zion.cs.uiuc.edu> Author: tbrethou Date: Thu Nov 20 13:34:40 2008 New Revision: 59742 URL: http://llvm.org/viewvc/llvm-project?rev=59742&view=rev Log: Do not constant fold away the GEP access for first elements of the struct. We need to be able to distinguish between an annotate attribute on the first element and the whole struct. Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=59742&r1=59741&r2=59742&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Thu Nov 20 13:34:40 2008 @@ -6068,8 +6068,17 @@ "Annotate attribute arg should always be a string"); Constant *strGV = TreeConstantToLLVM::EmitLV_STRING_CST(val); + + // We can not use the IRBuilder because it will constant fold away + // the GEP that is critical to distinguish between an annotate + // attribute on a whole struct from one on the first element of the + // struct. + BitCastInst *CastFieldPtr = new BitCastInst(FieldPtr, SBP, + FieldPtr->getNameStart()); + Builder.Insert(CastFieldPtr); + Value *Ops[4] = { - BitCastToType(FieldPtr, SBP), BitCastToType(strGV, SBP), + CastFieldPtr, BitCastToType(strGV, SBP), File, LineNo }; From dpatel at apple.com Thu Nov 20 13:50:17 2008 From: dpatel at apple.com (Devang Patel) Date: Thu, 20 Nov 2008 19:50:17 -0000 Subject: [llvm-commits] [llvm] r59745 - /llvm/trunk/lib/Transforms/Utils/InstructionNamer.cpp Message-ID: <200811201950.mAKJoH3c005061@zion.cs.uiuc.edu> Author: dpatel Date: Thu Nov 20 13:50:17 2008 New Revision: 59745 URL: http://llvm.org/viewvc/llvm-project?rev=59745&view=rev Log: Don't forget arguments! Modified: llvm/trunk/lib/Transforms/Utils/InstructionNamer.cpp Modified: llvm/trunk/lib/Transforms/Utils/InstructionNamer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/InstructionNamer.cpp?rev=59745&r1=59744&r2=59745&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/InstructionNamer.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/InstructionNamer.cpp Thu Nov 20 13:50:17 2008 @@ -30,7 +30,12 @@ } bool runOnFunction(Function &F) { - for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) + for (Function::arg_iterator AI = F.arg_begin(), AE = F.arg_end(); + AI != AE; ++AI) + if (!AI->hasName() && AI->getType() != Type::VoidTy) + AI->setName("tmp"); + + for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) if (!I->hasName() && I->getType() != Type::VoidTy) I->setName("tmp"); From gohman at apple.com Thu Nov 20 13:54:21 2008 From: gohman at apple.com (Dan Gohman) Date: Thu, 20 Nov 2008 19:54:21 -0000 Subject: [llvm-commits] [llvm] r59746 - /llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp Message-ID: <200811201954.mAKJsM5G005312@zion.cs.uiuc.edu> Author: djg Date: Thu Nov 20 13:54:21 2008 New Revision: 59746 URL: http://llvm.org/viewvc/llvm-project?rev=59746&view=rev Log: Add another machine-code printing pass when post-pass scheduling is run. Modified: llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp Modified: llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp?rev=59746&r1=59745&r2=59746&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp (original) +++ llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp Thu Nov 20 13:54:21 2008 @@ -226,9 +226,13 @@ PM.add(createMachineFunctionPrinterPass(cerr)); // Second pass scheduler. - if (!Fast && !DisablePostRAScheduler) + if (!Fast && !DisablePostRAScheduler) { PM.add(createPostRAScheduler()); + if (PrintMachineCode) + PM.add(createMachineFunctionPrinterPass(cerr)); + } + // Branch folding must be run after regalloc and prolog/epilog insertion. if (!Fast) PM.add(createBranchFoldingPass(getEnableTailMergeDefault())); From gohman at apple.com Thu Nov 20 13:58:36 2008 From: gohman at apple.com (Dan Gohman) Date: Thu, 20 Nov 2008 19:58:36 -0000 Subject: [llvm-commits] [llvm] r59747 - /llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp Message-ID: <200811201958.mAKJwaa9005499@zion.cs.uiuc.edu> Author: djg Date: Thu Nov 20 13:58:35 2008 New Revision: 59747 URL: http://llvm.org/viewvc/llvm-project?rev=59747&view=rev Log: Treat mid-block labels the same as terminators when building the MachineInstr scheduling DAG, meaning they implicitly depend on all preceding defs. This fixes Benchmarks/Shootout-C++/except and Regression/C++/EH/simple_rethrow in -relocation-model=pic -disable-post-RA-scheduler=false mode. Modified: llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp Modified: llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp?rev=59747&r1=59746&r2=59747&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp (original) +++ llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp Thu Nov 20 13:58:35 2008 @@ -97,7 +97,7 @@ } if (Terminator && SU->Succs.empty()) Terminator->addPred(SU, /*isCtrl=*/false, /*isSpecial=*/false); - if (MI->getDesc().isTerminator()) + if (MI->getDesc().isTerminator() || MI->isLabel()) Terminator = SU; } } From ofv at wanadoo.es Thu Nov 20 16:05:49 2008 From: ofv at wanadoo.es (Oscar Fuentes) Date: Thu, 20 Nov 2008 22:05:49 -0000 Subject: [llvm-commits] [llvm] r59752 - /llvm/trunk/docs/CMake.html Message-ID: <200811202205.mAKM5nbh012100@zion.cs.uiuc.edu> Author: ofv Date: Thu Nov 20 16:05:48 2008 New Revision: 59752 URL: http://llvm.org/viewvc/llvm-project?rev=59752&view=rev Log: CMake: Some documentation. Work in progress. Added: llvm/trunk/docs/CMake.html Added: llvm/trunk/docs/CMake.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/CMake.html?rev=59752&view=auto ============================================================================== --- llvm/trunk/docs/CMake.html (added) +++ llvm/trunk/docs/CMake.html Thu Nov 20 16:05:48 2008 @@ -0,0 +1,271 @@ + + + + Building LLVM with CMake + + + +
    + Building LLVM with CMake +
    + + + +
    +

    Written by ?scar Fuentes

    +
    + + + + + +
    + +

    CMake is a cross-platform + build-generator tool. CMake does not build the project, it generates + the files needed by your build tool (GNU make, Visual Studio, etc) for + building LLVM.

    + +

    If you are really anxious +

    + + + + + +
    + +

    We use here the command-line, non-interactive CMake interface

    + +
      + +
    1. Download + and install CMake. Version 2.6.2 is the minimum required.

      + +
    2. Open a shell. Your development tools must be reachable from this + shell through the PATH environment variable.

      + +
    3. Create a directory for containing the build. It is not + supported to build LLVM on the source directory. cd to this + directory:

      +
      +

      mkdir mybuilddir

      +

      cd mybuilddir

      +
      + +
    4. Execute this command on the shell + replacing path/to/llvm/source/root with the path to the + root of your LLVM source tree:

      +
      +

      cmake path/to/llvm/source/root

      +
      + +

      CMake will detect your development environment, perform a + series of test and generate the files required for building + LLVM. CMake will use default values for all build + parameters. See the Options and variables + section for fine-tuning your build

      + +

      This can fail if CMake can't detect your toolset, or if it + thinks that the environment is not sane enough. On this case + make sure that the toolset that you intend to use is the only + one reachable from the shell and that the shell itself is the + correct one for you development environment. CMake will refuse + to build MinGW makefiles if you have a POSIX shell reachable + through the PATH environment variable, for instance. You can + force CMake to use a given build tool, see + the Usage section.

      + +
    + +
    + + + + + +
    + +

    TODO

    + +
    + + + + + +
    + +

    Variables customize how the build will be generated. Options are + boolean variables, with possible values ON/OFF. Options and + variables are defined on the CMake command line like this:

    + +
    +

    cmake -DVARIABLE=value path/to/llvm/source

    +
    + +

    You can set a variable after the initial CMake invocation for + changing its value. You can also undefine a variable:

    + +
    +

    cmake -UVARIABLE path/to/llvm/source

    +
    + +

    Variables are stored on the CMake cache. This is a file + named CMakeCache.txt on the root of the build + directory. Do not hand-edit it.

    + +

    Variables are listed here appending its type after a colon. It is + correct to write the variable and the type on the CMake command + line:

    + +
    +

    cmake -DVARIABLE:TYPE=value path/to/llvm/source

    +
    + +
    + + + + +
    + +

    Here are listed some of the CMake variables that are used often, + along with a brief explanation and LLVM-specific notes. For full + documentation, check the CMake docs or execute cmake + --help-variable VARIABLE_NAME. + +

    +
    CMAKE_BUILD_TYPE:STRING
    + +
    Sets the build type for make based generators. Possible + values are Release, Debug, RelWithDebInfo and MiniSizeRel. On + systems like Visual Studio the user sets the build type with the IDE + settings.
    + +
    CMAKE_INSTALL_PREFIX:PATH
    +
    Path where LLVM will be installed if "make install" is invoked + or the "INSTALL" target is built.
    + +
    BUILD_SHARED_LIBS:BOOL
    +
    Flag indicating is shared libraries will be built. Its default + value is OFF. Shared libraries are not supported on Windows and + not recommended in the other OSes.
    +
    + +
    + + + + +
    + +
    +
    LLVM_TARGETS_TO_BUILD:STRING
    +
    Semicolon-separated list of targets to build, or all for + building all targets. Case-sensitive. For Visual C++ defaults + to X86. On the other cases defaults to all. Example: + -DLLVM_TARGETS_TO_BUILD="X86;PowerPC;Alpha".
    + +
    LLVM_ENABLE_THREADS:BOOL
    +
    Build with threads support, if available. Defaults to ON.
    + +
    LLVM_ENABLE_PIC:BOOL
    +
    Add the -fPIC flag to the compiler command-line, if the + compiler supports this flag. Some systems, like Windows, does not + need this flag. Defaults to OFF.
    + +
    LLVM_BUILD_32_BITS:BOOL
    +
    Build 32-bits executables and libraries on 64-bits systems. This + option is available only on some 64-bits unix systems. Defaults to + OFF.
    + +
    LLVM_PLO_FLAGS:STRING
    +
    Extra flags for creating partially linked objects. Visual C++ + does not use this.
    + +
    LLVM_TABLEGEN:STRING
    +
    Full path to a native TableGen executable (usually + named tblgen). This is intented for cross-compiling: if the + user sets this variable, no native TableGen will be created.
    +
    + +
    + + + + + +
    + +

    TODO

    + +
    + + + + + +
    + +

    TODO

    + +
    + + + + + +
    + +

    TODO

    + +
    + + + +
    +
    + Valid CSS! + Valid HTML 4.01! + + ?scar Fuentes
    + LLVM Compiler Infrastructure
    + Last modified: $Date: 2008-10-27 00:59:36 +0100 (Mon, 27 Oct 2008) $ +
    + + + From gohman at apple.com Thu Nov 20 16:09:53 2008 From: gohman at apple.com (Dan Gohman) Date: Thu, 20 Nov 2008 22:09:53 -0000 Subject: [llvm-commits] [llvm] r59753 - /llvm/trunk/include/llvm/Target/TargetInstrItineraries.h Message-ID: <200811202209.mAKM9rdc012278@zion.cs.uiuc.edu> Author: djg Date: Thu Nov 20 16:09:52 2008 New Revision: 59753 URL: http://llvm.org/viewvc/llvm-project?rev=59753&view=rev Log: Doxygenate comments. Modified: llvm/trunk/include/llvm/Target/TargetInstrItineraries.h Modified: llvm/trunk/include/llvm/Target/TargetInstrItineraries.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetInstrItineraries.h?rev=59753&r1=59752&r2=59753&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetInstrItineraries.h (original) +++ llvm/trunk/include/llvm/Target/TargetInstrItineraries.h Thu Nov 20 16:09:52 2008 @@ -19,60 +19,56 @@ namespace llvm { //===----------------------------------------------------------------------===// -// Instruction stage - These values represent a step in the execution of an -// instruction. The latency represents the number of discrete time slots used -// need to complete the stage. Units represent the choice of functional units -// that can be used to complete the stage. Eg. IntUnit1, IntUnit2. -// +/// Instruction stage - These values represent a step in the execution of an +/// instruction. The latency represents the number of discrete time slots used +/// need to complete the stage. Units represent the choice of functional units +/// that can be used to complete the stage. Eg. IntUnit1, IntUnit2. +/// struct InstrStage { - unsigned Cycles; // Length of stage in machine cycles - unsigned Units; // Choice of functional units + unsigned Cycles; ///< Length of stage in machine cycles + unsigned Units; ///< Choice of functional units }; //===----------------------------------------------------------------------===// -// Instruction itinerary - An itinerary represents a sequential series of steps -// required to complete an instruction. Itineraries are represented as -// sequences of instruction stages. -// +/// Instruction itinerary - An itinerary represents a sequential series of steps +/// required to complete an instruction. Itineraries are represented as +/// sequences of instruction stages. +/// struct InstrItinerary { - unsigned First; // Index of first stage in itinerary - unsigned Last; // Index of last + 1 stage in itinerary + unsigned First; ///< Index of first stage in itinerary + unsigned Last; ///< Index of last + 1 stage in itinerary }; //===----------------------------------------------------------------------===// -// Instruction itinerary Data - Itinerary data supplied by a subtarget to be -// used by a target. -// +/// Instruction itinerary Data - Itinerary data supplied by a subtarget to be +/// used by a target. +/// struct InstrItineraryData { - const InstrStage *Stages; // Array of stages selected - const InstrItinerary *Itineratries; // Array of itineraries selected + const InstrStage *Stages; ///< Array of stages selected + const InstrItinerary *Itineratries; ///< Array of itineraries selected -// -// Ctors. -// + /// Ctors. + /// InstrItineraryData() : Stages(0), Itineratries(0) {} InstrItineraryData(const InstrStage *S, const InstrItinerary *I) : Stages(S), Itineratries(I) {} - // - // isEmpty - Returns true if there are no itineraries. - // + /// isEmpty - Returns true if there are no itineraries. + /// inline bool isEmpty() const { return Itineratries == 0; } - // - // begin - Return the first stage of the itinerary. - // + /// begin - Return the first stage of the itinerary. + /// inline const InstrStage *begin(unsigned ItinClassIndx) const { unsigned StageIdx = Itineratries[ItinClassIndx].First; return Stages + StageIdx; } - // - // end - Return the last+1 stage of the itinerary. - // + /// end - Return the last+1 stage of the itinerary. + /// inline const InstrStage *end(unsigned ItinClassIndx) const { unsigned StageIdx = Itineratries[ItinClassIndx].Last; return Stages + StageIdx; From gohman at apple.com Thu Nov 20 16:10:21 2008 From: gohman at apple.com (Dan Gohman) Date: Thu, 20 Nov 2008 22:10:21 -0000 Subject: [llvm-commits] [llvm] r59754 - /llvm/trunk/include/llvm/Target/TargetInstrItineraries.h Message-ID: <200811202210.mAKMALMG012329@zion.cs.uiuc.edu> Author: djg Date: Thu Nov 20 16:10:21 2008 New Revision: 59754 URL: http://llvm.org/viewvc/llvm-project?rev=59754&view=rev Log: Delete redundant inline keywords. Modified: llvm/trunk/include/llvm/Target/TargetInstrItineraries.h Modified: llvm/trunk/include/llvm/Target/TargetInstrItineraries.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetInstrItineraries.h?rev=59754&r1=59753&r2=59754&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetInstrItineraries.h (original) +++ llvm/trunk/include/llvm/Target/TargetInstrItineraries.h Thu Nov 20 16:10:21 2008 @@ -58,18 +58,18 @@ /// isEmpty - Returns true if there are no itineraries. /// - inline bool isEmpty() const { return Itineratries == 0; } + bool isEmpty() const { return Itineratries == 0; } /// begin - Return the first stage of the itinerary. /// - inline const InstrStage *begin(unsigned ItinClassIndx) const { + const InstrStage *begin(unsigned ItinClassIndx) const { unsigned StageIdx = Itineratries[ItinClassIndx].First; return Stages + StageIdx; } /// end - Return the last+1 stage of the itinerary. /// - inline const InstrStage *end(unsigned ItinClassIndx) const { + const InstrStage *end(unsigned ItinClassIndx) const { unsigned StageIdx = Itineratries[ItinClassIndx].Last; return Stages + StageIdx; } From ofv at wanadoo.es Thu Nov 20 17:35:13 2008 From: ofv at wanadoo.es (Oscar Fuentes) Date: Thu, 20 Nov 2008 23:35:13 -0000 Subject: [llvm-commits] [llvm] r59755 - /llvm/trunk/docs/CMake.html Message-ID: <200811202335.mAKNZDHe015480@zion.cs.uiuc.edu> Author: ofv Date: Thu Nov 20 17:35:09 2008 New Revision: 59755 URL: http://llvm.org/viewvc/llvm-project?rev=59755&view=rev Log: CMake: More documentation. Modified: llvm/trunk/docs/CMake.html Modified: llvm/trunk/docs/CMake.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/CMake.html?rev=59755&r1=59754&r2=59755&view=diff ============================================================================== --- llvm/trunk/docs/CMake.html (original) +++ llvm/trunk/docs/CMake.html Thu Nov 20 17:35:09 2008 @@ -25,7 +25,7 @@
    -

    Written by ?scar Fuentes

    +

    Written by Oscar Fuentes

    @@ -41,7 +41,14 @@ the files needed by your build tool (GNU make, Visual Studio, etc) for building LLVM.

    -

    If you are really anxious +

    If you are really anxious about getting a functional LLVM build, + go to the Quick start section. If you + are a CMake novice, start on Basic CMake + usage and then go back to the Quick + start once you know what you are + doing. The Options and variables section + is a reference for customizing your build. If you already have + experience with CMake, this is the recommended starting point. @@ -105,7 +112,43 @@

    -

    TODO

    +

    This section explains basic aspects of CMake, mostly for + explaining those options which you may need on your day-to-day + usage.

    + +

    CMake comes with extensive documentation in the form of html + files and on the cmake executable itself. Execute cmake + --help for further help options.

    + +

    CMake requires to know for which build tool it shall generate + files (GNU make, Visual Studio, Xcode, etc). If not specified on + the command line, it tries to guess it based on you + environment. Once identified the build tool, CMake uses the + corresponding Generator for creating files for your build + tool. You can explicitly specify the generator with the command + line option -G "Name of the generator". For knowing the + available generators on your platform, execute

    + +
    +

    cmake --help

    +
    + +

    This will list the generator's names at the end of the help + text. Generator's names are case-sensitive. Example:

    + +
    +

    cmake -G "Visual Studio 8 2005" path/to/llvm/source/root

    +
    + +

    For a given development platform there can be more than one + adequate generator. If you use Visual Studio "NMake Makefiles" + is a generator you can use for building with NMake. By default, + CMake chooses the more specific generator supported by your + development environment. If you want an alternative generator, + you must tell this to CMake with the -G option.

    + +

    TODO: explain variables and cache. Move explanation here from + #options section.

    @@ -225,6 +268,8 @@
    +

    LLVM testing is not supported on Visual Studio.

    +

    TODO

    @@ -262,7 +307,7 @@ Valid HTML 4.01! - ?scar Fuentes
    + Oscar Fuentes
    LLVM Compiler Infrastructure
    Last modified: $Date: 2008-10-27 00:59:36 +0100 (Mon, 27 Oct 2008) $
    From isanbard at gmail.com Thu Nov 20 18:05:33 2008 From: isanbard at gmail.com (Bill Wendling) Date: Fri, 21 Nov 2008 00:05:33 -0000 Subject: [llvm-commits] [llvm] r59756 - /llvm/trunk/include/llvm/Intrinsics.td Message-ID: <200811210005.mAL05Xix016586@zion.cs.uiuc.edu> Author: void Date: Thu Nov 20 18:05:31 2008 New Revision: 59756 URL: http://llvm.org/viewvc/llvm-project?rev=59756&view=rev Log: Introduce two new "add" intrinsics. These return the sum plus a bit indicating that an overflow/carry occured. These are converted into ISD::[SU]ADDO nodes, which are lowered in a target-independent way into something sane. Eventually, each target can implement their own method of checking the overflow/carry flags. Modified: llvm/trunk/include/llvm/Intrinsics.td Modified: llvm/trunk/include/llvm/Intrinsics.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Intrinsics.td?rev=59756&r1=59755&r2=59756&view=diff ============================================================================== --- llvm/trunk/include/llvm/Intrinsics.td (original) +++ llvm/trunk/include/llvm/Intrinsics.td Thu Nov 20 18:05:31 2008 @@ -314,6 +314,15 @@ []>, GCCBuiltin<"__builtin_init_trampoline">; +//===------------------------ Overflow Intrinsics -------------------------===// +// + +// Expose the carry flag from add operations on two integrals. +def int_sadd_with_overflow : Intrinsic<[llvm_anyint_ty, llvm_i1_ty], + [LLVMMatchType<0>, LLVMMatchType<0>]>; +def int_uadd_with_overflow : Intrinsic<[llvm_anyint_ty, llvm_i1_ty], + [LLVMMatchType<0>, LLVMMatchType<0>]>; + //===------------------------- Atomic Intrinsics --------------------------===// // def int_memory_barrier : Intrinsic<[llvm_void_ty], From isanbard at gmail.com Thu Nov 20 18:06:33 2008 From: isanbard at gmail.com (Bill Wendling) Date: Fri, 21 Nov 2008 00:06:33 -0000 Subject: [llvm-commits] [llvm] r59757 - /llvm/trunk/lib/Transforms/IPO/Inliner.cpp Message-ID: <200811210006.mAL06XYR016622@zion.cs.uiuc.edu> Author: void Date: Thu Nov 20 18:06:32 2008 New Revision: 59757 URL: http://llvm.org/viewvc/llvm-project?rev=59757&view=rev Log: If the function being inlined has a higher stack protection level than the inlining function, then increase the stack protection level on the inlining function. Modified: llvm/trunk/lib/Transforms/IPO/Inliner.cpp Modified: llvm/trunk/lib/Transforms/IPO/Inliner.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/Inliner.cpp?rev=59757&r1=59756&r2=59757&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/Inliner.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/Inliner.cpp Thu Nov 20 18:06:32 2008 @@ -56,6 +56,15 @@ Function *Callee = CS.getCalledFunction(); if (!InlineFunction(CS, &CG, &TD)) return false; + // If the inlined function had a higher stack protection level than the + // calling function, then bump up the caller's stack protection level. + Function *Caller = CS.getCaller(); + if (Callee->hasFnAttr(Attribute::StackProtectReq)) + Caller->addFnAttr(Attribute::StackProtectReq); + else if (Callee->hasFnAttr(Attribute::StackProtect) && + !Caller->hasFnAttr(Attribute::StackProtectReq)) + Caller->addFnAttr(Attribute::StackProtect); + // If we inlined the last possible call site to the function, delete the // function body now. if (Callee->use_empty() && Callee->hasInternalLinkage() && From isanbard at gmail.com Thu Nov 20 18:09:21 2008 From: isanbard at gmail.com (Bill Wendling) Date: Fri, 21 Nov 2008 00:09:21 -0000 Subject: [llvm-commits] [llvm] r59758 - /llvm/trunk/lib/Transforms/IPO/Inliner.cpp Message-ID: <200811210009.mAL09LIH016709@zion.cs.uiuc.edu> Author: void Date: Thu Nov 20 18:09:21 2008 New Revision: 59758 URL: http://llvm.org/viewvc/llvm-project?rev=59758&view=rev Log: Fix error where it wasn't getting the correct caller function. Modified: llvm/trunk/lib/Transforms/IPO/Inliner.cpp Modified: llvm/trunk/lib/Transforms/IPO/Inliner.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/Inliner.cpp?rev=59758&r1=59757&r2=59758&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/Inliner.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/Inliner.cpp Thu Nov 20 18:09:21 2008 @@ -54,11 +54,12 @@ const std::set &SCCFunctions, const TargetData &TD) { Function *Callee = CS.getCalledFunction(); + Function *Caller = CS.getCaller(); + if (!InlineFunction(CS, &CG, &TD)) return false; // If the inlined function had a higher stack protection level than the // calling function, then bump up the caller's stack protection level. - Function *Caller = CS.getCaller(); if (Callee->hasFnAttr(Attribute::StackProtectReq)) Caller->addFnAttr(Attribute::StackProtectReq); else if (Callee->hasFnAttr(Attribute::StackProtect) && From gohman at apple.com Thu Nov 20 18:10:42 2008 From: gohman at apple.com (Dan Gohman) Date: Fri, 21 Nov 2008 00:10:42 -0000 Subject: [llvm-commits] [llvm] r59759 - in /llvm/trunk/lib/CodeGen/SelectionDAG: ScheduleDAGFast.cpp ScheduleDAGRRList.cpp Message-ID: <200811210010.mAL0Ag26016764@zion.cs.uiuc.edu> Author: djg Date: Thu Nov 20 18:10:42 2008 New Revision: 59759 URL: http://llvm.org/viewvc/llvm-project?rev=59759&view=rev Log: Change these schedulers to not emit no-ops. It turns out that the RR scheduler actually does look at latency values, but it doesn't use a hazard recognizer so it has no way to know when a no-op is needed, as opposed to just stalling and incrementing the cycle count. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp?rev=59759&r1=59758&r2=59759&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp Thu Nov 20 18:10:42 2008 @@ -577,9 +577,7 @@ } NotReady.clear(); - if (!CurSU) - Sequence.push_back(0); - else + if (CurSU) ScheduleNodeBottomUp(CurSU, CurCycle); ++CurCycle; } Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp?rev=59759&r1=59758&r2=59759&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Thu Nov 20 18:10:42 2008 @@ -1052,9 +1052,7 @@ } NotReady.clear(); - if (!CurSU) - Sequence.push_back(0); - else + if (CurSU) ScheduleNodeBottomUp(CurSU, CurCycle); ++CurCycle; } @@ -1152,9 +1150,7 @@ AvailableQueue->push_all(NotReady); NotReady.clear(); - if (!CurSU) - Sequence.push_back(0); - else + if (CurSU) ScheduleNodeTopDown(CurSU, CurCycle); ++CurCycle; } From isanbard at gmail.com Thu Nov 20 18:11:16 2008 From: isanbard at gmail.com (Bill Wendling) Date: Fri, 21 Nov 2008 00:11:16 -0000 Subject: [llvm-commits] [llvm] r59760 - in /llvm/trunk: include/llvm/CodeGen/SelectionDAGNodes.h lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200811210011.mAL0BGtv016793@zion.cs.uiuc.edu> Author: void Date: Thu Nov 20 18:11:16 2008 New Revision: 59760 URL: http://llvm.org/viewvc/llvm-project?rev=59760&view=rev Log: Add UADDO and SADDO nodes. These will be used for determining an overflow condition in an addition operation. Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h?rev=59760&r1=59759&r2=59760&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h (original) +++ llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h Thu Nov 20 18:11:16 2008 @@ -249,7 +249,14 @@ // to them to be chained together for add and sub of arbitrarily large // values. ADDE, SUBE, - + + // Overflow-aware nodes for arithmetic operations. These nodes take two + // operands: the normal lhs and rhs to the add. They produce two results: + // the normal result of the add, and a flag indicating whether an overflow + // occured. These nodes are generated from the llvm.[su]add.with.overflow + // intrinsics. They are lowered by target-dependent code. + SADDO, UADDO, + // Simple binary floating point operators. FADD, FSUB, FMUL, FDIV, FREM, Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=59760&r1=59759&r2=59760&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Thu Nov 20 18:11:16 2008 @@ -5151,6 +5151,8 @@ case ISD::CARRY_FALSE: return "carry_false"; case ISD::ADDC: return "addc"; case ISD::ADDE: return "adde"; + case ISD::SADDO: return "saddo"; + case ISD::UADDO: return "uaddo"; case ISD::SUBC: return "subc"; case ISD::SUBE: return "sube"; case ISD::SHL_PARTS: return "shl_parts"; From gohman at apple.com Thu Nov 20 18:12:10 2008 From: gohman at apple.com (Dan Gohman) Date: Fri, 21 Nov 2008 00:12:10 -0000 Subject: [llvm-commits] [llvm] r59761 - in /llvm/trunk: include/llvm/CodeGen/ScheduleDAGInstrs.h include/llvm/Target/TargetInstrItineraries.h lib/CodeGen/ScheduleDAGInstrs.cpp lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp Message-ID: <200811210012.mAL0CARY016838@zion.cs.uiuc.edu> Author: djg Date: Thu Nov 20 18:12:10 2008 New Revision: 59761 URL: http://llvm.org/viewvc/llvm-project?rev=59761&view=rev Log: Implement ComputeLatency for MachineInstr ScheduleDAGs. Factor some of the latency computation logic out of the SDNode ScheduleDAG code into a TargetInstrItineraries helper method to help with this. Modified: llvm/trunk/include/llvm/CodeGen/ScheduleDAGInstrs.h llvm/trunk/include/llvm/Target/TargetInstrItineraries.h llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp Modified: llvm/trunk/include/llvm/CodeGen/ScheduleDAGInstrs.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ScheduleDAGInstrs.h?rev=59761&r1=59760&r2=59761&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/ScheduleDAGInstrs.h (original) +++ llvm/trunk/include/llvm/CodeGen/ScheduleDAGInstrs.h Thu Nov 20 18:12:10 2008 @@ -53,6 +53,10 @@ /// input. virtual void BuildSchedUnits(); + /// ComputeLatency - Compute node latency. + /// + virtual void ComputeLatency(SUnit *SU); + virtual MachineBasicBlock *EmitSchedule(); /// Schedule - Order nodes according to selected style, filling Modified: llvm/trunk/include/llvm/Target/TargetInstrItineraries.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetInstrItineraries.h?rev=59761&r1=59760&r2=59761&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetInstrItineraries.h (original) +++ llvm/trunk/include/llvm/Target/TargetInstrItineraries.h Thu Nov 20 18:12:10 2008 @@ -73,6 +73,24 @@ unsigned StageIdx = Itineratries[ItinClassIndx].Last; return Stages + StageIdx; } + + /// getLatency - Return the scheduling latency of the given class. A + /// simple latency value for an instruction is an over-simplification + /// for some architectures, but it's a reasonable first approximation. + /// + unsigned getLatency(unsigned ItinClassIndx) const { + // If the target doesn't provide latency information, use a simple + // non-zero default value for all instructions. + if (isEmpty()) + return 1; + + // Just sum the cycle count for each stage. + unsigned Latency = 0; + for (const InstrStage *IS = begin(ItinClassIndx), *E = end(ItinClassIndx); + IS != E; ++IS) + Latency += IS->Cycles; + return Latency; + } }; Modified: llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp?rev=59761&r1=59760&r2=59761&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp (original) +++ llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp Thu Nov 20 18:12:10 2008 @@ -50,7 +50,7 @@ assert(TRI->isPhysicalRegister(Reg) && "Virtual register encountered!"); std::vector &UseList = Uses[Reg]; SUnit *&Def = Defs[Reg]; - // Optionally add output and anti dependences + // Optionally add output and anti dependences. if (Def && Def != SU) Def->addPred(SU, /*isCtrl=*/true, /*isSpecial=*/false, /*PhyReg=*/Reg, Cost); @@ -102,6 +102,15 @@ } } +void ScheduleDAGInstrs::ComputeLatency(SUnit *SU) { + const InstrItineraryData &InstrItins = TM.getInstrItineraryData(); + + // Compute the latency for the node. We use the sum of the latencies for + // all nodes flagged together into this SUnit. + SU->Latency = + InstrItins.getLatency(SU->getInstr()->getDesc().getSchedClass()); +} + void ScheduleDAGInstrs::dumpNode(const SUnit *SU) const { SU->getInstr()->dump(); } Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp?rev=59761&r1=59760&r2=59761&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp Thu Nov 20 18:12:10 2008 @@ -193,15 +193,17 @@ } SU->Latency = 0; - for (SDNode *N = SU->getNode(); N; N = N->getFlaggedNode()) { + bool SawMachineOpcode = false; + for (SDNode *N = SU->getNode(); N; N = N->getFlaggedNode()) if (N->isMachineOpcode()) { - unsigned SchedClass = TII->get(N->getMachineOpcode()).getSchedClass(); - const InstrStage *S = InstrItins.begin(SchedClass); - const InstrStage *E = InstrItins.end(SchedClass); - for (; S != E; ++S) - SU->Latency += S->Cycles; + SawMachineOpcode = true; + SU->Latency += + InstrItins.getLatency(TII->get(N->getMachineOpcode()).getSchedClass()); } - } + + // Ensure that CopyToReg and similar nodes have a non-zero latency. + if (!SawMachineOpcode) + SU->Latency = 1; } /// CountResults - The results of target nodes have register or immediate From ofv at wanadoo.es Thu Nov 20 18:18:45 2008 From: ofv at wanadoo.es (Oscar Fuentes) Date: Fri, 21 Nov 2008 00:18:45 -0000 Subject: [llvm-commits] [llvm] r59763 - /llvm/trunk/cmake/modules/TableGen.cmake Message-ID: <200811210018.mAL0Iksr017107@zion.cs.uiuc.edu> Author: ofv Date: Thu Nov 20 18:18:45 2008 New Revision: 59763 URL: http://llvm.org/viewvc/llvm-project?rev=59763&view=rev Log: CMake: Do not rebuild the world when tblgen changes but the .inc files it produces are not affected by the change. Modified: llvm/trunk/cmake/modules/TableGen.cmake Modified: llvm/trunk/cmake/modules/TableGen.cmake URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/cmake/modules/TableGen.cmake?rev=59763&r1=59762&r2=59763&view=diff ============================================================================== --- llvm/trunk/cmake/modules/TableGen.cmake (original) +++ llvm/trunk/cmake/modules/TableGen.cmake Thu Nov 20 18:18:45 2008 @@ -4,9 +4,16 @@ macro(tablegen ofn) file(GLOB all_tds "*.td") + add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${ofn}.tmp + COMMAND ${LLVM_TABLEGEN} ${ARGN} -I ${CMAKE_CURRENT_SOURCE_DIR} + -I ${LLVM_MAIN_SRC_DIR}/lib/Target -I ${LLVM_MAIN_INCLUDE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/${LLVM_TARGET_DEFINITIONS} -o ${ofn}.tmp + DEPENDS ${LLVM_TABLEGEN} ${all_tds} + COMMENT "Building ${ofn}.tmp..." + ) add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${ofn} - COMMAND ${LLVM_TABLEGEN} ${ARGN} -I ${CMAKE_CURRENT_SOURCE_DIR} -I ${LLVM_MAIN_SRC_DIR}/lib/Target -I ${LLVM_MAIN_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/${LLVM_TARGET_DEFINITIONS} -o ${ofn} - DEPENDS tblgen ${all_tds} + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${ofn}.tmp ${ofn} + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${ofn}.tmp COMMENT "Building ${ofn}..." ) set(TABLEGEN_OUTPUT ${TABLEGEN_OUTPUT} ${CMAKE_CURRENT_BINARY_DIR}/${ofn}) From gohman at apple.com Thu Nov 20 18:22:24 2008 From: gohman at apple.com (Dan Gohman) Date: Thu, 20 Nov 2008 16:22:24 -0800 Subject: [llvm-commits] [llvm] r59760 - in /llvm/trunk: include/llvm/CodeGen/SelectionDAGNodes.h lib/CodeGen/SelectionDAG/SelectionDAG.cpp In-Reply-To: <200811210011.mAL0BGtv016793@zion.cs.uiuc.edu> References: <200811210011.mAL0BGtv016793@zion.cs.uiuc.edu> Message-ID: On Nov 20, 2008, at 4:11 PM, Bill Wendling wrote: > + > + // Overflow-aware nodes for arithmetic operations. These nodes > take two > + // operands: the normal lhs and rhs to the add. They produce > two results: > + // the normal result of the add, and a flag indicating whether > an overflow > + // occured. These nodes are generated from the llvm. > [su]add.with.overflow > + // intrinsics. They are lowered by target-dependent code. > + SADDO, UADDO, Hi Bill, Is UADDO is equivalent to ADDC? Dan From evan.cheng at apple.com Thu Nov 20 18:29:08 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 20 Nov 2008 16:29:08 -0800 Subject: [llvm-commits] [llvm] r59761 - in /llvm/trunk: include/llvm/CodeGen/ScheduleDAGInstrs.h include/llvm/Target/TargetInstrItineraries.h lib/CodeGen/ScheduleDAGInstrs.cpp lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp In-Reply-To: <200811210012.mAL0CARY016838@zion.cs.uiuc.edu> References: <200811210012.mAL0CARY016838@zion.cs.uiuc.edu> Message-ID: <4CFBB45E-0C36-4614-8A7C-63C782E63396@apple.com> On Nov 20, 2008, at 4:12 PM, Dan Gohman wrote: > > Modified: llvm/trunk/include/llvm/Target/TargetInstrItineraries.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetInstrItineraries.h?rev=59761&r1=59760&r2=59761&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/include/llvm/Target/TargetInstrItineraries.h (original) > +++ llvm/trunk/include/llvm/Target/TargetInstrItineraries.h Thu Nov > 20 18:12:10 2008 > @@ -73,6 +73,24 @@ > unsigned StageIdx = Itineratries[ItinClassIndx].Last; > return Stages + StageIdx; > } > + > + /// getLatency - Return the scheduling latency of the given > class. A > + /// simple latency value for an instruction is an over- > simplification > + /// for some architectures, but it's a reasonable first > approximation. > + /// > + unsigned getLatency(unsigned ItinClassIndx) const { > + // If the target doesn't provide latency information, use a > simple > + // non-zero default value for all instructions. > + if (isEmpty()) > + return 1; Does it make sense for load instructions default latency to be 2? Evan > > + > + // Just sum the cycle count for each stage. > + unsigned Latency = 0; > + for (const InstrStage *IS = begin(ItinClassIndx), *E = > end(ItinClassIndx); > + IS != E; ++IS) > + Latency += IS->Cycles; > + return Latency; > + } > }; > > > > Modified: llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp?rev=59761&r1=59760&r2=59761&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp (original) > +++ llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp Thu Nov 20 18:12:10 > 2008 > @@ -50,7 +50,7 @@ > assert(TRI->isPhysicalRegister(Reg) && "Virtual register > encountered!"); > std::vector &UseList = Uses[Reg]; > SUnit *&Def = Defs[Reg]; > - // Optionally add output and anti dependences > + // Optionally add output and anti dependences. > if (Def && Def != SU) > Def->addPred(SU, /*isCtrl=*/true, /*isSpecial=*/false, > /*PhyReg=*/Reg, Cost); > @@ -102,6 +102,15 @@ > } > } > > +void ScheduleDAGInstrs::ComputeLatency(SUnit *SU) { > + const InstrItineraryData &InstrItins = TM.getInstrItineraryData(); > + > + // Compute the latency for the node. We use the sum of the > latencies for > + // all nodes flagged together into this SUnit. > + SU->Latency = > + InstrItins.getLatency(SU->getInstr()->getDesc().getSchedClass()); > +} > + > void ScheduleDAGInstrs::dumpNode(const SUnit *SU) const { > SU->getInstr()->dump(); > } > > Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp?rev=59761&r1=59760&r2=59761&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp > (original) > +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp Thu > Nov 20 18:12:10 2008 > @@ -193,15 +193,17 @@ > } > > SU->Latency = 0; > - for (SDNode *N = SU->getNode(); N; N = N->getFlaggedNode()) { > + bool SawMachineOpcode = false; > + for (SDNode *N = SU->getNode(); N; N = N->getFlaggedNode()) > if (N->isMachineOpcode()) { > - unsigned SchedClass = TII->get(N- > >getMachineOpcode()).getSchedClass(); > - const InstrStage *S = InstrItins.begin(SchedClass); > - const InstrStage *E = InstrItins.end(SchedClass); > - for (; S != E; ++S) > - SU->Latency += S->Cycles; > + SawMachineOpcode = true; > + SU->Latency += > + InstrItins.getLatency(TII->get(N- > >getMachineOpcode()).getSchedClass()); > } > - } > + > + // Ensure that CopyToReg and similar nodes have a non-zero latency. > + if (!SawMachineOpcode) > + SU->Latency = 1; > } > > /// CountResults - The results of target nodes have register or > immediate > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From clattner at apple.com Thu Nov 20 18:37:55 2008 From: clattner at apple.com (Chris Lattner) Date: Thu, 20 Nov 2008 16:37:55 -0800 Subject: [llvm-commits] [llvm] r59760 - in /llvm/trunk: include/llvm/CodeGen/SelectionDAGNodes.h lib/CodeGen/SelectionDAG/SelectionDAG.cpp In-Reply-To: <200811210011.mAL0BGtv016793@zion.cs.uiuc.edu> References: <200811210011.mAL0BGtv016793@zion.cs.uiuc.edu> Message-ID: On Nov 20, 2008, at 4:11 PM, Bill Wendling wrote: > Log: > Add UADDO and SADDO nodes. These will be used for determining an > overflow > condition in an addition operation. Cool. > @@ -249,7 +249,14 @@ > - > + > + // Overflow-aware nodes for arithmetic operations. These nodes > take two > + // operands: the normal lhs and rhs to the add. They produce > two results: > + // the normal result of the add, and a flag indicating whether > an overflow > + // occured. These nodes are generated from the llvm. > [su]add.with.overflow > + // intrinsics. They are lowered by target-dependent code. > + SADDO, UADDO, Please format the comment to make it more obvious what the input/ outputs are. Here are some good examples to follow: // RESULT, OUTCHAIN = EXCEPTIONADDR(INCHAIN) - This node represents the // address of the exception block on entry to an landing pad block. EXCEPTIONADDR, // RESULT, OUTCHAIN = EHSELECTION(INCHAIN, EXCEPTION) - This node represents // the selection index of the exception thrown. EHSELECTION, -Chris From isanbard at gmail.com Thu Nov 20 18:38:30 2008 From: isanbard at gmail.com (Bill Wendling) Date: Thu, 20 Nov 2008 16:38:30 -0800 Subject: [llvm-commits] [llvm] r59760 - in /llvm/trunk: include/llvm/CodeGen/SelectionDAGNodes.h lib/CodeGen/SelectionDAG/SelectionDAG.cpp In-Reply-To: References: <200811210011.mAL0BGtv016793@zion.cs.uiuc.edu> Message-ID: <16e5fdf90811201638x6a52ea1cpcba801684ededce2@mail.gmail.com> On Thu, Nov 20, 2008 at 4:22 PM, Dan Gohman wrote: > > On Nov 20, 2008, at 4:11 PM, Bill Wendling wrote: >> + >> + // Overflow-aware nodes for arithmetic operations. These nodes >> take two >> + // operands: the normal lhs and rhs to the add. They produce >> two results: >> + // the normal result of the add, and a flag indicating whether >> an overflow >> + // occured. These nodes are generated from the llvm. >> [su]add.with.overflow >> + // intrinsics. They are lowered by target-dependent code. >> + SADDO, UADDO, > > Hi Bill, > > Is UADDO is equivalent to ADDC? > Hmm. It does appear to be similar. How is ADDC handled later on? I see that the DAG combiner does some reasoning about trivial cases, but how is it handled in the back ends? -bw From isanbard at gmail.com Thu Nov 20 18:38:57 2008 From: isanbard at gmail.com (Bill Wendling) Date: Thu, 20 Nov 2008 16:38:57 -0800 Subject: [llvm-commits] [llvm] r59760 - in /llvm/trunk: include/llvm/CodeGen/SelectionDAGNodes.h lib/CodeGen/SelectionDAG/SelectionDAG.cpp In-Reply-To: References: <200811210011.mAL0BGtv016793@zion.cs.uiuc.edu> Message-ID: <16e5fdf90811201638p50878d08tf5819ff6bb46190f@mail.gmail.com> On Thu, Nov 20, 2008 at 4:37 PM, Chris Lattner wrote: > On Nov 20, 2008, at 4:11 PM, Bill Wendling wrote: >> @@ -249,7 +249,14 @@ >> - >> + >> + // Overflow-aware nodes for arithmetic operations. These nodes >> take two >> + // operands: the normal lhs and rhs to the add. They produce >> two results: >> + // the normal result of the add, and a flag indicating whether >> an overflow >> + // occured. These nodes are generated from the llvm. >> [su]add.with.overflow >> + // intrinsics. They are lowered by target-dependent code. >> + SADDO, UADDO, > > Please format the comment to make it more obvious what the input/ > outputs are. Here are some good examples to follow: > > // RESULT, OUTCHAIN = EXCEPTIONADDR(INCHAIN) - This node > represents the > // address of the exception block on entry to an landing pad block. > EXCEPTIONADDR, > > // RESULT, OUTCHAIN = EHSELECTION(INCHAIN, EXCEPTION) - This node > represents > // the selection index of the exception thrown. > EHSELECTION, > Okay. :-) -bw From isanbard at gmail.com Thu Nov 20 18:45:06 2008 From: isanbard at gmail.com (Bill Wendling) Date: Fri, 21 Nov 2008 00:45:06 -0000 Subject: [llvm-commits] [llvm] r59766 - /llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h Message-ID: <200811210045.mAL0j6g1018020@zion.cs.uiuc.edu> Author: void Date: Thu Nov 20 18:45:00 2008 New Revision: 59766 URL: http://llvm.org/viewvc/llvm-project?rev=59766&view=rev Log: Update comment. Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h?rev=59766&r1=59765&r2=59766&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h (original) +++ llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h Thu Nov 20 18:45:00 2008 @@ -250,6 +250,7 @@ // values. ADDE, SUBE, + // RESULT, OVERFLOW_FLAG, OUTCHAIN = [SU]ADDO(INCHAIN, LHS, RHS) - // Overflow-aware nodes for arithmetic operations. These nodes take two // operands: the normal lhs and rhs to the add. They produce two results: // the normal result of the add, and a flag indicating whether an overflow From daniel at zuster.org Thu Nov 20 19:00:42 2008 From: daniel at zuster.org (Daniel Dunbar) Date: Fri, 21 Nov 2008 01:00:42 -0000 Subject: [llvm-commits] [test-suite] r59769 - in /test-suite/trunk: Makefile.rules Makefile.tests SingleSource/Makefile.singlesrc Message-ID: <200811210100.mAL10gCB018595@zion.cs.uiuc.edu> Author: ddunbar Date: Thu Nov 20 19:00:41 2008 New Revision: 59769 URL: http://llvm.org/viewvc/llvm-project?rev=59769&view=rev Log: Teach test-suite how to build Objective-C[++] programs. - A little hacky as this just assumes that the C and C++ compilers can build Objective-C but I don't anticipate this being a problem for platforms we would use this on. Modified: test-suite/trunk/Makefile.rules test-suite/trunk/Makefile.tests test-suite/trunk/SingleSource/Makefile.singlesrc Modified: test-suite/trunk/Makefile.rules URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/Makefile.rules?rev=59769&r1=59768&r2=59769&view=diff ============================================================================== --- test-suite/trunk/Makefile.rules (original) +++ test-suite/trunk/Makefile.rules Thu Nov 20 19:00:41 2008 @@ -437,7 +437,7 @@ ifndef Source Source := $(notdir $(ExtraSource) $(wildcard $(SourceDir)/*.cpp \ $(SourceDir)/*.cc $(SourceDir)/*.c $(SourceDir)/*.y \ - $(SourceDir)/*.l)) + $(SourceDir)/*.l $(SourceDir)/*.m $(SourceDir)/*.mm)) endif # Modified: test-suite/trunk/Makefile.tests URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/Makefile.tests?rev=59769&r1=59768&r2=59769&view=diff ============================================================================== --- test-suite/trunk/Makefile.tests (original) +++ test-suite/trunk/Makefile.tests Thu Nov 20 19:00:41 2008 @@ -61,6 +61,16 @@ -$(LLVMGXX) $(CPPFLAGS) $(CXXFLAGS) $(LOPTFLAGS) $(TARGET_FLAGS) -c $< -o $@ -emit-llvm -$(call UPGRADE_LL,$@) +# Compile from X.m to Output/X.bc +Output/%.bc: %.m $(LCC1) Output/.dir $(INCLUDES) + -$(LLVMGCC) $(CPPFLAGS) $(CFLAGS) $(LOPTFLAGS) $(TARGET_FLAGS) -c $< -o $@ -emit-llvm + -$(call UPGRADE_LL,$@) + +# Compile from X.mm to Output/X.bc +Output/%.bc: %.mm $(LCC1XX) Output/.dir $(INCLUDES) + -$(LLVMGXX) $(CPPFLAGS) $(CXXFLAGS) $(LOPTFLAGS) $(TARGET_FLAGS) -c $< -o $@ -emit-llvm + -$(call UPGRADE_LL,$@) + # LLVM Assemble from X.ll to Output/X.bc. Because we are coming directly from # LLVM source, use the non-transforming assembler. # @@ -74,3 +84,6 @@ %.o: %.c +%.o: %.m + +%.o: %.mm Modified: test-suite/trunk/SingleSource/Makefile.singlesrc URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/SingleSource/Makefile.singlesrc?rev=59769&r1=59768&r2=59769&view=diff ============================================================================== --- test-suite/trunk/SingleSource/Makefile.singlesrc (original) +++ test-suite/trunk/SingleSource/Makefile.singlesrc Thu Nov 20 19:00:41 2008 @@ -30,6 +30,12 @@ Output/%.LOC.txt: $(SourceDir)/%.cpp cat $< | wc -l > $@ + +Output/%.LOC.txt: $(SourceDir)/%.m + cat $< | wc -l > $@ + +Output/%.LOC.txt: $(SourceDir)/%.mm + cat $< | wc -l > $@ endif # FIXME: LIBS should be specified, not hardcoded to -lm @@ -39,6 +45,11 @@ Output/%.native: $(SourceDir)/%.cpp Output/.dir -$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(OPTFLAGS) $(TARGET_FLAGS) $< -lm -o $@ $(LDFLAGS) +Output/%.native: $(SourceDir)/%.m Output/.dir + -$(CC) $(CPPFLAGS) $(CFLAGS) $(OPTFLAGS) $(TARGET_FLAGS) $< -lm -o $@ $(LDFLAGS) + +Output/%.native: $(SourceDir)/%.mm Output/.dir + -$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(OPTFLAGS) $(TARGET_FLAGS) $< -lm -o $@ $(LDFLAGS) bugpoint-gccas bugpoint-opt bugpoint-llvm-ld bugpoint-gccld bugpoint-jit bugpoint-llc bugpoint-llc-beta: @echo "The $@ target doesn't work in SingleSource. Try:" From gohman at apple.com Thu Nov 20 19:08:40 2008 From: gohman at apple.com (Dan Gohman) Date: Thu, 20 Nov 2008 17:08:40 -0800 Subject: [llvm-commits] [llvm] r59760 - in /llvm/trunk: include/llvm/CodeGen/SelectionDAGNodes.h lib/CodeGen/SelectionDAG/SelectionDAG.cpp In-Reply-To: <16e5fdf90811201638x6a52ea1cpcba801684ededce2@mail.gmail.com> References: <200811210011.mAL0BGtv016793@zion.cs.uiuc.edu> <16e5fdf90811201638x6a52ea1cpcba801684ededce2@mail.gmail.com> Message-ID: <088EE78A-D1EA-42FF-8754-51A8A6611B2F@apple.com> On Nov 20, 2008, at 4:38 PM, Bill Wendling wrote: > On Thu, Nov 20, 2008 at 4:22 PM, Dan Gohman wrote: >> >> On Nov 20, 2008, at 4:11 PM, Bill Wendling wrote: >>> + >>> + // Overflow-aware nodes for arithmetic operations. These nodes >>> take two >>> + // operands: the normal lhs and rhs to the add. They produce >>> two results: >>> + // the normal result of the add, and a flag indicating whether >>> an overflow >>> + // occured. These nodes are generated from the llvm. >>> [su]add.with.overflow >>> + // intrinsics. They are lowered by target-dependent code. >>> + SADDO, UADDO, >> >> Hi Bill, >> >> Is UADDO is equivalent to ADDC? >> > Hmm. It does appear to be similar. How is ADDC handled later on? I see > that the DAG combiner does some reasoning about trivial cases, but how > is it handled in the back ends? In the x86 backend, ADDC is lowered to a single add instruction, with the carry information carried by the flags register. Dan From gohman at apple.com Thu Nov 20 19:30:55 2008 From: gohman at apple.com (Dan Gohman) Date: Fri, 21 Nov 2008 01:30:55 -0000 Subject: [llvm-commits] [llvm] r59775 - /llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Message-ID: <200811210130.mAL1UtPG019629@zion.cs.uiuc.edu> Author: djg Date: Thu Nov 20 19:30:54 2008 New Revision: 59775 URL: http://llvm.org/viewvc/llvm-project?rev=59775&view=rev Log: Remove the CycleBound computation code from the ScheduleDAGRRList schedulers. This doesn't have much immediate impact because targets that use these schedulers by default don't yet provide pipeline information. This code also didn't have the benefit of register pressure information. Also, removing it will avoid problems with list-burr suddenly starting to do latency-oriented scheduling on x86 when we start providing pipeline data, which would increase spilling. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp?rev=59775&r1=59774&r2=59775&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Thu Nov 20 19:30:54 2008 @@ -270,19 +270,6 @@ } #endif - // Compute how many cycles it will be before this actually becomes - // available. This is the max of the start time of all predecessors plus - // their latencies. - // If this is a token edge, we don't need to wait for the latency of the - // preceeding instruction (e.g. a long-latency load) unless there is also - // some other data dependence. - unsigned PredDoneCycle = SU->Cycle; - if (!isChain) - PredDoneCycle += PredSU->Latency; - else if (SU->Latency) - PredDoneCycle += 1; - PredSU->CycleBound = std::max(PredSU->CycleBound, PredDoneCycle); - if (PredSU->NumSuccsLeft == 0) { PredSU->isAvailable = true; AvailableQueue->push(PredSU); @@ -339,22 +326,12 @@ /// unscheduled, incrcease the succ left count of its predecessors. Remove /// them from AvailableQueue if necessary. void ScheduleDAGRRList::CapturePred(SUnit *PredSU, SUnit *SU, bool isChain) { - unsigned CycleBound = 0; - for (SUnit::succ_iterator I = PredSU->Succs.begin(), E = PredSU->Succs.end(); - I != E; ++I) { - if (I->Dep == SU) - continue; - CycleBound = std::max(CycleBound, - I->Dep->Cycle + PredSU->Latency); - } - if (PredSU->isAvailable) { PredSU->isAvailable = false; if (!PredSU->isPending) AvailableQueue->remove(PredSU); } - PredSU->CycleBound = CycleBound; ++PredSU->NumSuccsLeft; } @@ -948,13 +925,11 @@ LRegsMap.clear(); SUnit *CurSU = AvailableQueue->pop(); while (CurSU) { - if (CurSU->CycleBound <= CurCycle) { - SmallVector LRegs; - if (!DelayForLiveRegsBottomUp(CurSU, LRegs)) - break; - Delayed = true; - LRegsMap.insert(std::make_pair(CurSU, LRegs)); - } + SmallVector LRegs; + if (!DelayForLiveRegsBottomUp(CurSU, LRegs)) + break; + Delayed = true; + LRegsMap.insert(std::make_pair(CurSU, LRegs)); CurSU->isPending = true; // This SU is not in AvailableQueue right now. NotReady.push_back(CurSU); @@ -1083,19 +1058,6 @@ } #endif - // Compute how many cycles it will be before this actually becomes - // available. This is the max of the start time of all predecessors plus - // their latencies. - // If this is a token edge, we don't need to wait for the latency of the - // preceeding instruction (e.g. a long-latency load) unless there is also - // some other data dependence. - unsigned PredDoneCycle = SU->Cycle; - if (!isChain) - PredDoneCycle += SU->Latency; - else if (SU->Latency) - PredDoneCycle += 1; - SuccSU->CycleBound = std::max(SuccSU->CycleBound, PredDoneCycle); - if (SuccSU->NumPredsLeft == 0) { SuccSU->isAvailable = true; AvailableQueue->push(SuccSU); @@ -1137,19 +1099,10 @@ // While Available queue is not empty, grab the node with the highest // priority. If it is not ready put it back. Schedule the node. - std::vector NotReady; Sequence.reserve(SUnits.size()); while (!AvailableQueue->empty()) { SUnit *CurSU = AvailableQueue->pop(); - while (CurSU && CurSU->CycleBound > CurCycle) { - NotReady.push_back(CurSU); - CurSU = AvailableQueue->pop(); - } - // Add the nodes that aren't ready back onto the available list. - AvailableQueue->push_all(NotReady); - NotReady.clear(); - if (CurSU) ScheduleNodeTopDown(CurSU, CurCycle); ++CurCycle; @@ -1433,9 +1386,6 @@ if (left->Depth != right->Depth) return left->Depth < right->Depth; - if (left->CycleBound != right->CycleBound) - return left->CycleBound > right->CycleBound; - assert(left->NodeQueueId && right->NodeQueueId && "NodeQueueId cannot be zero"); return (left->NodeQueueId > right->NodeQueueId); @@ -1636,9 +1586,6 @@ if (left->NumSuccsLeft != right->NumSuccsLeft) return left->NumSuccsLeft > right->NumSuccsLeft; - if (left->CycleBound != right->CycleBound) - return left->CycleBound > right->CycleBound; - assert(left->NodeQueueId && right->NodeQueueId && "NodeQueueId cannot be zero"); return (left->NodeQueueId > right->NodeQueueId); From daniel at zuster.org Thu Nov 20 19:36:26 2008 From: daniel at zuster.org (Daniel Dunbar) Date: Fri, 21 Nov 2008 01:36:26 -0000 Subject: [llvm-commits] [test-suite] r59776 - in /test-suite/trunk/SingleSource/UnitTests: Makefile ObjC++/ ObjC++/Hello.mm ObjC++/Makefile ObjC/ ObjC/Makefile ObjC/print-class-info.m Message-ID: <200811210136.mAL1aQhC019785@zion.cs.uiuc.edu> Author: ddunbar Date: Thu Nov 20 19:36:26 2008 New Revision: 59776 URL: http://llvm.org/viewvc/llvm-project?rev=59776&view=rev Log: Add an Obj-C and an Obj-C++ test. - Only run on x86/Darwin for now. Added: test-suite/trunk/SingleSource/UnitTests/ObjC/ (with props) test-suite/trunk/SingleSource/UnitTests/ObjC++/ (with props) test-suite/trunk/SingleSource/UnitTests/ObjC++/Hello.mm test-suite/trunk/SingleSource/UnitTests/ObjC++/Makefile test-suite/trunk/SingleSource/UnitTests/ObjC/Makefile test-suite/trunk/SingleSource/UnitTests/ObjC/print-class-info.m Modified: test-suite/trunk/SingleSource/UnitTests/Makefile Modified: test-suite/trunk/SingleSource/UnitTests/Makefile URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/SingleSource/UnitTests/Makefile?rev=59776&r1=59775&r2=59776&view=diff ============================================================================== --- test-suite/trunk/SingleSource/UnitTests/Makefile (original) +++ test-suite/trunk/SingleSource/UnitTests/Makefile Thu Nov 20 19:36:26 2008 @@ -15,5 +15,12 @@ DIRS += SignlessTypes Threads +# Only test Obj-C on darwin/x86 for time being. +ifeq ($(ARCH),x86) +ifeq ($(OS),Darwin) +DIRS += ObjC ObjC++ +endif +endif + PROGRAM_REQUIRED_TO_EXIT_OK := 1 include $(LEVEL)/SingleSource/Makefile.singlesrc Propchange: test-suite/trunk/SingleSource/UnitTests/ObjC/ ------------------------------------------------------------------------------ --- svn:ignore (added) +++ svn:ignore Thu Nov 20 19:36:26 2008 @@ -0,0 +1 @@ +Output Propchange: test-suite/trunk/SingleSource/UnitTests/ObjC++/ ------------------------------------------------------------------------------ --- svn:ignore (added) +++ svn:ignore Thu Nov 20 19:36:26 2008 @@ -0,0 +1 @@ +Output Added: test-suite/trunk/SingleSource/UnitTests/ObjC++/Hello.mm URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/SingleSource/UnitTests/ObjC%2B%2B/Hello.mm?rev=59776&view=auto ============================================================================== --- test-suite/trunk/SingleSource/UnitTests/ObjC++/Hello.mm (added) +++ test-suite/trunk/SingleSource/UnitTests/ObjC++/Hello.mm Thu Nov 20 19:36:26 2008 @@ -0,0 +1,66 @@ +/* Taken from Objective-C 2.0 manual, errors in retyping are + mine. */ + +#import + +class Hello { + private: + id greeting_text; + public: + Hello() { + greeting_text = @"Hello, world!"; + } + Hello(const char *initial_greeting_text) { + greeting_text = [[NSString alloc] + initWithUTF8String:initial_greeting_text]; + } + void say_hello() { + printf("%s\n", [greeting_text UTF8String]); + } +}; + + at interface Greeting : NSObject { + @private + Hello *hello; +} +-(id) init; +-(void) dealloc; +-(void) sayGreeting; +-(void) sayGreeting:(Hello*)greeting; + at end + + at implementation Greeting +-(id) init { + if (self = [super init]) { + hello = new Hello(); + } + return self; +} +-(void) dealloc { + delete hello; + [super dealloc]; +} +-(void) sayGreeting { + hello->say_hello(); +} +-(void) sayGreeting:(Hello*)greeting { + greeting->say_hello(); +} + at end + +// Taken from the Objective-C 2.0 guide. +int main() { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + + Greeting *greeting = [[Greeting alloc] init]; + [greeting sayGreeting]; + + Hello *hello = new Hello("Bonjour, monde!"); + [greeting sayGreeting:hello]; + + delete hello; + [greeting release]; + [pool release]; + return 0; +} + Added: test-suite/trunk/SingleSource/UnitTests/ObjC++/Makefile URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/SingleSource/UnitTests/ObjC%2B%2B/Makefile?rev=59776&view=auto ============================================================================== --- test-suite/trunk/SingleSource/UnitTests/ObjC++/Makefile (added) +++ test-suite/trunk/SingleSource/UnitTests/ObjC++/Makefile Thu Nov 20 19:36:26 2008 @@ -0,0 +1,9 @@ +# SingleSource/UnitTests/ObjC++/Makefile +LEVEL = ../../.. +include $(LEVEL)/Makefile.config + +DIRS := + +LDFLAGS += -lstdc++ -lobjc -framework Foundation +PROGRAM_REQUIRED_TO_EXIT_OK := 1 +include $(LEVEL)/SingleSource/Makefile.singlesrc Added: test-suite/trunk/SingleSource/UnitTests/ObjC/Makefile URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/SingleSource/UnitTests/ObjC/Makefile?rev=59776&view=auto ============================================================================== --- test-suite/trunk/SingleSource/UnitTests/ObjC/Makefile (added) +++ test-suite/trunk/SingleSource/UnitTests/ObjC/Makefile Thu Nov 20 19:36:26 2008 @@ -0,0 +1,9 @@ +# SingleSource/UnitTests/ObjC/Makefile +LEVEL = ../../.. +include $(LEVEL)/Makefile.config + +DIRS := + +LDFLAGS += -lobjc -framework Foundation +PROGRAM_REQUIRED_TO_EXIT_OK := 1 +include $(LEVEL)/SingleSource/Makefile.singlesrc Added: test-suite/trunk/SingleSource/UnitTests/ObjC/print-class-info.m URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/SingleSource/UnitTests/ObjC/print-class-info.m?rev=59776&view=auto ============================================================================== --- test-suite/trunk/SingleSource/UnitTests/ObjC/print-class-info.m (added) +++ test-suite/trunk/SingleSource/UnitTests/ObjC/print-class-info.m Thu Nov 20 19:36:26 2008 @@ -0,0 +1,422 @@ +#include +#include +#include +#include + + at protocol UnusedProtocol ++(void) makeWaffles; + at end + + at protocol P2 + at end + + at protocol P + at required ++(void) requiredProtocolClassMethod; +-(void) requiredProtocolInstanceMethod; + at optional ++(void) optionalProtocolClassMethod; +-(void) optionalProtocolInstanceMethod; + + at required + at property int requiredProtocolProperty; + at optional + at property int optionalProtocolProperty; // XXX this is not actually + // optional in Obj-C 2? or + // maybe just in old ABI? + at end + + at protocol CategoryProtocol ++(void) categoryClassMethod; +-(void) categoryInstanceMethod; + at end + + at interface A : NSObject

    { + at private + int privateVar; + at protected + int protectedVar; + at public + int publicVar; + __weak id weakVar; + __strong id strongVar; + + int halfDynamicA, halfDynamicB; +} + + at property(assign) int requiredProtocolProperty; + at property(assign) int optionalProtocolProperty; + + at property(assign) int Ptest_a; + at property(copy) id Ptest_b; + at property(retain) id Ptest_c; + + at property(getter=iGetThings) int things; + at property(setter=iSetOtherThings:) int otherThings; + + at property(assign) int dynamicNotReally; + at property(assign) int halfDynamicA; + at property(assign) int halfDynamicB; + ++(void) classMethod; +-(void) instanceMethod; + at end + + at interface A () ++(void) extendedClassMethod; +-(void) extendedInstanceMethod; ++(void) requiredProtocolClassMethod; +-(void) requiredProtocolInstanceMethod; + at end + + at implementation A + at dynamic Ptest_a, Ptest_b, Ptest_c; + at dynamic things, otherThings; + + at dynamic dynamicNotReally; +-(int) dynamicNotReally {}; +-(void) dynamicNotReally: (int) arg {}; + + at synthesize halfDynamicA; +-(int) halfDynamicA {}; + + at synthesize halfDynamicB; +-(void) halfDynamicB: (int) arg {}; + + at synthesize requiredProtocolProperty = privateVar; +#ifdef ABI2 + at synthesize optionalProtocolProperty = someRandomVar; +#else + at synthesize optionalProtocolProperty = publicVar; +#endif + ++(void) classMethod { + printf("I am a class method\n"); +} +-(void) instanceMethod { + printf("I am an instance method\n"); +} + ++(void) requiredProtocolClassMethod { + printf("I am a required protocol class method\n"); +} + +-(void) requiredProtocolInstanceMethod { + printf("I am a required protocol instance method\n"); +} + ++(void) extendedClassMethod { + printf("I am an extended class method\n"); +} +-(void) extendedInstanceMethod { + printf("I am an extended instance method\n"); +} + at end + + at interface A ( A_Category ) ++(void) categoryClassMethod; +-(void) categoryInstanceMethod; + + at property(assign) int categoryProperty; + at end + + at implementation A ( A_Category ) + at dynamic categoryProperty; + ++(void) categoryClassMethod { +} +-(void) categoryInstanceMethod { +} + at end + +/***/ + +int ivar_cmp(const void *av, const void *bv) { + const Ivar *a = av; + const Ivar *b = bv; + return strcmp(ivar_getName(*a), ivar_getName(*b)); +} + +int methodDescription_cmp(const void *av, const void *bv) { + const struct objc_method_description *a = av; + const struct objc_method_description *b = bv; + return strcmp(sel_getName(a->name), sel_getName(b->name)); +} + +int method_cmp(const void *av, const void *bv) { + const Method *a = av; + const Method *b = bv; + return strcmp(method_getName(*a), method_getName(*b)); +} + +int property_cmp(const void *av, const void *bv) { + const objc_property_t *a = av; + const objc_property_t *b = bv; + return strcmp(property_getName(*a), property_getName(*b)); +} + +int protocol_cmp(const void *av, const void *bv) { + Protocol * const *a = av; + Protocol * const *b = bv; + return strcmp(protocol_getName(*a), protocol_getName(*b)); +} + +void sort_ivars(Ivar *ivars, unsigned numIvars) { + qsort(ivars, numIvars, sizeof(*ivars), ivar_cmp); +} + +void sort_methodDescriptions(struct objc_method_description *methods, unsigned numMethods) { + qsort(methods, numMethods, sizeof(*methods), methodDescription_cmp); +} + +void sort_methods(Method *methods, unsigned numMethods) { + unsigned i; + qsort(methods, numMethods, sizeof(*methods), method_cmp); +} + +void sort_properties(objc_property_t *properties, unsigned numProperties) { + qsort(properties, numProperties, sizeof(*properties), property_cmp); +} + +void sort_protocols(Protocol **protocols, unsigned numProtocols) { + qsort(protocols, numProtocols, sizeof(*protocols), protocol_cmp); +} + +/***/ + +static int indent = 0; +#define PRINT1(e0,t0) printf("%*s" #e0 ": %" #t0 "\n", indent*2, "", e0) +#define PRINT2(e0,t0,e1,t1) printf("%*s" #e0 ": %" #t0 ", " #e1 ": %" #t1 "\n", indent*2, "", e0, e1) +#define PRINT3(e0,t0,e1,t1,e2,t2) printf("%*s" #e0 ": %" #t0 ", " #e1 ": %" #t1 ", " #e2 ": %" #t2 "\n", indent*2, "", e0, e1, e2) +#define PRINT4(e0,t0,e1,t1,e2,t2,e3,t3) printf("%*s" #e0 ": %" #t0 ", " #e1 ": %" #t1 ", " #e2 ": %" #t2 ", " #e3 ": %" #t3 "\n", indent*2, "", e0, e1, e2, e3) +#define PRINT5(e0,t0,e1,t1,e2,t2,e3,t3,e4,t4) printf("%*s" #e0 ": %" #t0 ", " #e1 ": %" #t1 ", " #e2 ": %" #t2 ", " #e3 ": %" #t3 ", " #e4 ": %" #t4 "\n", indent*2, "", e0, e1, e2, e3, e4) +void printInfo(Class c, int printData) { + unsigned i; + + ++indent; + PRINT1(c != 0, d); + PRINT1(class_getName(c), s); + PRINT1(object_getClassName(c), s); + PRINT1(objc_getClass(class_getName(c)) == c, d); + PRINT1(class_conformsToProtocol(c, @protocol(P)), d); + + unsigned numIvars; + Ivar *ivars = class_copyIvarList(c, &numIvars); + sort_ivars(ivars, numIvars); + PRINT1(numIvars, d); + if (printData) { + ++indent; + for (i=0; i References: <200811210045.mAL0j6g1018020@zion.cs.uiuc.edu> Message-ID: <2B71376D-B2B0-47DA-A411-7047B0C59457@apple.com> On Nov 20, 2008, at 4:45 PM, Bill Wendling wrote: > Author: void > Date: Thu Nov 20 18:45:00 2008 > New Revision: 59766 > > URL: http://llvm.org/viewvc/llvm-project?rev=59766&view=rev > Log: > Update comment. > > Modified: > llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h > > Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h?rev=59766&r1=59765&r2=59766&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h (original) > +++ llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h Thu Nov 20 > 18:45:00 2008 > @@ -250,6 +250,7 @@ > // values. > ADDE, SUBE, > > + // RESULT, OVERFLOW_FLAG, OUTCHAIN = [SU]ADDO(INCHAIN, LHS, > RHS) - > // Overflow-aware nodes for arithmetic operations. These nodes > take two > // operands: the normal lhs and rhs to the add. They produce two > results: > // the normal result of the add, and a flag indicating whether > an overflow These shouldn't take a CHAIN input, -Chris From clattner at apple.com Thu Nov 20 19:41:47 2008 From: clattner at apple.com (Chris Lattner) Date: Thu, 20 Nov 2008 17:41:47 -0800 Subject: [llvm-commits] [llvm] r59760 - in /llvm/trunk: include/llvm/CodeGen/SelectionDAGNodes.h lib/CodeGen/SelectionDAG/SelectionDAG.cpp In-Reply-To: <088EE78A-D1EA-42FF-8754-51A8A6611B2F@apple.com> References: <200811210011.mAL0BGtv016793@zion.cs.uiuc.edu> <16e5fdf90811201638x6a52ea1cpcba801684ededce2@mail.gmail.com> <088EE78A-D1EA-42FF-8754-51A8A6611B2F@apple.com> Message-ID: <3FC10397-71A9-48AD-89FD-568F61316725@apple.com> On Nov 20, 2008, at 5:08 PM, Dan Gohman wrote: > > On Nov 20, 2008, at 4:38 PM, Bill Wendling wrote: > >> On Thu, Nov 20, 2008 at 4:22 PM, Dan Gohman wrote: >>> >>> On Nov 20, 2008, at 4:11 PM, Bill Wendling wrote: >>>> + >>>> + // Overflow-aware nodes for arithmetic operations. These nodes >>>> take two >>>> + // operands: the normal lhs and rhs to the add. They produce >>>> two results: >>>> + // the normal result of the add, and a flag indicating whether >>>> an overflow >>>> + // occured. These nodes are generated from the llvm. >>>> [su]add.with.overflow >>>> + // intrinsics. They are lowered by target-dependent code. >>>> + SADDO, UADDO, >>> >>> Hi Bill, >>> >>> Is UADDO is equivalent to ADDC? >>> >> Hmm. It does appear to be similar. How is ADDC handled later on? I >> see >> that the DAG combiner does some reasoning about trivial cases, but >> how >> is it handled in the back ends? > > In the x86 backend, ADDC is lowered to a single add instruction, with > the carry information carried by the flags register. They aren't the same. ADDC returns a value + flag. SADDO returns a value + bool. The use of the bool may very well be a store to memory or something like that. You can't flag these together. OTOH, I think it would be perfectly fine for X86 to custom legalize SADDO into ADDC + an X86ISD::SETO node or something. -Chris From gohman at apple.com Thu Nov 20 19:44:52 2008 From: gohman at apple.com (Dan Gohman) Date: Fri, 21 Nov 2008 01:44:52 -0000 Subject: [llvm-commits] [llvm] r59777 - in /llvm/trunk/lib/CodeGen: ScheduleDAGInstrs.cpp SelectionDAG/ScheduleDAGSDNodes.cpp Message-ID: <200811210144.mAL1iqPf020148@zion.cs.uiuc.edu> Author: djg Date: Thu Nov 20 19:44:51 2008 New Revision: 59777 URL: http://llvm.org/viewvc/llvm-project?rev=59777&view=rev Log: Use ComputeLatency in the MachineInstr scheduler. Modified: llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp Modified: llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp?rev=59777&r1=59776&r2=59777&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp (original) +++ llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp Thu Nov 20 19:44:51 2008 @@ -99,6 +99,9 @@ Terminator->addPred(SU, /*isCtrl=*/false, /*isSpecial=*/false); if (MI->getDesc().isTerminator() || MI->isLabel()) Terminator = SU; + + // Assign the Latency field of SU using target-provided information. + ComputeLatency(SU); } } Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp?rev=59777&r1=59776&r2=59777&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp Thu Nov 20 19:44:51 2008 @@ -132,6 +132,7 @@ assert(N->getNodeId() == -1 && "Node already inserted!"); N->setNodeId(NodeSUnit->NodeNum); + // Assign the Latency field of NodeSUnit using target-provided information. ComputeLatency(NodeSUnit); } From dpatel at apple.com Thu Nov 20 19:52:59 2008 From: dpatel at apple.com (Devang Patel) Date: Fri, 21 Nov 2008 01:52:59 -0000 Subject: [llvm-commits] [llvm] r59778 - /llvm/trunk/lib/Transforms/Scalar/SCCP.cpp Message-ID: <200811210152.mAL1qx6Z020446@zion.cs.uiuc.edu> Author: dpatel Date: Thu Nov 20 19:52:59 2008 New Revision: 59778 URL: http://llvm.org/viewvc/llvm-project?rev=59778&view=rev Log: Fix unused variable warnings. Modified: llvm/trunk/lib/Transforms/Scalar/SCCP.cpp Modified: llvm/trunk/lib/Transforms/Scalar/SCCP.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SCCP.cpp?rev=59778&r1=59777&r2=59778&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/SCCP.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/SCCP.cpp Thu Nov 20 19:52:59 2008 @@ -1788,6 +1788,7 @@ // The constant folder may not have been able to fold the terminator // if this is a branch or switch on undef. Fold it manually as a // branch to the first successor. +#ifndef NDEBUG if (BranchInst *BI = dyn_cast(I)) { assert(BI->isConditional() && isa(BI->getCondition()) && "Branch should be foldable!"); @@ -1796,6 +1797,7 @@ } else { assert(0 && "Didn't fold away reference to block!"); } +#endif // Make this an uncond branch to the first successor. TerminatorInst *TI = I->getParent()->getTerminator(); From gohman at apple.com Thu Nov 20 19:58:53 2008 From: gohman at apple.com (Dan Gohman) Date: Thu, 20 Nov 2008 17:58:53 -0800 Subject: [llvm-commits] [llvm] r59760 - in /llvm/trunk: include/llvm/CodeGen/SelectionDAGNodes.h lib/CodeGen/SelectionDAG/SelectionDAG.cpp In-Reply-To: <3FC10397-71A9-48AD-89FD-568F61316725@apple.com> References: <200811210011.mAL0BGtv016793@zion.cs.uiuc.edu> <16e5fdf90811201638x6a52ea1cpcba801684ededce2@mail.gmail.com> <088EE78A-D1EA-42FF-8754-51A8A6611B2F@apple.com> <3FC10397-71A9-48AD-89FD-568F61316725@apple.com> Message-ID: On Nov 20, 2008, at 5:41 PM, Chris Lattner wrote: > > On Nov 20, 2008, at 5:08 PM, Dan Gohman wrote: > >> >> On Nov 20, 2008, at 4:38 PM, Bill Wendling wrote: >> >>> On Thu, Nov 20, 2008 at 4:22 PM, Dan Gohman >>> wrote: >>>> >>>> On Nov 20, 2008, at 4:11 PM, Bill Wendling wrote: >>>>> + >>>>> + // Overflow-aware nodes for arithmetic operations. These >>>>> nodes >>>>> take two >>>>> + // operands: the normal lhs and rhs to the add. They produce >>>>> two results: >>>>> + // the normal result of the add, and a flag indicating >>>>> whether >>>>> an overflow >>>>> + // occured. These nodes are generated from the llvm. >>>>> [su]add.with.overflow >>>>> + // intrinsics. They are lowered by target-dependent code. >>>>> + SADDO, UADDO, >>>> >>>> Hi Bill, >>>> >>>> Is UADDO is equivalent to ADDC? >>>> >>> Hmm. It does appear to be similar. How is ADDC handled later on? I >>> see >>> that the DAG combiner does some reasoning about trivial cases, but >>> how >>> is it handled in the back ends? >> >> In the x86 backend, ADDC is lowered to a single add instruction, with >> the carry information carried by the flags register. > > They aren't the same. ADDC returns a value + flag. SADDO returns a > value + bool. The use of the bool may very well be a store to memory > or something like that. You can't flag these together. Ok. Bill, can you update the comment to reflect this? Thanks, Dan From isanbard at gmail.com Thu Nov 20 20:03:52 2008 From: isanbard at gmail.com (Bill Wendling) Date: Fri, 21 Nov 2008 02:03:52 -0000 Subject: [llvm-commits] [llvm] r59779 - in /llvm/trunk: include/llvm/CodeGen/SelectionDAGNodes.h lib/CodeGen/SelectionDAG/DAGCombiner.cpp lib/CodeGen/SelectionDAG/SelectionDAG.cpp lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Message-ID: <200811210203.mAL23qX5020821@zion.cs.uiuc.edu> Author: void Date: Thu Nov 20 20:03:52 2008 New Revision: 59779 URL: http://llvm.org/viewvc/llvm-project?rev=59779&view=rev Log: Implement the sadd_with_overflow intrinsic. This is converted into "ISD::ADDO". ISD::ADDO is lowered into a target-independent form that does the addition and then checks if the result is less than one of the operands. (If it is, then there was an overflow.) Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h?rev=59779&r1=59778&r2=59779&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h (original) +++ llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h Thu Nov 20 20:03:52 2008 @@ -250,13 +250,13 @@ // values. ADDE, SUBE, - // RESULT, OVERFLOW_FLAG, OUTCHAIN = [SU]ADDO(INCHAIN, LHS, RHS) - - // Overflow-aware nodes for arithmetic operations. These nodes take two - // operands: the normal lhs and rhs to the add. They produce two results: - // the normal result of the add, and a flag indicating whether an overflow - // occured. These nodes are generated from the llvm.[su]add.with.overflow - // intrinsics. They are lowered by target-dependent code. - SADDO, UADDO, + // RESULT, OVERFLOW_FLAG, OUTCHAIN = ADDO(INCHAIN, LHS, RHS) - + // Overflow-aware node for arithmetic operations. This node takes two + // operands: the normal lhs and rhs to the add. It produces two results: the + // normal result of the add, and a flag indicating whether an overflow + // occured. This node is generated from the llvm.sadd.with.overflow + // intrinsic. It is lowered by target-dependent code. + ADDO, // Simple binary floating point operators. FADD, FSUB, FMUL, FDIV, FREM, Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=59779&r1=59778&r2=59779&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Thu Nov 20 20:03:52 2008 @@ -190,6 +190,7 @@ SDValue visitBUILD_VECTOR(SDNode *N); SDValue visitCONCAT_VECTORS(SDNode *N); SDValue visitVECTOR_SHUFFLE(SDNode *N); + SDValue visitADDO(SDNode *N); SDValue XformToShuffleWithZero(SDNode *N); SDValue ReassociateOps(unsigned Opc, SDValue LHS, SDValue RHS); @@ -727,6 +728,7 @@ case ISD::BUILD_VECTOR: return visitBUILD_VECTOR(N); case ISD::CONCAT_VECTORS: return visitCONCAT_VECTORS(N); case ISD::VECTOR_SHUFFLE: return visitVECTOR_SHUFFLE(N); + case ISD::ADDO: return visitADDO(N); } return SDValue(); } @@ -5143,6 +5145,34 @@ return SDValue(); } +SDValue DAGCombiner::visitADDO(SDNode *N) { + SDValue Chain = N->getOperand(2); + SDValue LHS = N->getOperand(0); + SDValue RHS = N->getOperand(1); + + SDValue Sum = DAG.getNode(ISD::ADD, LHS.getValueType(), LHS, RHS); + AddToWorkList(Sum.getNode()); + SDValue Cmp = DAG.getSetCC(MVT::i1, Sum, LHS, ISD::SETLT); + AddToWorkList(Cmp.getNode()); + + MVT ValueVTs[] = { LHS.getValueType(), MVT::i1, MVT::Other }; + SDValue Ops[] = { Sum, Cmp, Chain }; + + SDValue Merge = DAG.getMergeValues(DAG.getVTList(&ValueVTs[0], 3), + &Ops[0], 3); + SDNode *MNode = Merge.getNode(); + + AddToWorkList(MNode); + DAG.ReplaceAllUsesOfValueWith(SDValue(N, 0), SDValue(MNode, 0)); + DAG.ReplaceAllUsesOfValueWith(SDValue(N, 1), SDValue(MNode, 1)); + DAG.ReplaceAllUsesOfValueWith(SDValue(N, 2), SDValue(MNode, 2)); + + // Since the node is now dead, remove it from the graph. + removeFromWorkList(N); + DAG.DeleteNode(N); + return SDValue(N, 0); +} + /// XformToShuffleWithZero - Returns a vector_shuffle if it able to transform /// an AND to a vector_shuffle with the destination vector and a zero vector. /// e.g. AND V, <0xffffffff, 0, 0xffffffff, 0>. ==> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=59779&r1=59778&r2=59779&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Thu Nov 20 20:03:52 2008 @@ -5151,8 +5151,7 @@ case ISD::CARRY_FALSE: return "carry_false"; case ISD::ADDC: return "addc"; case ISD::ADDE: return "adde"; - case ISD::SADDO: return "saddo"; - case ISD::UADDO: return "uaddo"; + case ISD::ADDO: return "addo"; case ISD::SUBC: return "subc"; case ISD::SUBE: return "sube"; case ISD::SHL_PARTS: return "shl_parts"; Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp?rev=59779&r1=59778&r2=59779&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Thu Nov 20 20:03:52 2008 @@ -4092,6 +4092,31 @@ DAG.setRoot(DAG.getNode(ISD::TRAP, MVT::Other, getRoot())); return 0; } + + case Intrinsic::sadd_with_overflow: { + // Convert to "ISD::ADDO" instruction. + SDValue Chain = getRoot(); + SDValue Op1 = getValue(I.getOperand(1)); + SDValue Op2 = getValue(I.getOperand(2)); + MVT Ty = Op1.getValueType(); + + MVT ValueVTs[] = { Ty, MVT::i1, MVT::Other }; + SDValue Ops[] = { Op1, Op2, Chain }; + + SDValue Result = DAG.getNode(ISD::ADDO, DAG.getVTList(&ValueVTs[0], 3), + &Ops[0], 3); + + setValue(&I, Result); + + unsigned NumArgRegs = Result.getNode()->getNumValues() - 1; + DAG.setRoot(SDValue(Result.getNode(), NumArgRegs)); + return 0; + } + case Intrinsic::uadd_with_overflow: { + // TODO: Convert to "ISD::ADDC" instruction. + return 0; + } + case Intrinsic::prefetch: { SDValue Ops[4]; Ops[0] = getRoot(); From isanbard at gmail.com Thu Nov 20 20:06:45 2008 From: isanbard at gmail.com (Bill Wendling) Date: Thu, 20 Nov 2008 18:06:45 -0800 Subject: [llvm-commits] [llvm] r59760 - in /llvm/trunk: include/llvm/CodeGen/SelectionDAGNodes.h lib/CodeGen/SelectionDAG/SelectionDAG.cpp In-Reply-To: References: <200811210011.mAL0BGtv016793@zion.cs.uiuc.edu> <16e5fdf90811201638x6a52ea1cpcba801684ededce2@mail.gmail.com> <088EE78A-D1EA-42FF-8754-51A8A6611B2F@apple.com> <3FC10397-71A9-48AD-89FD-568F61316725@apple.com> Message-ID: <16e5fdf90811201806g17f79697gd71e97e106adf2ae@mail.gmail.com> On Thu, Nov 20, 2008 at 5:58 PM, Dan Gohman wrote: > > On Nov 20, 2008, at 5:41 PM, Chris Lattner wrote: > >> >> On Nov 20, 2008, at 5:08 PM, Dan Gohman wrote: >> >>> >>> On Nov 20, 2008, at 4:38 PM, Bill Wendling wrote: >>> >>>> On Thu, Nov 20, 2008 at 4:22 PM, Dan Gohman >>>> wrote: >>>>> >>>>> On Nov 20, 2008, at 4:11 PM, Bill Wendling wrote: >>>>>> + >>>>>> + // Overflow-aware nodes for arithmetic operations. These >>>>>> nodes >>>>>> take two >>>>>> + // operands: the normal lhs and rhs to the add. They produce >>>>>> two results: >>>>>> + // the normal result of the add, and a flag indicating >>>>>> whether >>>>>> an overflow >>>>>> + // occured. These nodes are generated from the llvm. >>>>>> [su]add.with.overflow >>>>>> + // intrinsics. They are lowered by target-dependent code. >>>>>> + SADDO, UADDO, >>>>> >>>>> Hi Bill, >>>>> >>>>> Is UADDO is equivalent to ADDC? >>>>> >>>> Hmm. It does appear to be similar. How is ADDC handled later on? I >>>> see >>>> that the DAG combiner does some reasoning about trivial cases, but >>>> how >>>> is it handled in the back ends? >>> >>> In the x86 backend, ADDC is lowered to a single add instruction, with >>> the carry information carried by the flags register. >> >> They aren't the same. ADDC returns a value + flag. SADDO returns a >> value + bool. The use of the bool may very well be a store to memory >> or something like that. You can't flag these together. > > Ok. Bill, can you update the comment to reflect this? > Yes. Sorry for the confusion. :-) Also, ignore my recent check-in. I was going to change it, but I'm changing it back soon. -bw From isanbard at gmail.com Thu Nov 20 20:12:42 2008 From: isanbard at gmail.com (Bill Wendling) Date: Fri, 21 Nov 2008 02:12:42 -0000 Subject: [llvm-commits] [llvm] r59780 - in /llvm/trunk: include/llvm/CodeGen/SelectionDAGNodes.h lib/CodeGen/SelectionDAG/DAGCombiner.cpp lib/CodeGen/SelectionDAG/SelectionDAG.cpp lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Message-ID: <200811210212.mAL2ChPo021116@zion.cs.uiuc.edu> Author: void Date: Thu Nov 20 20:12:42 2008 New Revision: 59780 URL: http://llvm.org/viewvc/llvm-project?rev=59780&view=rev Log: Rename "ADDO" to "SADDO" and "UADDO". The "UADDO" isn't equivalent to "ADDC" because the boolean it returns to indicate an overflow may not be treated like as a flag. It could be stored to memory, for instance. Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h?rev=59780&r1=59779&r2=59780&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h (original) +++ llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h Thu Nov 20 20:12:42 2008 @@ -250,13 +250,14 @@ // values. ADDE, SUBE, - // RESULT, OVERFLOW_FLAG, OUTCHAIN = ADDO(INCHAIN, LHS, RHS) - - // Overflow-aware node for arithmetic operations. This node takes two - // operands: the normal lhs and rhs to the add. It produces two results: the - // normal result of the add, and a flag indicating whether an overflow - // occured. This node is generated from the llvm.sadd.with.overflow - // intrinsic. It is lowered by target-dependent code. - ADDO, + // RESULT, BOOL, OUTCHAIN = [SU]ADDO(INCHAIN, LHS, RHS) - Overflow-aware + // node for arithmetic operations. This node takes two operands: the normal + // lhs and rhs to the add. It produces two results: the normal result of the + // add, and a boolean to indicate if an overflow occured (this isn't a flag, + // because it may be stored to memory, etc.). This node is generated from + // the llvm.sadd.with.overflow intrinsic. It is lowered by target-dependent + // code. + SADDO, UADDO, // Simple binary floating point operators. FADD, FSUB, FMUL, FDIV, FREM, Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=59780&r1=59779&r2=59780&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Thu Nov 20 20:12:42 2008 @@ -190,7 +190,8 @@ SDValue visitBUILD_VECTOR(SDNode *N); SDValue visitCONCAT_VECTORS(SDNode *N); SDValue visitVECTOR_SHUFFLE(SDNode *N); - SDValue visitADDO(SDNode *N); + SDValue visitSADDO(SDNode *N); + SDValue visitUADDO(SDNode *N); SDValue XformToShuffleWithZero(SDNode *N); SDValue ReassociateOps(unsigned Opc, SDValue LHS, SDValue RHS); @@ -728,7 +729,8 @@ case ISD::BUILD_VECTOR: return visitBUILD_VECTOR(N); case ISD::CONCAT_VECTORS: return visitCONCAT_VECTORS(N); case ISD::VECTOR_SHUFFLE: return visitVECTOR_SHUFFLE(N); - case ISD::ADDO: return visitADDO(N); + case ISD::SADDO: return visitSADDO(N); + case ISD::UADDO: return visitUADDO(N); } return SDValue(); } @@ -5145,7 +5147,7 @@ return SDValue(); } -SDValue DAGCombiner::visitADDO(SDNode *N) { +SDValue DAGCombiner::visitSADDO(SDNode *N) { SDValue Chain = N->getOperand(2); SDValue LHS = N->getOperand(0); SDValue RHS = N->getOperand(1); @@ -5173,6 +5175,10 @@ return SDValue(N, 0); } +SDValue DAGCombiner::visitUADDO(SDNode *N) { + return SDValue(); +} + /// XformToShuffleWithZero - Returns a vector_shuffle if it able to transform /// an AND to a vector_shuffle with the destination vector and a zero vector. /// e.g. AND V, <0xffffffff, 0, 0xffffffff, 0>. ==> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=59780&r1=59779&r2=59780&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Thu Nov 20 20:12:42 2008 @@ -5151,7 +5151,8 @@ case ISD::CARRY_FALSE: return "carry_false"; case ISD::ADDC: return "addc"; case ISD::ADDE: return "adde"; - case ISD::ADDO: return "addo"; + case ISD::SADDO: return "saddo"; + case ISD::UADDO: return "uaddo"; case ISD::SUBC: return "subc"; case ISD::SUBE: return "sube"; case ISD::SHL_PARTS: return "shl_parts"; Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp?rev=59780&r1=59779&r2=59780&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Thu Nov 20 20:12:42 2008 @@ -4094,7 +4094,7 @@ } case Intrinsic::sadd_with_overflow: { - // Convert to "ISD::ADDO" instruction. + // Convert to "ISD::SADDO" instruction. SDValue Chain = getRoot(); SDValue Op1 = getValue(I.getOperand(1)); SDValue Op2 = getValue(I.getOperand(2)); @@ -4103,7 +4103,7 @@ MVT ValueVTs[] = { Ty, MVT::i1, MVT::Other }; SDValue Ops[] = { Op1, Op2, Chain }; - SDValue Result = DAG.getNode(ISD::ADDO, DAG.getVTList(&ValueVTs[0], 3), + SDValue Result = DAG.getNode(ISD::SADDO, DAG.getVTList(&ValueVTs[0], 3), &Ops[0], 3); setValue(&I, Result); @@ -4113,7 +4113,7 @@ return 0; } case Intrinsic::uadd_with_overflow: { - // TODO: Convert to "ISD::ADDC" instruction. + // TODO: Convert to "ISD::UADDO" instruction. return 0; } From isanbard at gmail.com Thu Nov 20 20:15:51 2008 From: isanbard at gmail.com (Bill Wendling) Date: Fri, 21 Nov 2008 02:15:51 -0000 Subject: [llvm-commits] [llvm] r59781 - /llvm/trunk/test/CodeGen/Generic/add-with-overflow.ll Message-ID: <200811210215.mAL2Fp6J021307@zion.cs.uiuc.edu> Author: void Date: Thu Nov 20 20:15:51 2008 New Revision: 59781 URL: http://llvm.org/viewvc/llvm-project?rev=59781&view=rev Log: Add generic test for add with overflow. Added: llvm/trunk/test/CodeGen/Generic/add-with-overflow.ll Added: llvm/trunk/test/CodeGen/Generic/add-with-overflow.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Generic/add-with-overflow.ll?rev=59781&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/Generic/add-with-overflow.ll (added) +++ llvm/trunk/test/CodeGen/Generic/add-with-overflow.ll Thu Nov 20 20:15:51 2008 @@ -0,0 +1,23 @@ +; RUN: llvm-as < %s | llc + + at ok = internal constant [4 x i8] c"%d\0A\00" + at no = internal constant [4 x i8] c"no\0A\00" + +define i1 @foo(i32 %v1, i32 %v2) nounwind { +entry: + %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2) + %sum = extractvalue {i32, i1} %t, 0 + %obit = extractvalue {i32, i1} %t, 1 + br i1 %obit, label %overflow, label %normal + +normal: + %t1 = tail call i32 (i8*, ...)* @printf( i8* getelementptr ([4 x i8]* @ok, i32 0, i32 0), i32 %sum ) nounwind + ret i1 true + +overflow: + %t2 = tail call i32 (i8*, ...)* @printf( i8* getelementptr ([4 x i8]* @no, i32 0, i32 0) ) nounwind + ret i1 false +} + +declare i32 @printf(i8*, ...) nounwind +declare {i32, i1} @llvm.sadd.with.overflow.i32(i32, i32) From gohman at apple.com Thu Nov 20 20:18:57 2008 From: gohman at apple.com (Dan Gohman) Date: Fri, 21 Nov 2008 02:18:57 -0000 Subject: [llvm-commits] [llvm] r59782 - in /llvm/trunk: include/llvm/CodeGen/ScheduleDAG.h lib/CodeGen/ScheduleDAG.cpp lib/CodeGen/ScheduleDAGPrinter.cpp lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Message-ID: <200811210218.mAL2IvuV021438@zion.cs.uiuc.edu> Author: djg Date: Thu Nov 20 20:18:56 2008 New Revision: 59782 URL: http://llvm.org/viewvc/llvm-project?rev=59782&view=rev Log: Rename SDep's isSpecial to isArtificial, to make this field a little less mysterious. Modified: llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h llvm/trunk/lib/CodeGen/ScheduleDAG.cpp llvm/trunk/lib/CodeGen/ScheduleDAGPrinter.cpp llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Modified: llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h?rev=59782&r1=59781&r2=59782&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h (original) +++ llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h Thu Nov 20 20:18:56 2008 @@ -42,12 +42,14 @@ /// cost of the depdenency, etc. struct SDep { SUnit *Dep; // Dependent - either a predecessor or a successor. - unsigned Reg; // If non-zero, this dep is a phy register dependency. + unsigned Reg; // If non-zero, this dep is a physreg dependency. int Cost; // Cost of the dependency. bool isCtrl : 1; // True iff it's a control dependency. - bool isSpecial : 1; // True iff it's a special ctrl dep added during sched. - SDep(SUnit *d, unsigned r, int t, bool c, bool s) - : Dep(d), Reg(r), Cost(t), isCtrl(c), isSpecial(s) {} + bool isArtificial : 1; // True iff it's an artificial ctrl dep added + // during sched that may be safely deleted if + // necessary. + SDep(SUnit *d, unsigned r, int t, bool c, bool a) + : Dep(d), Reg(r), Cost(t), isCtrl(c), isArtificial(a) {} }; /// SUnit - Scheduling unit. This is a node in the scheduling DAG. @@ -139,14 +141,14 @@ /// addPred - This adds the specified node as a pred of the current node if /// not already. This returns true if this is a new pred. - bool addPred(SUnit *N, bool isCtrl, bool isSpecial, + bool addPred(SUnit *N, bool isCtrl, bool isArtificial, unsigned PhyReg = 0, int Cost = 1) { for (unsigned i = 0, e = (unsigned)Preds.size(); i != e; ++i) if (Preds[i].Dep == N && - Preds[i].isCtrl == isCtrl && Preds[i].isSpecial == isSpecial) + Preds[i].isCtrl == isCtrl && Preds[i].isArtificial == isArtificial) return false; - Preds.push_back(SDep(N, PhyReg, Cost, isCtrl, isSpecial)); - N->Succs.push_back(SDep(this, PhyReg, Cost, isCtrl, isSpecial)); + Preds.push_back(SDep(N, PhyReg, Cost, isCtrl, isArtificial)); + N->Succs.push_back(SDep(this, PhyReg, Cost, isCtrl, isArtificial)); if (!isCtrl) { ++NumPreds; ++N->NumSuccs; @@ -158,15 +160,15 @@ return true; } - bool removePred(SUnit *N, bool isCtrl, bool isSpecial) { + bool removePred(SUnit *N, bool isCtrl, bool isArtificial) { for (SmallVector::iterator I = Preds.begin(), E = Preds.end(); I != E; ++I) - if (I->Dep == N && I->isCtrl == isCtrl && I->isSpecial == isSpecial) { + if (I->Dep == N && I->isCtrl == isCtrl && I->isArtificial == isArtificial) { bool FoundSucc = false; for (SmallVector::iterator II = N->Succs.begin(), EE = N->Succs.end(); II != EE; ++II) if (II->Dep == this && - II->isCtrl == isCtrl && II->isSpecial == isSpecial) { + II->isCtrl == isCtrl && II->isArtificial == isArtificial) { FoundSucc = true; N->Succs.erase(II); break; @@ -373,7 +375,7 @@ unsigned getOperand() const { return Operand; } const SUnit *getNode() const { return Node; } bool isCtrlDep() const { return Node->Preds[Operand].isCtrl; } - bool isSpecialDep() const { return Node->Preds[Operand].isSpecial; } + bool isArtificialDep() const { return Node->Preds[Operand].isArtificial; } }; template <> struct GraphTraits { Modified: llvm/trunk/lib/CodeGen/ScheduleDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ScheduleDAG.cpp?rev=59782&r1=59781&r2=59782&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/ScheduleDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/ScheduleDAG.cpp Thu Nov 20 20:18:56 2008 @@ -188,7 +188,7 @@ else cerr << " val #"; cerr << I->Dep << " - SU(" << I->Dep->NodeNum << ")"; - if (I->isSpecial) + if (I->isArtificial) cerr << " *"; cerr << "\n"; } @@ -202,7 +202,7 @@ else cerr << " val #"; cerr << I->Dep << " - SU(" << I->Dep->NodeNum << ")"; - if (I->isSpecial) + if (I->isArtificial) cerr << " *"; cerr << "\n"; } Modified: llvm/trunk/lib/CodeGen/ScheduleDAGPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ScheduleDAGPrinter.cpp?rev=59782&r1=59781&r2=59782&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/ScheduleDAGPrinter.cpp (original) +++ llvm/trunk/lib/CodeGen/ScheduleDAGPrinter.cpp Thu Nov 20 20:18:56 2008 @@ -50,7 +50,7 @@ /// edge, override this method. template static std::string getEdgeAttributes(const void *Node, EdgeIter EI) { - if (EI.isSpecialDep()) + if (EI.isArtificialDep()) return "color=cyan,style=dashed"; if (EI.isCtrlDep()) return "color=blue,style=dashed"; Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp?rev=59782&r1=59781&r2=59782&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp Thu Nov 20 20:18:56 2008 @@ -80,12 +80,12 @@ /// AddPred - This adds the specified node X as a predecessor of /// the current node Y if not already. /// This returns true if this is a new predecessor. - bool AddPred(SUnit *Y, SUnit *X, bool isCtrl, bool isSpecial, + bool AddPred(SUnit *Y, SUnit *X, bool isCtrl, bool isArtificial, unsigned PhyReg = 0, int Cost = 1); /// RemovePred - This removes the specified node N from the predecessors of /// the current node M. - bool RemovePred(SUnit *M, SUnit *N, bool isCtrl, bool isSpecial); + bool RemovePred(SUnit *M, SUnit *N, bool isCtrl, bool isArtificial); private: void ReleasePred(SUnit *SU, SUnit *PredSU, bool isChain); @@ -189,16 +189,16 @@ } /// AddPred - adds an edge from SUnit X to SUnit Y. -bool ScheduleDAGFast::AddPred(SUnit *Y, SUnit *X, bool isCtrl, bool isSpecial, - unsigned PhyReg, int Cost) { - return Y->addPred(X, isCtrl, isSpecial, PhyReg, Cost); +bool ScheduleDAGFast::AddPred(SUnit *Y, SUnit *X, bool isCtrl, + bool isArtificial, unsigned PhyReg, int Cost) { + return Y->addPred(X, isCtrl, isArtificial, PhyReg, Cost); } /// RemovePred - This removes the specified node N from the predecessors of /// the current node M. bool ScheduleDAGFast::RemovePred(SUnit *M, SUnit *N, - bool isCtrl, bool isSpecial) { - return M->removePred(N, isCtrl, isSpecial); + bool isCtrl, bool isArtificial) { + return M->removePred(N, isCtrl, isArtificial); } /// CopyAndMoveSuccessors - Clone the specified node and move its scheduled @@ -295,10 +295,10 @@ I != E; ++I) { if (I->isCtrl) ChainSuccs.push_back(SDep(I->Dep, I->Reg, I->Cost, - I->isCtrl, I->isSpecial)); + I->isCtrl, I->isArtificial)); else NodeSuccs.push_back(SDep(I->Dep, I->Reg, I->Cost, - I->isCtrl, I->isSpecial)); + I->isCtrl, I->isArtificial)); } if (ChainPred) { @@ -308,29 +308,29 @@ } for (unsigned i = 0, e = LoadPreds.size(); i != e; ++i) { SDep *Pred = &LoadPreds[i]; - RemovePred(SU, Pred->Dep, Pred->isCtrl, Pred->isSpecial); + RemovePred(SU, Pred->Dep, Pred->isCtrl, Pred->isArtificial); if (isNewLoad) { - AddPred(LoadSU, Pred->Dep, Pred->isCtrl, Pred->isSpecial, + AddPred(LoadSU, Pred->Dep, Pred->isCtrl, Pred->isArtificial, Pred->Reg, Pred->Cost); } } for (unsigned i = 0, e = NodePreds.size(); i != e; ++i) { SDep *Pred = &NodePreds[i]; - RemovePred(SU, Pred->Dep, Pred->isCtrl, Pred->isSpecial); - AddPred(NewSU, Pred->Dep, Pred->isCtrl, Pred->isSpecial, + RemovePred(SU, Pred->Dep, Pred->isCtrl, Pred->isArtificial); + AddPred(NewSU, Pred->Dep, Pred->isCtrl, Pred->isArtificial, Pred->Reg, Pred->Cost); } for (unsigned i = 0, e = NodeSuccs.size(); i != e; ++i) { SDep *Succ = &NodeSuccs[i]; - RemovePred(Succ->Dep, SU, Succ->isCtrl, Succ->isSpecial); - AddPred(Succ->Dep, NewSU, Succ->isCtrl, Succ->isSpecial, + RemovePred(Succ->Dep, SU, Succ->isCtrl, Succ->isArtificial); + AddPred(Succ->Dep, NewSU, Succ->isCtrl, Succ->isArtificial, Succ->Reg, Succ->Cost); } for (unsigned i = 0, e = ChainSuccs.size(); i != e; ++i) { SDep *Succ = &ChainSuccs[i]; - RemovePred(Succ->Dep, SU, Succ->isCtrl, Succ->isSpecial); + RemovePred(Succ->Dep, SU, Succ->isCtrl, Succ->isArtificial); if (isNewLoad) { - AddPred(Succ->Dep, LoadSU, Succ->isCtrl, Succ->isSpecial, + AddPred(Succ->Dep, LoadSU, Succ->isCtrl, Succ->isArtificial, Succ->Reg, Succ->Cost); } } @@ -353,7 +353,7 @@ // New SUnit has the exact same predecessors. for (SUnit::pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); I != E; ++I) - if (!I->isSpecial) { + if (!I->isArtificial) { AddPred(NewSU, I->Dep, I->isCtrl, false, I->Reg, I->Cost); NewSU->Depth = std::max(NewSU->Depth, I->Dep->Depth+1); } @@ -363,7 +363,7 @@ SmallVector, 4> DelDeps; for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); I != E; ++I) { - if (I->isSpecial) + if (I->isArtificial) continue; if (I->Dep->isScheduled) { NewSU->Height = std::max(NewSU->Height, I->Dep->Height+1); @@ -400,7 +400,7 @@ SmallVector, 4> DelDeps; for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); I != E; ++I) { - if (I->isSpecial) + if (I->isArtificial) continue; if (I->Dep->isScheduled) { AddPred(I->Dep, CopyToSU, I->isCtrl, false, I->Reg, I->Cost); Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp?rev=59782&r1=59781&r2=59782&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Thu Nov 20 20:18:56 2008 @@ -94,12 +94,12 @@ /// the current node Y if not already. /// This returns true if this is a new predecessor. /// Updates the topological ordering if required. - bool AddPred(SUnit *Y, SUnit *X, bool isCtrl, bool isSpecial, + bool AddPred(SUnit *Y, SUnit *X, bool isCtrl, bool isArtificial, unsigned PhyReg = 0, int Cost = 1); /// RemovePred - This removes the specified node N from the predecessors of /// the current node M. Updates the topological ordering if required. - bool RemovePred(SUnit *M, SUnit *N, bool isCtrl, bool isSpecial); + bool RemovePred(SUnit *M, SUnit *N, bool isCtrl, bool isArtificial); private: void ReleasePred(SUnit *SU, SUnit *PredSU, bool isChain); @@ -482,8 +482,8 @@ /// AddPred - adds an edge from SUnit X to SUnit Y. /// Updates the topological ordering if required. -bool ScheduleDAGRRList::AddPred(SUnit *Y, SUnit *X, bool isCtrl, bool isSpecial, - unsigned PhyReg, int Cost) { +bool ScheduleDAGRRList::AddPred(SUnit *Y, SUnit *X, bool isCtrl, + bool isArtificial, unsigned PhyReg, int Cost) { int UpperBound, LowerBound; LowerBound = Node2Index[Y->NodeNum]; UpperBound = Node2Index[X->NodeNum]; @@ -498,15 +498,15 @@ Shift(Visited, LowerBound, UpperBound); } // Now really insert the edge. - return Y->addPred(X, isCtrl, isSpecial, PhyReg, Cost); + return Y->addPred(X, isCtrl, isArtificial, PhyReg, Cost); } /// RemovePred - This removes the specified node N from the predecessors of /// the current node M. Updates the topological ordering if required. bool ScheduleDAGRRList::RemovePred(SUnit *M, SUnit *N, - bool isCtrl, bool isSpecial) { + bool isCtrl, bool isArtificial) { // InitDAGTopologicalSorting(); - return M->removePred(N, isCtrl, isSpecial); + return M->removePred(N, isCtrl, isArtificial); } /// DFS - Make a DFS traversal to mark all nodes reachable from SU and mark @@ -696,10 +696,10 @@ I != E; ++I) { if (I->isCtrl) ChainSuccs.push_back(SDep(I->Dep, I->Reg, I->Cost, - I->isCtrl, I->isSpecial)); + I->isCtrl, I->isArtificial)); else NodeSuccs.push_back(SDep(I->Dep, I->Reg, I->Cost, - I->isCtrl, I->isSpecial)); + I->isCtrl, I->isArtificial)); } if (ChainPred) { @@ -709,29 +709,29 @@ } for (unsigned i = 0, e = LoadPreds.size(); i != e; ++i) { SDep *Pred = &LoadPreds[i]; - RemovePred(SU, Pred->Dep, Pred->isCtrl, Pred->isSpecial); + RemovePred(SU, Pred->Dep, Pred->isCtrl, Pred->isArtificial); if (isNewLoad) { - AddPred(LoadSU, Pred->Dep, Pred->isCtrl, Pred->isSpecial, + AddPred(LoadSU, Pred->Dep, Pred->isCtrl, Pred->isArtificial, Pred->Reg, Pred->Cost); } } for (unsigned i = 0, e = NodePreds.size(); i != e; ++i) { SDep *Pred = &NodePreds[i]; - RemovePred(SU, Pred->Dep, Pred->isCtrl, Pred->isSpecial); - AddPred(NewSU, Pred->Dep, Pred->isCtrl, Pred->isSpecial, + RemovePred(SU, Pred->Dep, Pred->isCtrl, Pred->isArtificial); + AddPred(NewSU, Pred->Dep, Pred->isCtrl, Pred->isArtificial, Pred->Reg, Pred->Cost); } for (unsigned i = 0, e = NodeSuccs.size(); i != e; ++i) { SDep *Succ = &NodeSuccs[i]; - RemovePred(Succ->Dep, SU, Succ->isCtrl, Succ->isSpecial); - AddPred(Succ->Dep, NewSU, Succ->isCtrl, Succ->isSpecial, + RemovePred(Succ->Dep, SU, Succ->isCtrl, Succ->isArtificial); + AddPred(Succ->Dep, NewSU, Succ->isCtrl, Succ->isArtificial, Succ->Reg, Succ->Cost); } for (unsigned i = 0, e = ChainSuccs.size(); i != e; ++i) { SDep *Succ = &ChainSuccs[i]; - RemovePred(Succ->Dep, SU, Succ->isCtrl, Succ->isSpecial); + RemovePred(Succ->Dep, SU, Succ->isCtrl, Succ->isArtificial); if (isNewLoad) { - AddPred(Succ->Dep, LoadSU, Succ->isCtrl, Succ->isSpecial, + AddPred(Succ->Dep, LoadSU, Succ->isCtrl, Succ->isArtificial, Succ->Reg, Succ->Cost); } } @@ -758,7 +758,7 @@ // New SUnit has the exact same predecessors. for (SUnit::pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); I != E; ++I) - if (!I->isSpecial) { + if (!I->isArtificial) { AddPred(NewSU, I->Dep, I->isCtrl, false, I->Reg, I->Cost); NewSU->Depth = std::max(NewSU->Depth, I->Dep->Depth+1); } @@ -768,7 +768,7 @@ SmallVector, 4> DelDeps; for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); I != E; ++I) { - if (I->isSpecial) + if (I->isArtificial) continue; if (I->Dep->isScheduled) { NewSU->Height = std::max(NewSU->Height, I->Dep->Height+1); @@ -810,7 +810,7 @@ SmallVector, 4> DelDeps; for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); I != E; ++I) { - if (I->isSpecial) + if (I->isArtificial) continue; if (I->Dep->isScheduled) { CopyToSU->Height = std::max(CopyToSU->Height, I->Dep->Height+1); From isanbard at gmail.com Thu Nov 20 20:22:59 2008 From: isanbard at gmail.com (Bill Wendling) Date: Fri, 21 Nov 2008 02:22:59 -0000 Subject: [llvm-commits] [llvm] r59783 - in /llvm/trunk/lib/CodeGen/SelectionDAG: DAGCombiner.cpp SelectionDAGBuild.cpp Message-ID: <200811210223.mAL2N0o6021598@zion.cs.uiuc.edu> Author: void Date: Thu Nov 20 20:22:59 2008 New Revision: 59783 URL: http://llvm.org/viewvc/llvm-project?rev=59783&view=rev Log: Remove chains. Unnecessary. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=59783&r1=59782&r2=59783&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Thu Nov 20 20:22:59 2008 @@ -5148,7 +5148,6 @@ } SDValue DAGCombiner::visitSADDO(SDNode *N) { - SDValue Chain = N->getOperand(2); SDValue LHS = N->getOperand(0); SDValue RHS = N->getOperand(1); @@ -5157,17 +5156,16 @@ SDValue Cmp = DAG.getSetCC(MVT::i1, Sum, LHS, ISD::SETLT); AddToWorkList(Cmp.getNode()); - MVT ValueVTs[] = { LHS.getValueType(), MVT::i1, MVT::Other }; - SDValue Ops[] = { Sum, Cmp, Chain }; + MVT ValueVTs[] = { LHS.getValueType(), MVT::i1 }; + SDValue Ops[] = { Sum, Cmp }; - SDValue Merge = DAG.getMergeValues(DAG.getVTList(&ValueVTs[0], 3), - &Ops[0], 3); + SDValue Merge = DAG.getMergeValues(DAG.getVTList(&ValueVTs[0], 2), + &Ops[0], 2); SDNode *MNode = Merge.getNode(); AddToWorkList(MNode); DAG.ReplaceAllUsesOfValueWith(SDValue(N, 0), SDValue(MNode, 0)); DAG.ReplaceAllUsesOfValueWith(SDValue(N, 1), SDValue(MNode, 1)); - DAG.ReplaceAllUsesOfValueWith(SDValue(N, 2), SDValue(MNode, 2)); // Since the node is now dead, remove it from the graph. removeFromWorkList(N); Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp?rev=59783&r1=59782&r2=59783&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Thu Nov 20 20:22:59 2008 @@ -4095,21 +4095,17 @@ case Intrinsic::sadd_with_overflow: { // Convert to "ISD::SADDO" instruction. - SDValue Chain = getRoot(); SDValue Op1 = getValue(I.getOperand(1)); SDValue Op2 = getValue(I.getOperand(2)); MVT Ty = Op1.getValueType(); - MVT ValueVTs[] = { Ty, MVT::i1, MVT::Other }; - SDValue Ops[] = { Op1, Op2, Chain }; + MVT ValueVTs[] = { Ty, MVT::i1 }; + SDValue Ops[] = { Op1, Op2 }; - SDValue Result = DAG.getNode(ISD::SADDO, DAG.getVTList(&ValueVTs[0], 3), - &Ops[0], 3); + SDValue Result = DAG.getNode(ISD::SADDO, DAG.getVTList(&ValueVTs[0], 2), + &Ops[0], 2); setValue(&I, Result); - - unsigned NumArgRegs = Result.getNode()->getNumValues() - 1; - DAG.setRoot(SDValue(Result.getNode(), NumArgRegs)); return 0; } case Intrinsic::uadd_with_overflow: { From isanbard at gmail.com Thu Nov 20 20:24:44 2008 From: isanbard at gmail.com (Bill Wendling) Date: Fri, 21 Nov 2008 02:24:44 -0000 Subject: [llvm-commits] [llvm] r59784 - /llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h Message-ID: <200811210224.mAL2Ois5021657@zion.cs.uiuc.edu> Author: void Date: Thu Nov 20 20:24:44 2008 New Revision: 59784 URL: http://llvm.org/viewvc/llvm-project?rev=59784&view=rev Log: Update comment to reflect a semblance of reality. Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h?rev=59784&r1=59783&r2=59784&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h (original) +++ llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h Thu Nov 20 20:24:44 2008 @@ -250,13 +250,12 @@ // values. ADDE, SUBE, - // RESULT, BOOL, OUTCHAIN = [SU]ADDO(INCHAIN, LHS, RHS) - Overflow-aware - // node for arithmetic operations. This node takes two operands: the normal - // lhs and rhs to the add. It produces two results: the normal result of the - // add, and a boolean to indicate if an overflow occured (this isn't a flag, - // because it may be stored to memory, etc.). This node is generated from - // the llvm.sadd.with.overflow intrinsic. It is lowered by target-dependent - // code. + // RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for arithmetic + // operations. These nodes takes two operands: the normal lhs and rhs to the + // add. They produce two results: the normal result of the add, and a + // boolean to indicate if an overflow occured (*not* a flag, because it may + // be stored to memory, etc.). These nodes is generated from the + // llvm.[su]add.with.overflow intrinsics. SADDO, UADDO, // Simple binary floating point operators. From gohman at apple.com Thu Nov 20 20:27:52 2008 From: gohman at apple.com (Dan Gohman) Date: Fri, 21 Nov 2008 02:27:52 -0000 Subject: [llvm-commits] [llvm] r59785 - in /llvm/trunk: include/llvm/CodeGen/ScheduleDAG.h lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Message-ID: <200811210227.mAL2RrN0021784@zion.cs.uiuc.edu> Author: djg Date: Thu Nov 20 20:27:52 2008 New Revision: 59785 URL: http://llvm.org/viewvc/llvm-project?rev=59785&view=rev Log: Add a flag to SDep for tracking which edges are anti-dependence edges. Modified: llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Modified: llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h?rev=59785&r1=59784&r2=59785&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h (original) +++ llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h Thu Nov 20 20:27:52 2008 @@ -48,8 +48,10 @@ bool isArtificial : 1; // True iff it's an artificial ctrl dep added // during sched that may be safely deleted if // necessary. - SDep(SUnit *d, unsigned r, int t, bool c, bool a) - : Dep(d), Reg(r), Cost(t), isCtrl(c), isArtificial(a) {} + bool isAntiDep : 1; // True iff it's an anti-dependency (on a physical + // register. + SDep(SUnit *d, unsigned r, int t, bool c, bool a, bool anti) + : Dep(d), Reg(r), Cost(t), isCtrl(c), isArtificial(a), isAntiDep(anti) {} }; /// SUnit - Scheduling unit. This is a node in the scheduling DAG. @@ -140,15 +142,17 @@ } /// addPred - This adds the specified node as a pred of the current node if - /// not already. This returns true if this is a new pred. + /// not already. It also adds the current node as a successor of the + /// specified node. This returns true if this is a new pred. bool addPred(SUnit *N, bool isCtrl, bool isArtificial, - unsigned PhyReg = 0, int Cost = 1) { + unsigned PhyReg = 0, int Cost = 1, bool isAntiDep = false) { for (unsigned i = 0, e = (unsigned)Preds.size(); i != e; ++i) if (Preds[i].Dep == N && Preds[i].isCtrl == isCtrl && Preds[i].isArtificial == isArtificial) return false; - Preds.push_back(SDep(N, PhyReg, Cost, isCtrl, isArtificial)); - N->Succs.push_back(SDep(this, PhyReg, Cost, isCtrl, isArtificial)); + Preds.push_back(SDep(N, PhyReg, Cost, isCtrl, isArtificial, isAntiDep)); + N->Succs.push_back(SDep(this, PhyReg, Cost, isCtrl, + isArtificial, isAntiDep)); if (!isCtrl) { ++NumPreds; ++N->NumSuccs; Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp?rev=59785&r1=59784&r2=59785&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp Thu Nov 20 20:27:52 2008 @@ -287,18 +287,18 @@ if (I->isCtrl) ChainPred = I->Dep; else if (I->Dep->getNode() && I->Dep->getNode()->isOperandOf(LoadNode)) - LoadPreds.push_back(SDep(I->Dep, I->Reg, I->Cost, false, false)); + LoadPreds.push_back(SDep(I->Dep, I->Reg, I->Cost, false, false, false)); else - NodePreds.push_back(SDep(I->Dep, I->Reg, I->Cost, false, false)); + NodePreds.push_back(SDep(I->Dep, I->Reg, I->Cost, false, false, false)); } for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); I != E; ++I) { if (I->isCtrl) ChainSuccs.push_back(SDep(I->Dep, I->Reg, I->Cost, - I->isCtrl, I->isArtificial)); + I->isCtrl, I->isArtificial, I->isAntiDep)); else NodeSuccs.push_back(SDep(I->Dep, I->Reg, I->Cost, - I->isCtrl, I->isArtificial)); + I->isCtrl, I->isArtificial, I->isAntiDep)); } if (ChainPred) { Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp?rev=59785&r1=59784&r2=59785&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Thu Nov 20 20:27:52 2008 @@ -688,18 +688,18 @@ if (I->isCtrl) ChainPred = I->Dep; else if (I->Dep->getNode() && I->Dep->getNode()->isOperandOf(LoadNode)) - LoadPreds.push_back(SDep(I->Dep, I->Reg, I->Cost, false, false)); + LoadPreds.push_back(SDep(I->Dep, I->Reg, I->Cost, false, false, false)); else - NodePreds.push_back(SDep(I->Dep, I->Reg, I->Cost, false, false)); + NodePreds.push_back(SDep(I->Dep, I->Reg, I->Cost, false, false, false)); } for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); I != E; ++I) { if (I->isCtrl) ChainSuccs.push_back(SDep(I->Dep, I->Reg, I->Cost, - I->isCtrl, I->isArtificial)); + I->isCtrl, I->isArtificial, I->isAntiDep)); else NodeSuccs.push_back(SDep(I->Dep, I->Reg, I->Cost, - I->isCtrl, I->isArtificial)); + I->isCtrl, I->isArtificial, I->isAntiDep)); } if (ChainPred) { From isanbard at gmail.com Thu Nov 20 20:33:36 2008 From: isanbard at gmail.com (Bill Wendling) Date: Fri, 21 Nov 2008 02:33:36 -0000 Subject: [llvm-commits] [llvm] r59786 - /llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Message-ID: <200811210233.mAL2XaR0022000@zion.cs.uiuc.edu> Author: void Date: Thu Nov 20 20:33:36 2008 New Revision: 59786 URL: http://llvm.org/viewvc/llvm-project?rev=59786&view=rev Log: Generate code for llvm.uadd.with.overflow intrinsic. No conversion support yet. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp?rev=59786&r1=59785&r2=59786&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Thu Nov 20 20:33:36 2008 @@ -4109,7 +4109,18 @@ return 0; } case Intrinsic::uadd_with_overflow: { - // TODO: Convert to "ISD::UADDO" instruction. + // Convert to "ISD::UADDO" instruction. + SDValue Op1 = getValue(I.getOperand(1)); + SDValue Op2 = getValue(I.getOperand(2)); + MVT Ty = Op1.getValueType(); + + MVT ValueVTs[] = { Ty, MVT::i1 }; + SDValue Ops[] = { Op1, Op2 }; + + SDValue Result = DAG.getNode(ISD::UADDO, DAG.getVTList(&ValueVTs[0], 2), + &Ops[0], 2); + + setValue(&I, Result); return 0; } From gohman at apple.com Thu Nov 20 20:38:22 2008 From: gohman at apple.com (Dan Gohman) Date: Fri, 21 Nov 2008 02:38:22 -0000 Subject: [llvm-commits] [llvm] r59787 - /llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp Message-ID: <200811210238.mAL2cMTc022196@zion.cs.uiuc.edu> Author: djg Date: Thu Nov 20 20:38:21 2008 New Revision: 59787 URL: http://llvm.org/viewvc/llvm-project?rev=59787&view=rev Log: Set the isAntiDep flag in the MachineInstr scheduler. Modified: llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp Modified: llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp?rev=59787&r1=59786&r2=59787&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp (original) +++ llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp Thu Nov 20 20:38:21 2008 @@ -53,7 +53,7 @@ // Optionally add output and anti dependences. if (Def && Def != SU) Def->addPred(SU, /*isCtrl=*/true, /*isSpecial=*/false, - /*PhyReg=*/Reg, Cost); + /*PhyReg=*/Reg, Cost, /*isAntiDep=*/MO.isUse()); for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { SUnit *&Def = Defs[*Alias]; if (Def && Def != SU) From isanbard at gmail.com Thu Nov 20 20:38:44 2008 From: isanbard at gmail.com (Bill Wendling) Date: Fri, 21 Nov 2008 02:38:44 -0000 Subject: [llvm-commits] [llvm] r59788 - /llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Message-ID: <200811210238.mAL2ci1Z022226@zion.cs.uiuc.edu> Author: void Date: Thu Nov 20 20:38:44 2008 New Revision: 59788 URL: http://llvm.org/viewvc/llvm-project?rev=59788&view=rev Log: Combine the two add with overflow intrinsics lowerings. They differ only in DAG node type. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp?rev=59788&r1=59787&r2=59788&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Thu Nov 20 20:38:44 2008 @@ -4093,8 +4093,8 @@ return 0; } + case Intrinsic::uadd_with_overflow: case Intrinsic::sadd_with_overflow: { - // Convert to "ISD::SADDO" instruction. SDValue Op1 = getValue(I.getOperand(1)); SDValue Op2 = getValue(I.getOperand(2)); MVT Ty = Op1.getValueType(); @@ -4102,23 +4102,10 @@ MVT ValueVTs[] = { Ty, MVT::i1 }; SDValue Ops[] = { Op1, Op2 }; - SDValue Result = DAG.getNode(ISD::SADDO, DAG.getVTList(&ValueVTs[0], 2), - &Ops[0], 2); - - setValue(&I, Result); - return 0; - } - case Intrinsic::uadd_with_overflow: { - // Convert to "ISD::UADDO" instruction. - SDValue Op1 = getValue(I.getOperand(1)); - SDValue Op2 = getValue(I.getOperand(2)); - MVT Ty = Op1.getValueType(); - - MVT ValueVTs[] = { Ty, MVT::i1 }; - SDValue Ops[] = { Op1, Op2 }; - - SDValue Result = DAG.getNode(ISD::UADDO, DAG.getVTList(&ValueVTs[0], 2), - &Ops[0], 2); + SDValue Result = + DAG.getNode((Intrinsic == Intrinsic::sadd_with_overflow) ? + ISD::SADDO : ISD::UADDO, + DAG.getVTList(&ValueVTs[0], 2), &Ops[0], 2); setValue(&I, Result); return 0; From scottm at aero.org Thu Nov 20 20:56:16 2008 From: scottm at aero.org (Scott Michel) Date: Fri, 21 Nov 2008 02:56:16 -0000 Subject: [llvm-commits] [llvm] r59790 - in /llvm/trunk: lib/Target/CellSPU/SPUISelDAGToDAG.cpp lib/Target/CellSPU/SPUISelLowering.cpp lib/Target/CellSPU/SPUInstrInfo.cpp lib/Target/CellSPU/SPUInstrInfo.td test/CodeGen/CellSPU/loads.ll test/CodeGen/CellSPU/stores.ll Message-ID: <200811210256.mAL2uGp0022829@zion.cs.uiuc.edu> Author: pingbak Date: Thu Nov 20 20:56:16 2008 New Revision: 59790 URL: http://llvm.org/viewvc/llvm-project?rev=59790&view=rev Log: CellSPU: (a) Fix bgs 3052, 3057 (b) Incorporate Duncan's suggestions re: i1 promotion (c) Indentation updates. Added: llvm/trunk/test/CodeGen/CellSPU/loads.ll llvm/trunk/test/CodeGen/CellSPU/stores.ll Modified: llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.cpp llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td Modified: llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp?rev=59790&r1=59789&r2=59790&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp Thu Nov 20 20:56:16 2008 @@ -430,8 +430,8 @@ SPUDAGToDAGISel::SelectDFormAddr(SDValue Op, SDValue N, SDValue &Base, SDValue &Index) { return DFormAddressPredicate(Op, N, Base, Index, - SPUFrameInfo::minFrameOffset(), - SPUFrameInfo::maxFrameOffset()); + SPUFrameInfo::minFrameOffset(), + SPUFrameInfo::maxFrameOffset()); } bool @@ -544,7 +544,35 @@ Base = CurDAG->getTargetConstant(0, N.getValueType()); Index = N; return true; + } else if (Opc == ISD::Register || Opc == ISD::CopyFromReg) { + unsigned OpOpc = Op.getOpcode(); + + if (OpOpc == ISD::STORE || OpOpc == ISD::LOAD) { + // Direct load/store without getelementptr + SDValue Addr, Offs; + + // Get the register from CopyFromReg + if (Opc == ISD::CopyFromReg) + Addr = N.getOperand(1); + else + Addr = N; // Register + + if (OpOpc == ISD::STORE) + Offs = Op.getOperand(3); + else + Offs = Op.getOperand(2); // LOAD + + if (Offs.getOpcode() == ISD::Constant || Offs.getOpcode() == ISD::UNDEF) { + if (Offs.getOpcode() == ISD::UNDEF) + Offs = CurDAG->getTargetConstant(0, Offs.getValueType()); + + Base = Offs; + Index = Addr; + return true; + } + } } + return false; } @@ -554,21 +582,27 @@ \arg Base The base pointer operand \arg Index The offset/index operand - If the address \a N can be expressed as a [r + s10imm] address, returns false. - Otherwise, creates two operands, Base and Index that will become the [r+r] - address. + If the address \a N can be expressed as an A-form or D-form address, returns + false. Otherwise, creates two operands, Base and Index that will become the + (r)(r) X-form address. */ bool SPUDAGToDAGISel::SelectXFormAddr(SDValue Op, SDValue N, SDValue &Base, SDValue &Index) { - if (SelectAFormAddr(Op, N, Base, Index) - || SelectDFormAddr(Op, N, Base, Index)) - return false; - - // All else fails, punt and use an X-form address: - Base = N.getOperand(0); - Index = N.getOperand(1); - return true; + if (!SelectAFormAddr(Op, N, Base, Index) + && !SelectDFormAddr(Op, N, Base, Index)) { + // default form of a X-form address is r(r) in operands 0 and 1: + SDValue Op0 = N.getOperand(0); + SDValue Op1 = N.getOperand(1); + + if (Op0.getOpcode() == ISD::Register && Op1.getOpcode() == ISD::Register) { + Base = Op0; + Index = Op1; + return true; + } + } + + return false; } //! Convert the operand from a target-independent to a target-specific node Modified: llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp?rev=59790&r1=59789&r2=59790&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp (original) +++ llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp Thu Nov 20 20:56:16 2008 @@ -165,8 +165,7 @@ setOperationAction(ISD::STORE, VT, Custom); } - // Custom lower BRCOND for i1, i8 to "promote" the result to - // i32 and i16, respectively. + // Custom lower BRCOND for i8 to "promote" the result to i16 setOperationAction(ISD::BRCOND, MVT::Other, Custom); // Expand the jumptable branches @@ -215,7 +214,8 @@ setOperationAction(ISD::SHL, MVT::i8, Custom); setOperationAction(ISD::SRL, MVT::i8, Custom); setOperationAction(ISD::SRA, MVT::i8, Custom); - // And SPU needs custom lowering for shift left/right for i64 + + // SPU needs custom lowering for shift left/right for i64 setOperationAction(ISD::SHL, MVT::i64, Custom); setOperationAction(ISD::SRL, MVT::i64, Custom); setOperationAction(ISD::SRA, MVT::i64, Custom); @@ -223,7 +223,13 @@ // Custom lower i8, i32 and i64 multiplications setOperationAction(ISD::MUL, MVT::i8, Custom); setOperationAction(ISD::MUL, MVT::i32, Custom); - setOperationAction(ISD::MUL, MVT::i64, Expand); + setOperationAction(ISD::MUL, MVT::i64, Expand); // libcall + + // SMUL_LOHI, UMUL_LOHI + setOperationAction(ISD::SMUL_LOHI, MVT::i32, Custom); + setOperationAction(ISD::UMUL_LOHI, MVT::i32, Custom); + setOperationAction(ISD::SMUL_LOHI, MVT::i64, Custom); + setOperationAction(ISD::UMUL_LOHI, MVT::i64, Custom); // Need to custom handle (some) common i8, i64 math ops setOperationAction(ISD::ADD, MVT::i64, Custom); @@ -247,13 +253,11 @@ // SPU has a version of select that implements (a&~c)|(b&c), just like // select ought to work: - setOperationAction(ISD::SELECT, MVT::i1, Promote); setOperationAction(ISD::SELECT, MVT::i8, Legal); setOperationAction(ISD::SELECT, MVT::i16, Legal); setOperationAction(ISD::SELECT, MVT::i32, Legal); setOperationAction(ISD::SELECT, MVT::i64, Expand); - setOperationAction(ISD::SETCC, MVT::i1, Promote); setOperationAction(ISD::SETCC, MVT::i8, Legal); setOperationAction(ISD::SETCC, MVT::i16, Legal); setOperationAction(ISD::SETCC, MVT::i32, Legal); @@ -299,7 +303,7 @@ // We want to legalize GlobalAddress and ConstantPool nodes into the // appropriate instructions to materialize the address. - for (unsigned sctype = (unsigned) MVT::i1; sctype < (unsigned) MVT::f128; + for (unsigned sctype = (unsigned) MVT::i8; sctype < (unsigned) MVT::f128; ++sctype) { MVT VT = (MVT::SimpleValueType)sctype; @@ -699,8 +703,7 @@ int chunk_offset, slot_offset; bool was16aligned; - // The vector type we really want to load from the 16-byte chunk, except - // in the case of MVT::i1, which has to be v16i8. + // The vector type we really want to load from the 16-byte chunk. MVT vecVT = MVT::getVectorVT(VT, (128 / VT.getSizeInBits())), stVecVT = MVT::getVectorVT(StVT, (128 / StVT.getSizeInBits())); @@ -908,7 +911,7 @@ return SDValue(); } -//! Lower MVT::i1, MVT::i8 brcond to a promoted type (MVT::i32, MVT::i16) +//! Lower MVT::i8 brcond to a promoted type (MVT::i32, MVT::i16) static SDValue LowerBRCOND(SDValue Op, SelectionDAG &DAG) { @@ -916,8 +919,8 @@ MVT CondVT = Cond.getValueType(); MVT CondNVT; - if (CondVT == MVT::i1 || CondVT == MVT::i8) { - CondNVT = (CondVT == MVT::i1 ? MVT::i32 : MVT::i16); + if (CondVT == MVT::i8) { + CondNVT = MVT::i16; return DAG.getNode(ISD::BRCOND, Op.getValueType(), Op.getOperand(0), DAG.getNode(ISD::ZERO_EXTEND, CondNVT, Op.getOperand(1)), @@ -957,37 +960,37 @@ switch (ObjectVT.getSimpleVT()) { default: { - cerr << "LowerFORMAL_ARGUMENTS Unhandled argument type: " - << ObjectVT.getMVTString() - << "\n"; - abort(); + cerr << "LowerFORMAL_ARGUMENTS Unhandled argument type: " + << ObjectVT.getMVTString() + << "\n"; + abort(); } case MVT::i8: - ArgRegClass = &SPU::R8CRegClass; - break; + ArgRegClass = &SPU::R8CRegClass; + break; case MVT::i16: - ArgRegClass = &SPU::R16CRegClass; - break; + ArgRegClass = &SPU::R16CRegClass; + break; case MVT::i32: - ArgRegClass = &SPU::R32CRegClass; - break; + ArgRegClass = &SPU::R32CRegClass; + break; case MVT::i64: - ArgRegClass = &SPU::R64CRegClass; - break; + ArgRegClass = &SPU::R64CRegClass; + break; case MVT::f32: - ArgRegClass = &SPU::R32FPRegClass; - break; + ArgRegClass = &SPU::R32FPRegClass; + break; case MVT::f64: - ArgRegClass = &SPU::R64FPRegClass; - break; + ArgRegClass = &SPU::R64FPRegClass; + break; case MVT::v2f64: case MVT::v4f32: case MVT::v2i64: case MVT::v4i32: case MVT::v8i16: case MVT::v16i8: - ArgRegClass = &SPU::VECREGRegClass; - break; + ArgRegClass = &SPU::VECREGRegClass; + break; } unsigned VReg = RegInfo.createVirtualRegister(ArgRegClass); @@ -2103,7 +2106,6 @@ // zero fill uppper part of preferred slot, don't care about the // other slots: unsigned int mask_val; - if (i <= prefslot_end) { mask_val = ((i < prefslot_begin) @@ -2884,7 +2886,7 @@ } } // Otherwise, return unchanged. -#if 1 +#ifdef NDEBUG if (Result.getNode()) { DEBUG(cerr << "\nReplace.SPU: "); DEBUG(N->dump(&DAG)); Modified: llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.cpp?rev=59790&r1=59789&r2=59790&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.cpp (original) +++ llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.cpp Thu Nov 20 20:56:16 2008 @@ -161,7 +161,7 @@ case SPU::STQDr64: case SPU::STQDr32: case SPU::STQDr16: - // case SPU::STQDr8: + case SPU::STQDr8: case SPU::STQXv16i8: case SPU::STQXv8i16: case SPU::STQXv4i32: @@ -171,7 +171,7 @@ case SPU::STQXr64: case SPU::STQXr32: case SPU::STQXr16: - // case SPU::STQXr8: + case SPU::STQXr8: if (MI->getOperand(1).isImm() && !MI->getOperand(1).getImm() && MI->getOperand(2).isFI()) { FrameIndex = MI->getOperand(2).getIndex(); Modified: llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td?rev=59790&r1=59789&r2=59790&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td (original) +++ llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td Thu Nov 20 20:56:16 2008 @@ -3494,26 +3494,62 @@ "fi\t$rT, $rA, $rB", SPrecFP, [(set R32FP:$rT, (SPUinterpolate R32FP:$rA, R32FP:$rB))]>; -// Floating Compare Equal +//-------------------------------------------------------------------------- +// Basic single precision floating point comparisons: +// +// Note: There is no support on SPU for single precision NaN. Consequently, +// ordered and unordered comparisons are the same. +//-------------------------------------------------------------------------- + def FCEQf32 : RRForm<0b01000011110, (outs R32C:$rT), (ins R32FP:$rA, R32FP:$rB), "fceq\t$rT, $rA, $rB", SPrecFP, - [(set R32C:$rT, (setoeq R32FP:$rA, R32FP:$rB))]>; + [(set R32C:$rT, (setueq R32FP:$rA, R32FP:$rB))]>; + +def : Pat<(setoeq R32FP:$rA, R32FP:$rB), + (FCEQf32 R32FP:$rA, R32FP:$rB)>; def FCMEQf32 : RRForm<0b01010011110, (outs R32C:$rT), (ins R32FP:$rA, R32FP:$rB), "fcmeq\t$rT, $rA, $rB", SPrecFP, - [(set R32C:$rT, (setoeq (fabs R32FP:$rA), (fabs R32FP:$rB)))]>; + [(set R32C:$rT, (setueq (fabs R32FP:$rA), (fabs R32FP:$rB)))]>; + +def : Pat<(setoeq (fabs R32FP:$rA), (fabs R32FP:$rB)), + (FCMEQf32 R32FP:$rA, R32FP:$rB)>; def FCGTf32 : RRForm<0b01000011010, (outs R32C:$rT), (ins R32FP:$rA, R32FP:$rB), "fcgt\t$rT, $rA, $rB", SPrecFP, - [(set R32C:$rT, (setogt R32FP:$rA, R32FP:$rB))]>; + [(set R32C:$rT, (setugt R32FP:$rA, R32FP:$rB))]>; + +def : Pat<(setugt R32FP:$rA, R32FP:$rB), + (FCGTf32 R32FP:$rA, R32FP:$rB)>; def FCMGTf32 : RRForm<0b01010011010, (outs R32C:$rT), (ins R32FP:$rA, R32FP:$rB), "fcmgt\t$rT, $rA, $rB", SPrecFP, - [(set R32C:$rT, (setogt (fabs R32FP:$rA), (fabs R32FP:$rB)))]>; + [(set R32C:$rT, (setugt (fabs R32FP:$rA), (fabs R32FP:$rB)))]>; + +def : Pat<(setugt (fabs R32FP:$rA), (fabs R32FP:$rB)), + (FCMGTf32 R32FP:$rA, R32FP:$rB)>; + +//-------------------------------------------------------------------------- +// Single precision floating point comparisons and SETCC equivalents: +//-------------------------------------------------------------------------- + +def : SETCCNegCondReg; +def : SETCCNegCondReg; + +def : SETCCBinOpReg; +def : SETCCBinOpReg; + +def : SETCCBinOpReg; +def : SETCCBinOpReg; + +def : Pat<(setule R32FP:$rA, R32FP:$rB), + (XORIr32 (FCGTf32 R32FP:$rA, R32FP:$rB), 0xffffffff)>; +def : Pat<(setole R32FP:$rA, R32FP:$rB), + (XORIr32 (FCGTf32 R32FP:$rA, R32FP:$rB), 0xffffffff)>; // FP Status and Control Register Write // Why isn't rT a don't care in the ISA? Added: llvm/trunk/test/CodeGen/CellSPU/loads.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/loads.ll?rev=59790&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/CellSPU/loads.ll (added) +++ llvm/trunk/test/CodeGen/CellSPU/loads.ll Thu Nov 20 20:56:16 2008 @@ -0,0 +1,20 @@ +; RUN: llvm-as -o - %s | llc -march=cellspu > %t1.s +; RUN: grep {lqd.*0(\$3)} %t1.s | count 1 +; RUN: grep {lqd.*16(\$3)} %t1.s | count 1 + +; ModuleID = 'loads.bc' +target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128" +target triple = "spu" + +define <4 x float> @load_v4f32_1(<4 x float>* %a) nounwind readonly { +entry: + %tmp1 = load <4 x float>* %a + ret <4 x float> %tmp1 +} + +define <4 x float> @load_v4f32_2(<4 x float>* %a) nounwind readonly { +entry: + %arrayidx = getelementptr <4 x float>* %a, i32 1 ; <<4 x float>*> [#uses=1] + %tmp1 = load <4 x float>* %arrayidx ; <<4 x float>> [#uses=1] + ret <4 x float> %tmp1 +} Added: llvm/trunk/test/CodeGen/CellSPU/stores.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/stores.ll?rev=59790&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/CellSPU/stores.ll (added) +++ llvm/trunk/test/CodeGen/CellSPU/stores.ll Thu Nov 20 20:56:16 2008 @@ -0,0 +1,22 @@ +; RUN: llvm-as -o - %s | llc -march=cellspu > %t1.s +; RUN: grep {stqd.*0(\$3)} %t1.s | count 1 +; RUN: grep {stqd.*16(\$3)} %t1.s | count 1 +; RUN: grep 16256 %t1.s | count 1 +; RUN: grep 16384 %t1.s | count 1 + +; ModuleID = 'stores.bc' +target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128" +target triple = "spu" + +define void @store_v4f32_1(<4 x float>* %a) nounwind { +entry: + store <4 x float> < float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00 >, <4 x float>* %a + ret void +} + +define void @store_v4f32_2(<4 x float>* %a) nounwind { +entry: + %arrayidx = getelementptr <4 x float>* %a, i32 1 + store <4 x float> < float 2.000000e+00, float 2.000000e+00, float 2.000000e+00, float 2.000000e+00 >, <4 x float>* %arrayidx + ret void +} From clattner at apple.com Thu Nov 20 22:00:49 2008 From: clattner at apple.com (Chris Lattner) Date: Thu, 20 Nov 2008 20:00:49 -0800 Subject: [llvm-commits] [llvm] r59784 - /llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h In-Reply-To: <200811210224.mAL2Ois5021657@zion.cs.uiuc.edu> References: <200811210224.mAL2Ois5021657@zion.cs.uiuc.edu> Message-ID: <7198D900-896E-4B78-B532-9EF3A50CD925@apple.com> On Nov 20, 2008, at 6:24 PM, Bill Wendling wrote: > Author: void > Date: Thu Nov 20 20:24:44 2008 > New Revision: 59784 > > URL: http://llvm.org/viewvc/llvm-project?rev=59784&view=rev > Log: > Update comment to reflect a semblance of reality. Awesome, thanks Bill! -Chris > > > Modified: > llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h > > Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h?rev=59784&r1=59783&r2=59784&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h (original) > +++ llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h Thu Nov 20 > 20:24:44 2008 > @@ -250,13 +250,12 @@ > // values. > ADDE, SUBE, > > - // RESULT, BOOL, OUTCHAIN = [SU]ADDO(INCHAIN, LHS, RHS) - > Overflow-aware > - // node for arithmetic operations. This node takes two > operands: the normal > - // lhs and rhs to the add. It produces two results: the normal > result of the > - // add, and a boolean to indicate if an overflow occured (this > isn't a flag, > - // because it may be stored to memory, etc.). This node is > generated from > - // the llvm.sadd.with.overflow intrinsic. It is lowered by > target-dependent > - // code. > + // RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for > arithmetic > + // operations. These nodes takes two operands: the normal lhs > and rhs to the > + // add. They produce two results: the normal result of the add, > and a > + // boolean to indicate if an overflow occured (*not* a flag, > because it may > + // be stored to memory, etc.). These nodes is generated from the > + // llvm.[su]add.with.overflow intrinsics. > SADDO, UADDO, > > // Simple binary floating point operators. > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From wangmp at apple.com Thu Nov 20 22:25:22 2008 From: wangmp at apple.com (Mon P Wang) Date: Fri, 21 Nov 2008 04:25:22 -0000 Subject: [llvm-commits] [llvm] r59792 - /llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Message-ID: <200811210425.mAL4PN5t025947@zion.cs.uiuc.edu> Author: wangmp Date: Thu Nov 20 22:25:21 2008 New Revision: 59792 URL: http://llvm.org/viewvc/llvm-project?rev=59792&view=rev Log: Clean up normalization of shuffles Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp?rev=59792&r1=59791&r2=59792&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Thu Nov 20 22:25:21 2008 @@ -2304,18 +2304,17 @@ } void SelectionDAGLowering::visitShuffleVector(User &I) { - SDValue Srcs[2]; - Srcs[0] = getValue(I.getOperand(0)); - Srcs[1] = getValue(I.getOperand(1)); + SDValue Src1 = getValue(I.getOperand(0)); + SDValue Src2 = getValue(I.getOperand(1)); SDValue Mask = getValue(I.getOperand(2)); MVT VT = TLI.getValueType(I.getType()); - MVT SrcVT = Srcs[0].getValueType(); + MVT SrcVT = Src1.getValueType(); int MaskNumElts = Mask.getNumOperands(); int SrcNumElts = SrcVT.getVectorNumElements(); if (SrcNumElts == MaskNumElts) { - setValue(&I, DAG.getNode(ISD::VECTOR_SHUFFLE, VT, Srcs[0], Srcs[1], Mask)); + setValue(&I, DAG.getNode(ISD::VECTOR_SHUFFLE, VT, Src1, Src2, Mask)); return; } @@ -2325,10 +2324,10 @@ if (SrcNumElts < MaskNumElts && MaskNumElts % SrcNumElts == 0) { // Mask is longer than the source vectors and is a multiple of the source // vectors. We can use concatenate vector to make the mask and vectors - // length match. + // lengths match. if (SrcNumElts*2 == MaskNumElts && SequentialMask(Mask, 0)) { // The shuffle is concatenating two vectors together. - setValue(&I, DAG.getNode(ISD::CONCAT_VECTORS, VT, Srcs[0], Srcs[1])); + setValue(&I, DAG.getNode(ISD::CONCAT_VECTORS, VT, Src1, Src2)); return; } @@ -2336,16 +2335,20 @@ unsigned NumConcat = MaskNumElts / SrcNumElts; SDValue UndefVal = DAG.getNode(ISD::UNDEF, SrcVT); - SmallVector MOps1, MOps2; - MOps1.push_back(Srcs[0]); - MOps2.push_back(Srcs[1]); + SDValue* MOps1 = new SDValue[NumConcat]; + SDValue* MOps2 = new SDValue[NumConcat]; + MOps1[0] = Src1; + MOps2[0] = Src2; for (unsigned i = 1; i != NumConcat; ++i) { - MOps1.push_back(UndefVal); - MOps2.push_back(UndefVal); + MOps1[i] = UndefVal; + MOps2[i] = UndefVal; } - Srcs[0] = DAG.getNode(ISD::CONCAT_VECTORS, VT, &MOps1[0], MOps1.size()); - Srcs[1] = DAG.getNode(ISD::CONCAT_VECTORS, VT, &MOps2[0], MOps2.size()); - + Src1 = DAG.getNode(ISD::CONCAT_VECTORS, VT, MOps1, NumConcat); + Src2 = DAG.getNode(ISD::CONCAT_VECTORS, VT, MOps2, NumConcat); + + delete [] MOps1; + delete [] MOps2; + // Readjust mask for new input vector length. SmallVector MappedOps; for (int i = 0; i != MaskNumElts; ++i) { @@ -2363,7 +2366,7 @@ Mask = DAG.getNode(ISD::BUILD_VECTOR, Mask.getValueType(), &MappedOps[0], MappedOps.size()); - setValue(&I, DAG.getNode(ISD::VECTOR_SHUFFLE, VT, Srcs[0], Srcs[1], Mask)); + setValue(&I, DAG.getNode(ISD::VECTOR_SHUFFLE, VT, Src1, Src2, Mask)); return; } @@ -2371,13 +2374,13 @@ // Resulting vector is shorter than the incoming vector. if (SrcNumElts == MaskNumElts && SequentialMask(Mask,0)) { // Shuffle extracts 1st vector. - setValue(&I, Srcs[0]); + setValue(&I, Src1); return; } if (SrcNumElts == MaskNumElts && SequentialMask(Mask,MaskNumElts)) { // Shuffle extracts 2nd vector. - setValue(&I, Srcs[1]); + setValue(&I, Src2); return; } @@ -2406,7 +2409,7 @@ // Check if the access is smaller than the vector size and can we find // a reasonable extract index. - int RangeUse[2]; // 0 = Unused, 1 = Extract, 2 = Can not Extract. + int RangeUse[2] = { 2, 2 }; // 0 = Unused, 1 = Extract, 2 = Can not Extract. int StartIdx[2]; // StartIdx to extract from for (int Input=0; Input < 2; ++Input) { if (MinRange[Input] == SrcNumElts+1 && MaxRange[Input] == -1) { @@ -2414,7 +2417,7 @@ StartIdx[Input] = 0; } else if (MaxRange[Input] - MinRange[Input] < MaskNumElts) { // Fits within range but we should see if we can find a good - // start index that a multiple of the mask length. + // start index that is a multiple of the mask length. if (MaxRange[Input] < MaskNumElts) { RangeUse[Input] = 1; // Extract from beginning of the vector StartIdx[Input] = 0; @@ -2422,11 +2425,8 @@ StartIdx[Input] = (MinRange[Input]/MaskNumElts)*MaskNumElts; if (MaxRange[Input] - StartIdx[Input] < MaskNumElts) RangeUse[Input] = 1; // Extract from a multiple of the mask length. - else - RangeUse[Input] = 2; // Can not extract } - } else - RangeUse[Input] = 2; // Access doesn't fit within range + } } if (RangeUse[0] == 0 && RangeUse[0] == 0) { @@ -2436,11 +2436,12 @@ else if (RangeUse[0] < 2 && RangeUse[1] < 2) { // Extract appropriate subvector and generate a vector shuffle for (int Input=0; Input < 2; ++Input) { + SDValue& Src = Input == 0 ? Src1 : Src2; if (RangeUse[Input] == 0) { - Srcs[Input] = DAG.getNode(ISD::UNDEF, VT); + Src = DAG.getNode(ISD::UNDEF, VT); } else { - Srcs[Input] = DAG.getNode(ISD::EXTRACT_SUBVECTOR, VT, Srcs[Input], - DAG.getIntPtrConstant(StartIdx[Input])); + Src = DAG.getNode(ISD::EXTRACT_SUBVECTOR, VT, Src, + DAG.getIntPtrConstant(StartIdx[Input])); } } // Calculate new mask. @@ -2461,7 +2462,7 @@ } Mask = DAG.getNode(ISD::BUILD_VECTOR, Mask.getValueType(), &MappedOps[0], MappedOps.size()); - setValue(&I, DAG.getNode(ISD::VECTOR_SHUFFLE, VT, Srcs[0], Srcs[1], Mask)); + setValue(&I, DAG.getNode(ISD::VECTOR_SHUFFLE, VT, Src1, Src2, Mask)); return; } } @@ -2480,10 +2481,10 @@ assert(isa(Arg) && "Invalid VECTOR_SHUFFLE mask!"); int Idx = cast(Arg)->getZExtValue(); if (Idx < SrcNumElts) - Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EltVT, Srcs[0], + Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EltVT, Src1, DAG.getConstant(Idx, PtrVT))); else - Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EltVT, Srcs[1], + Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EltVT, Src2, DAG.getConstant(Idx - SrcNumElts, PtrVT))); } } From lattner at cs.uiuc.edu Fri Nov 21 00:00:13 2008 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 21 Nov 2008 00:00:13 -0600 Subject: [llvm-commits] CVS: llvm-www/Users.html Message-ID: <200811210600.mAL60Dsl029289@zion.cs.uiuc.edu> Changes in directory llvm-www: Users.html updated: 1.40 -> 1.41 --- Log message: Add Alchemy --- Diffs of the changes: (+9 -1) Users.html | 10 +++++++++- 1 files changed, 9 insertions(+), 1 deletion(-) Index: llvm-www/Users.html diff -u llvm-www/Users.html:1.40 llvm-www/Users.html:1.41 --- llvm-www/Users.html:1.40 Tue Oct 28 16:22:14 2008 +++ llvm-www/Users.html Thu Nov 20 23:58:49 2008 @@ -27,6 +27,14 @@ href="http://llvm.org/ProjectsWithLLVM/#adobe-hydra">Hydra Language. + + + Adobe Systems Incorporated + Alchemy C/C++ Compiler for the ActionScript + Virtual Machine (AVM2). See the FAQ + and Scott Petersen's DevMtg talk for more details. + + Ageia Technologies @@ -391,6 +399,6 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!">
    LLVM Development List
    - Last modified: $Date: 2008/10/28 21:22:14 $ + Last modified: $Date: 2008/11/21 05:58:49 $ From sabre at nondot.org Fri Nov 21 00:00:30 2008 From: sabre at nondot.org (Chris Lattner) Date: Fri, 21 Nov 2008 00:00:30 -0600 Subject: [llvm-commits] CVS: llvm-www/Users.html Message-ID: <200811210600.mAL60UUH029316@zion.cs.uiuc.edu> Changes in directory llvm-www: Users.html updated: 1.41 -> 1.42 --- Log message: update apple entry. --- Diffs of the changes: (+3 -3) Users.html | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) Index: llvm-www/Users.html diff -u llvm-www/Users.html:1.41 llvm-www/Users.html:1.42 --- llvm-www/Users.html:1.41 Thu Nov 20 23:58:49 2008 +++ llvm-www/Users.html Fri Nov 21 00:00:09 2008 @@ -50,8 +50,8 @@ Apple Inc. - llvm-gcc 4.2 compiler in Xcode (PowerPC 32, X86-32, X86-64) with - LTO integration. + llvm-gcc 4.2 compiler in Xcode 3.1 and above. It supports PPC32/X86-32/X86-64 and + includes transparent LTO integration. @@ -399,6 +399,6 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!">
    LLVM Development List
    - Last modified: $Date: 2008/11/21 05:58:49 $ + Last modified: $Date: 2008/11/21 06:00:09 $ From sabre at nondot.org Fri Nov 21 00:10:32 2008 From: sabre at nondot.org (Chris Lattner) Date: Fri, 21 Nov 2008 00:10:32 -0600 Subject: [llvm-commits] CVS: llvm-www/pubs/2008-10-EMSOFT-Volatiles.html 2008-10-EMSOFT-Volatiles.pdf 2008-10-EMSOFT-Volatiles.ppt Message-ID: <200811210610.mAL6AWWG029720@zion.cs.uiuc.edu> Changes in directory llvm-www/pubs: 2008-10-EMSOFT-Volatiles.html added (r1.1) 2008-10-EMSOFT-Volatiles.pdf added (r1.1) 2008-10-EMSOFT-Volatiles.ppt added (r1.1) --- Log message: add volatile paper. --- Diffs of the changes: (+56 -0) 2008-10-EMSOFT-Volatiles.html | 56 ++++++++++++++++++++++++++++++++++++++++++ 2008-10-EMSOFT-Volatiles.pdf | 0 2008-10-EMSOFT-Volatiles.ppt | 0 3 files changed, 56 insertions(+) Index: llvm-www/pubs/2008-10-EMSOFT-Volatiles.html diff -c /dev/null llvm-www/pubs/2008-10-EMSOFT-Volatiles.html:1.1 *** /dev/null Fri Nov 21 00:10:23 2008 --- llvm-www/pubs/2008-10-EMSOFT-Volatiles.html Fri Nov 21 00:10:12 2008 *************** *** 0 **** --- 1,56 ---- + + + + + + Volatiles Are Miscompiled, and What to Do about It + + + +

    + Volatiles Are Miscompiled, and What to Do about It +
    +
    + Eric Eide, John Regehr +
    + +

    Abstract:

    +
    + C's volatile qualifier is intended to provide a reliable link between + operations at the source-code level and operations at the memory-system + level. We tested thirteen production-quality C compilers + and, for each, found situations in which the compiler generated + incorrect code for accessing volatile variables. This result is disturbing + because it implies that embedded software and operating + systems???both typically coded in C, both being bases for many + mission-critical and safety-critical applications, and both relying + on the correct translation of volatiles???may be being miscompiled. + Our contribution is centered on a novel technique for finding + volatile bugs and a novel technique for working around them. First, + we present access summary testing: an efficient, practical, and automatic + way to detect code-generation errors related to the volatile + qualifier. We have found a number of compiler bugs by performing + access summary testing on randomly generated C programs. Some + of these bugs have been confirmed and fixed by compiler developers. + Second, we present and evaluate a workaround for the compiler + defects we discovered. In 96% of the cases in which one of + our randomly generated programs is miscompiled, we can cause the + faulty C compiler to produce correctly behaving code by applying + a straightforward source-level transformation to the test program. +
    + +

    Download:

    + + +

    See also:

    + + + Index: llvm-www/pubs/2008-10-EMSOFT-Volatiles.pdf Index: llvm-www/pubs/2008-10-EMSOFT-Volatiles.ppt From sabre at nondot.org Fri Nov 21 00:13:35 2008 From: sabre at nondot.org (Chris Lattner) Date: Fri, 21 Nov 2008 00:13:35 -0600 Subject: [llvm-commits] CVS: llvm-www/pubs/index.html Message-ID: <200811210613.mAL6DZ8D029833@zion.cs.uiuc.edu> Changes in directory llvm-www/pubs: index.html updated: 1.84 -> 1.85 --- Log message: add emsoft paper --- Diffs of the changes: (+12 -5) index.html | 17 ++++++++++++----- 1 files changed, 12 insertions(+), 5 deletions(-) Index: llvm-www/pubs/index.html diff -u llvm-www/pubs/index.html:1.84 llvm-www/pubs/index.html:1.85 --- llvm-www/pubs/index.html:1.84 Tue Nov 4 04:25:34 2008 +++ llvm-www/pubs/index.html Fri Nov 21 00:13:13 2008 @@ -3,17 +3,24 @@
      -
    1. "Introduction to the LLVM Compiler System"
      - Chris Lattner
      - Plenary Talk, ACAT 2008: Advanced Computing and Analysis Techniques in Physics Research, Erice, Sicily, Italy, November 2008.
    2. - -
    3. "KLEE: Unassisted and Automatic Generation of High-Coverage Tests for Complex Systems Programs"
      Cristian Cadar, Daniel Dunbar, Dawson Engler
      Proc. 8th USENIX Symposium on Operating Systems Design and Implementation (OSDI 2008), December 2008
    4. +
    5. "Introduction to the LLVM Compiler System"
      + Chris Lattner
      + Plenary Talk, ACAT 2008: Advanced Computing and Analysis Techniques in Physics Research, Erice, Sicily, Italy, November 2008
    6. + + +
    7. "Volatiles Are Miscompiled, +and What to Do about It"
      +Eric Eide, John Regehr
      +Proc. EMSOFT International Conference on Embedded Software (EMSOFT 2008), October 2008
    8. + + +
    9. "A Lazy Developer Approach: Building a JVM with Third Party Software"
      Nicolas Geoffray, Gael Thomas, Charles Clement and Bertil Folliot
      From duraid at octopus.com.au Fri Nov 21 00:17:33 2008 From: duraid at octopus.com.au (Duraid Madina) Date: Fri, 21 Nov 2008 06:17:33 -0000 Subject: [llvm-commits] [test-suite] r59793 - in /test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia: ./ AMGmk/ IRSmk/ sphot/ Message-ID: <200811210617.mAL6HatX030020@zion.cs.uiuc.edu> Author: duraid Date: Fri Nov 21 00:17:30 2008 New Revision: 59793 URL: http://llvm.org/viewvc/llvm-project?rev=59793&view=rev Log: add some ASC Sequoia benchmarks Added: test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/ test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/ test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/COPYRIGHT_and_DISCLAIMER test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/Makefile test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/csr_matrix.c test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/csr_matrix.h test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/csr_matvec.c test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/headers.h test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/hypre_error.c test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/hypre_memory.c test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/laplace.c test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/main.c test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/relax.c test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/seq_mv.h test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/utilities.h test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/vector.c test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/IRSmk/ test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/IRSmk/COPYRIGHT_and_DISCLAIMER test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/IRSmk/Makefile test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/IRSmk/irsmk.h test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/IRSmk/irsmk_input test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/IRSmk/main.c test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/IRSmk/reference_output test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/IRSmk/rmatmult3.c test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/IRSmk/utility.c test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/Makefile test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/ test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/LICENSE test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/Makefile test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/allocdyn.f test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/copyglob.f test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/copypriv.f test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/copyseed.f test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/correct_answer test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/execute.f test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/genmesh.f test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/genxsec.f test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/geomz.inc test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/globals.inc test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/input.dat test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/interp.f test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/iranfeven.f test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/iranfodd.f test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/mpi_stubs.f test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/mpi_stubs_f77.h test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/mpif.h test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/opac.txt test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/params.inc test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/plnkut.f test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/pranf.f test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/pranf.inc test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/randseed.inc test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/ranf.f test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/ranfatok.f test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/ranfk.f test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/ranfkbinary.f test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/ranfmodmult.f test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/rans.f test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/rdinput.f test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/rdopac.f test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/second.f test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/seedranf.f test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/shared.inc test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/sphot.f test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/sphot_read_v0.9.1.txt test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/sphot_v0.9.1.txt test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/thom.f test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/times.inc test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/writeout.f test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/wroutput.f test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/zonevols.f Added: test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/COPYRIGHT_and_DISCLAIMER URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/COPYRIGHT_and_DISCLAIMER?rev=59793&view=auto ============================================================================== --- test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/COPYRIGHT_and_DISCLAIMER (added) +++ test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/COPYRIGHT_and_DISCLAIMER Fri Nov 21 00:17:30 2008 @@ -0,0 +1,33 @@ +This work was produced at the University of California, Lawrence Livermore +National Laboratory (UC LLNL) under contract no. W-7405-ENG-48 (Contract 48) +between the U.S. Department of Energy (DOE) and The Regents of the University +of California (University) for the operation of UC LLNL. The rights of the +Federal Government are reserved under Contract 48 subject to the restrictions +agreed upon by the DOE and University as allowed under DOE Acquisition Letter +97-1. + + + DISCLAIMER + + +This work was prepared as an account of work sponsored by an agency of +the United States Government. Neither the United States Government nor the +University of California nor any of their employees, makes any warranty, +express or implied, or assumes any liability or responsibility for the +accuracy, completeness, or usefulness of any information, apparatus, product, +or process disclosed, or represents that its use would not infringe +privately-owned rights. Reference herein to any specific commercial +products, process, or service by trade name, trademark, manufacturer or +otherwise does not necessarily constitute or imply its endorsement, +recommendation, or favoring by the United States Government or the University +of California. The views and opinions of authors expressed herein do not +necessarily state or reflect those of the United States Government or the +University of California, and shall not be used for advertising or product +endorsement purposes. + + + NOTIFICATION OF COMMERCIAL USE + + +Commercialization of this product is prohibited without notifying the +Department of Energy (DOE) or Lawrence Livermore National Laboratory (LLNL). Added: test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/Makefile URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/Makefile?rev=59793&view=auto ============================================================================== --- test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/Makefile (added) +++ test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/Makefile Fri Nov 21 00:17:30 2008 @@ -0,0 +1,8 @@ +LEVEL = ../../../.. + +PROG = AMGmk + +LIBS += -lm +LDFLAGS += -lm + +include ../../../Makefile.multisrc Added: test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/csr_matrix.c URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/csr_matrix.c?rev=59793&view=auto ============================================================================== --- test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/csr_matrix.c (added) +++ test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/csr_matrix.c Fri Nov 21 00:17:30 2008 @@ -0,0 +1,551 @@ +/*BHEADER********************************************************************** + * Copyright (c) 2006 The Regents of the University of California. + * Produced at the Lawrence Livermore National Laboratory. + * Written by the HYPRE team. UCRL-CODE-222953. + * All rights reserved. + * + * This file is part of HYPRE (see http://www.llnl.gov/CASC/hypre/). + * Please see the COPYRIGHT_and_LICENSE file for the copyright notice, + * disclaimer, contact information and the GNU Lesser General Public License. + * + * HYPRE 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) version 2.1 dated February 1999. + * + * HYPRE 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 terms and conditions of the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU Lesser 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 + * + * $Revision: 2.12 $ + ***********************************************************************EHEADER*/ + + + +/****************************************************************************** + * + * Member functions for hypre_CSRMatrix class. + * + *****************************************************************************/ + +#include "headers.h" + +/*-------------------------------------------------------------------------- + * hypre_CSRMatrixCreate + *--------------------------------------------------------------------------*/ + +hypre_CSRMatrix * +hypre_CSRMatrixCreate( int num_rows, + int num_cols, + int num_nonzeros ) +{ + hypre_CSRMatrix *matrix; + + matrix = hypre_CTAlloc(hypre_CSRMatrix, 1); + + hypre_CSRMatrixData(matrix) = NULL; + hypre_CSRMatrixI(matrix) = NULL; + hypre_CSRMatrixJ(matrix) = NULL; + hypre_CSRMatrixRownnz(matrix) = NULL; + hypre_CSRMatrixNumRows(matrix) = num_rows; + hypre_CSRMatrixNumCols(matrix) = num_cols; + hypre_CSRMatrixNumNonzeros(matrix) = num_nonzeros; + + /* set defaults */ + hypre_CSRMatrixOwnsData(matrix) = 1; + hypre_CSRMatrixNumRownnz(matrix) = num_rows; + + + return matrix; +} +/*-------------------------------------------------------------------------- + * hypre_CSRMatrixDestroy + *--------------------------------------------------------------------------*/ + +int +hypre_CSRMatrixDestroy( hypre_CSRMatrix *matrix ) +{ + int ierr=0; + + if (matrix) + { + hypre_TFree(hypre_CSRMatrixI(matrix)); + if (hypre_CSRMatrixRownnz(matrix)) + hypre_TFree(hypre_CSRMatrixRownnz(matrix)); + if ( hypre_CSRMatrixOwnsData(matrix) ) + { + hypre_TFree(hypre_CSRMatrixData(matrix)); + hypre_TFree(hypre_CSRMatrixJ(matrix)); + } + hypre_TFree(matrix); + } + + return ierr; +} + +/*-------------------------------------------------------------------------- + * hypre_CSRMatrixInitialize + *--------------------------------------------------------------------------*/ + +int +hypre_CSRMatrixInitialize( hypre_CSRMatrix *matrix ) +{ + int num_rows = hypre_CSRMatrixNumRows(matrix); + int num_nonzeros = hypre_CSRMatrixNumNonzeros(matrix); +/* int num_rownnz = hypre_CSRMatrixNumRownnz(matrix); */ + + int ierr=0; + + if ( ! hypre_CSRMatrixData(matrix) && num_nonzeros ) + hypre_CSRMatrixData(matrix) = hypre_CTAlloc(double, num_nonzeros); + if ( ! hypre_CSRMatrixI(matrix) ) + hypre_CSRMatrixI(matrix) = hypre_CTAlloc(int, num_rows + 1); +/* if ( ! hypre_CSRMatrixRownnz(matrix) ) + hypre_CSRMatrixRownnz(matrix) = hypre_CTAlloc(int, num_rownnz);*/ + if ( ! hypre_CSRMatrixJ(matrix) && num_nonzeros ) + hypre_CSRMatrixJ(matrix) = hypre_CTAlloc(int, num_nonzeros); + + return ierr; +} + +/*-------------------------------------------------------------------------- + * hypre_CSRMatrixSetDataOwner + *--------------------------------------------------------------------------*/ + +int +hypre_CSRMatrixSetDataOwner( hypre_CSRMatrix *matrix, + int owns_data ) +{ + int ierr=0; + + hypre_CSRMatrixOwnsData(matrix) = owns_data; + + return ierr; +} + +/*-------------------------------------------------------------------------- + * hypre_CSRMatrixSetRownnz + * + * function to set the substructure rownnz and num_rowsnnz inside the CSRMatrix + * it needs the A_i substructure of CSRMatrix to find the nonzero rows. + * It runs after the create CSR and when A_i is known..It does not check for + * the existence of A_i or of the CSR matrix. + *--------------------------------------------------------------------------*/ + +int +hypre_CSRMatrixSetRownnz( hypre_CSRMatrix *matrix ) +{ + int ierr=0; + int num_rows = hypre_CSRMatrixNumRows(matrix); + int *A_i = hypre_CSRMatrixI(matrix); + int *Arownnz; + + int i, adiag; + int irownnz=0; + + for (i=0; i < num_rows; i++) + { + adiag = (A_i[i+1] - A_i[i]); + if(adiag > 0) irownnz++; + } + + hypre_CSRMatrixNumRownnz(matrix) = irownnz; + + if ((irownnz == 0) || (irownnz == num_rows)) + { + hypre_CSRMatrixRownnz(matrix) = NULL; + } + else + { + Arownnz = hypre_CTAlloc(int, irownnz); + irownnz = 0; + for (i=0; i < num_rows; i++) + { + adiag = A_i[i+1]-A_i[i]; + if(adiag > 0) Arownnz[irownnz++] = i; + } + hypre_CSRMatrixRownnz(matrix) = Arownnz; + } + return ierr; +} + +/*-------------------------------------------------------------------------- + * hypre_CSRMatrixRead + *--------------------------------------------------------------------------*/ + +hypre_CSRMatrix * +hypre_CSRMatrixRead( char *file_name ) +{ + hypre_CSRMatrix *matrix; + + FILE *fp; + + double *matrix_data; + int *matrix_i; + int *matrix_j; + int num_rows; + int num_nonzeros; + int max_col = 0; + + int file_base = 1; + + int j; + + /*---------------------------------------------------------- + * Read in the data + *----------------------------------------------------------*/ + + fp = fopen(file_name, "r"); + + fscanf(fp, "%d", &num_rows); + + matrix_i = hypre_CTAlloc(int, num_rows + 1); + for (j = 0; j < num_rows+1; j++) + { + fscanf(fp, "%d", &matrix_i[j]); + matrix_i[j] -= file_base; + } + + num_nonzeros = matrix_i[num_rows]; + + matrix = hypre_CSRMatrixCreate(num_rows, num_rows, matrix_i[num_rows]); + hypre_CSRMatrixI(matrix) = matrix_i; + hypre_CSRMatrixInitialize(matrix); + + matrix_j = hypre_CSRMatrixJ(matrix); + for (j = 0; j < num_nonzeros; j++) + { + fscanf(fp, "%d", &matrix_j[j]); + matrix_j[j] -= file_base; + + if (matrix_j[j] > max_col) + { + max_col = matrix_j[j]; + } + } + + matrix_data = hypre_CSRMatrixData(matrix); + for (j = 0; j < matrix_i[num_rows]; j++) + { + fscanf(fp, "%le", &matrix_data[j]); + } + + fclose(fp); + + hypre_CSRMatrixNumNonzeros(matrix) = num_nonzeros; + hypre_CSRMatrixNumCols(matrix) = ++max_col; + + return matrix; +} + +/*-------------------------------------------------------------------------- + * hypre_CSRMatrixPrint + *--------------------------------------------------------------------------*/ + +int +hypre_CSRMatrixPrint( hypre_CSRMatrix *matrix, + char *file_name ) +{ + FILE *fp; + + double *matrix_data; + int *matrix_i; + int *matrix_j; + int num_rows; + + int file_base = 1; + + int j; + + int ierr = 0; + + /*---------------------------------------------------------- + * Print the matrix data + *----------------------------------------------------------*/ + + matrix_data = hypre_CSRMatrixData(matrix); + matrix_i = hypre_CSRMatrixI(matrix); + matrix_j = hypre_CSRMatrixJ(matrix); + num_rows = hypre_CSRMatrixNumRows(matrix); + + fp = fopen(file_name, "w"); + + fprintf(fp, "%d\n", num_rows); + + for (j = 0; j <= num_rows; j++) + { + fprintf(fp, "%d\n", matrix_i[j] + file_base); + } + + for (j = 0; j < matrix_i[num_rows]; j++) + { + fprintf(fp, "%d\n", matrix_j[j] + file_base); + } + + if (matrix_data) + { + for (j = 0; j < matrix_i[num_rows]; j++) + { + fprintf(fp, "%.14e\n", matrix_data[j]); + } + } + else + { + fprintf(fp, "Warning: No matrix data!\n"); + } + + fclose(fp); + + return ierr; +} + +/*-------------------------------------------------------------------------- + * hypre_CSRMatrixCopy: + * copys A to B, + * if copy_data = 0 only the structure of A is copied to B. + * the routine does not check if the dimensions of A and B match !!! + *--------------------------------------------------------------------------*/ + +int +hypre_CSRMatrixCopy( hypre_CSRMatrix *A, hypre_CSRMatrix *B, int copy_data ) +{ + int ierr=0; + int num_rows = hypre_CSRMatrixNumRows(A); + int *A_i = hypre_CSRMatrixI(A); + int *A_j = hypre_CSRMatrixJ(A); + double *A_data; + int *B_i = hypre_CSRMatrixI(B); + int *B_j = hypre_CSRMatrixJ(B); + double *B_data; + + int i, j; + + for (i=0; i < num_rows; i++) + { + B_i[i] = A_i[i]; + for (j=A_i[i]; j < A_i[i+1]; j++) + { + B_j[j] = A_j[j]; + } + } + B_i[num_rows] = A_i[num_rows]; + if (copy_data) + { + A_data = hypre_CSRMatrixData(A); + B_data = hypre_CSRMatrixData(B); + for (i=0; i < num_rows; i++) + { + for (j=A_i[i]; j < A_i[i+1]; j++) + { + B_data[j] = A_data[j]; + } + } + } + return ierr; +} + +/*-------------------------------------------------------------------------- + * hypre_CSRMatrixClone + * Creates and returns a new copy of the argument, A. + * Data is not copied, only structural information is reproduced. + * Copying is a deep copy in that no pointers are copied; new arrays are + * created where necessary. + *--------------------------------------------------------------------------*/ + +hypre_CSRMatrix * hypre_CSRMatrixClone( hypre_CSRMatrix * A ) +{ + int num_rows = hypre_CSRMatrixNumRows( A ); + int num_cols = hypre_CSRMatrixNumCols( A ); + int num_nonzeros = hypre_CSRMatrixNumNonzeros( A ); + hypre_CSRMatrix * B = hypre_CSRMatrixCreate( num_rows, num_cols, num_nonzeros ); + int * A_i; + int * A_j; + int * B_i; + int * B_j; + int i, j; + + hypre_CSRMatrixInitialize( B ); + + A_i = hypre_CSRMatrixI(A); + A_j = hypre_CSRMatrixJ(A); + B_i = hypre_CSRMatrixI(B); + B_j = hypre_CSRMatrixJ(B); + + for ( i=0; i data) +#define hypre_CSRMatrixI(matrix) ((matrix) -> i) +#define hypre_CSRMatrixJ(matrix) ((matrix) -> j) +#define hypre_CSRMatrixNumRows(matrix) ((matrix) -> num_rows) +#define hypre_CSRMatrixNumCols(matrix) ((matrix) -> num_cols) +#define hypre_CSRMatrixNumNonzeros(matrix) ((matrix) -> num_nonzeros) +#define hypre_CSRMatrixRownnz(matrix) ((matrix) -> rownnz) +#define hypre_CSRMatrixNumRownnz(matrix) ((matrix) -> num_rownnz) +#define hypre_CSRMatrixOwnsData(matrix) ((matrix) -> owns_data) + + + +/*-------------------------------------------------------------------------- + * CSR Boolean Matrix + *--------------------------------------------------------------------------*/ + +typedef struct +{ + int *i; + int *j; + int num_rows; + int num_cols; + int num_nonzeros; + int owns_data; + +} hypre_CSRBooleanMatrix; + +/*-------------------------------------------------------------------------- + * Accessor functions for the CSR Boolean Matrix structure + *--------------------------------------------------------------------------*/ + +#define hypre_CSRBooleanMatrix_Get_I(matrix) ((matrix)->i) +#define hypre_CSRBooleanMatrix_Get_J(matrix) ((matrix)->j) +#define hypre_CSRBooleanMatrix_Get_NRows(matrix) ((matrix)->num_rows) +#define hypre_CSRBooleanMatrix_Get_NCols(matrix) ((matrix)->num_cols) +#define hypre_CSRBooleanMatrix_Get_NNZ(matrix) ((matrix)->num_nonzeros) +#define hypre_CSRBooleanMatrix_Get_OwnsData(matrix) ((matrix)->owns_data) + +#endif + Added: test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/csr_matvec.c URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/csr_matvec.c?rev=59793&view=auto ============================================================================== --- test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/csr_matvec.c (added) +++ test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/csr_matvec.c Fri Nov 21 00:17:30 2008 @@ -0,0 +1,513 @@ +/*BHEADER********************************************************************** + * Copyright (c) 2006 The Regents of the University of California. + * Produced at the Lawrence Livermore National Laboratory. + * Written by the HYPRE team. UCRL-CODE-222953. + * All rights reserved. + * + * This file is part of HYPRE (see http://www.llnl.gov/CASC/hypre/). + * Please see the COPYRIGHT_and_LICENSE file for the copyright notice, + * disclaimer, contact information and the GNU Lesser General Public License. + * + * HYPRE 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) version 2.1 dated February 1999. + * + * HYPRE 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 terms and conditions of the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU Lesser 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 + * + * $Revision: 2.10 $ + ***********************************************************************EHEADER*/ + + + +/****************************************************************************** + * + * Matvec functions for hypre_CSRMatrix class. + * + *****************************************************************************/ + +#include "headers.h" +#include +#include "omp.h" + +/*-------------------------------------------------------------------------- + * hypre_CSRMatrixMatvec + *--------------------------------------------------------------------------*/ + +int +hypre_CSRMatrixMatvec( double alpha, + hypre_CSRMatrix *A, + hypre_Vector *x, + double beta, + hypre_Vector *y ) +{ + double *A_data = hypre_CSRMatrixData(A); + int *A_i = hypre_CSRMatrixI(A); + int *A_j = hypre_CSRMatrixJ(A); + int num_rows = hypre_CSRMatrixNumRows(A); + int num_cols = hypre_CSRMatrixNumCols(A); + + int *A_rownnz = hypre_CSRMatrixRownnz(A); + int num_rownnz = hypre_CSRMatrixNumRownnz(A); + + double *x_data = hypre_VectorData(x); + double *y_data = hypre_VectorData(y); + int x_size = hypre_VectorSize(x); + int y_size = hypre_VectorSize(y); + int num_vectors = hypre_VectorNumVectors(x); + int idxstride_y = hypre_VectorIndexStride(y); + int vecstride_y = hypre_VectorVectorStride(y); + int idxstride_x = hypre_VectorIndexStride(x); + int vecstride_x = hypre_VectorVectorStride(x); + + double temp, tempx; + + int i, j, jj; + + int m; + + double xpar=0.7; + + int ierr = 0; + + + /*--------------------------------------------------------------------- + * Check for size compatibility. Matvec returns ierr = 1 if + * length of X doesn't equal the number of columns of A, + * ierr = 2 if the length of Y doesn't equal the number of rows + * of A, and ierr = 3 if both are true. + * + * Because temporary vectors are often used in Matvec, none of + * these conditions terminates processing, and the ierr flag + * is informational only. + *--------------------------------------------------------------------*/ + + hypre_assert( num_vectors == hypre_VectorNumVectors(y) ); + + if (num_cols != x_size) + ierr = 1; + + if (num_rows != y_size) + ierr = 2; + + if (num_cols != x_size && num_rows != y_size) + ierr = 3; + + /*----------------------------------------------------------------------- + * Do (alpha == 0.0) computation - RDF: USE MACHINE EPS + *-----------------------------------------------------------------------*/ + + if (alpha == 0.0) + { + for (i = 0; i < num_rows*num_vectors; i++) + y_data[i] *= beta; + + return ierr; + } + + /*----------------------------------------------------------------------- + * y = (beta/alpha)*y + *-----------------------------------------------------------------------*/ + + temp = beta / alpha; + + if (temp != 1.0) + { + if (temp == 0.0) + { + for (i = 0; i < num_rows*num_vectors; i++) + y_data[i] = 0.0; + } + else + { + for (i = 0; i < num_rows*num_vectors; i++) + y_data[i] *= temp; + } + } + + /*----------------------------------------------------------------- + * y += A*x + *-----------------------------------------------------------------*/ + +/* use rownnz pointer to do the A*x multiplication when num_rownnz is smaller than num_rows */ + + if (num_rownnz < xpar*(num_rows)) + { + for (i = 0; i < num_rownnz; i++) + { + m = A_rownnz[i]; + + /* + * for (jj = A_i[m]; jj < A_i[m+1]; jj++) + * { + * j = A_j[jj]; + * y_data[m] += A_data[jj] * x_data[j]; + * } */ + if ( num_vectors==1 ) + { + tempx = y_data[m]; + for (jj = A_i[m]; jj < A_i[m+1]; jj++) + tempx += A_data[jj] * x_data[A_j[jj]]; + y_data[m] = tempx; + } + else + for ( j=0; j 1) + { + + + for (i1 = 0; i1 < num_threads; i1++) + { + size = num_cols/num_threads; + rest = num_cols - size*num_threads; + if (i1 < rest) + { + ns = i1*size+i1-1; + ne = (i1+1)*size+i1+1; + } + else + { + ns = i1*size+rest-1; + ne = (i1+1)*size+rest; + } + if ( num_vectors==1 ) + { + for (i = 0; i < num_rows; i++) + { + for (jj = A_i[i]; jj < A_i[i+1]; jj++) + { + j = A_j[jj]; + if (j > ns && j < ne) + y_data[j] += A_data[jj] * x_data[i]; + } + } + } + else + { + for (i = 0; i < num_rows; i++) + { + for ( jv=0; jv ns && j < ne) + y_data[ j*idxstride_y + jv*vecstride_y ] += + A_data[jj] * x_data[ i*idxstride_x + jv*vecstride_x]; + } + } + } + } + + } + } + else + { + for (i = 0; i < num_rows; i++) + { + if ( num_vectors==1 ) + { + for (jj = A_i[i]; jj < A_i[i+1]; jj++) + { + j = A_j[jj]; + y_data[j] += A_data[jj] * x_data[i]; + } + } + else + { + for ( jv=0; jv +#include +#include + +#include "utilities.h" +#include "seq_mv.h" + + Added: test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/hypre_error.c URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/hypre_error.c?rev=59793&view=auto ============================================================================== --- test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/hypre_error.c (added) +++ test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/hypre_error.c Fri Nov 21 00:17:30 2008 @@ -0,0 +1,76 @@ +/*BHEADER********************************************************************** + * Copyright (c) 2006 The Regents of the University of California. + * Produced at the Lawrence Livermore National Laboratory. + * Written by the HYPRE team, UCRL-CODE-222953. + * All rights reserved. + * + * This file is part of HYPRE (see http://www.llnl.gov/CASC/hypre/). + * Please see the COPYRIGHT_and_LICENSE file for the copyright notice, + * disclaimer and the GNU Lesser General Public License. + * + * 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) version 2.1 dated February 1999. + * + * 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 terms and conditions of the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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 + * + * $Revision: 2.5 $ + ***********************************************************************EHEADER*/ + +#include +#include "utilities.h" + +int hypre__global_error = 0; + +/* Process the error with code ierr raised in the given line of the + given source file. */ +void hypre_error_handler(char *filename, int line, int ierr) +{ + hypre_error_flag |= ierr; + +#ifdef HYPRE_PRINT_ERRORS + fprintf(stderr, + "hypre error in file \"%s\", line %d, error code = %d ", + filename, line, ierr); +#endif +} + +int HYPRE_GetError() +{ + return hypre_error_flag; +} + +int HYPRE_CheckError(int ierr, int hypre_error_code) +{ + return ierr & hypre_error_code; +} + +void HYPRE_DescribeError(int ierr, char *msg) +{ + if (ierr == 0) + sprintf(msg,"[No error] "); + + if (ierr & HYPRE_ERROR_GENERIC) + sprintf(msg,"[Generic error] "); + + if (ierr & HYPRE_ERROR_MEMORY) + sprintf(msg,"[Memory error] "); + + if (ierr & HYPRE_ERROR_ARG) + sprintf(msg,"[Error in argument %d] ", HYPRE_GetErrorArg()); + + if (ierr & HYPRE_ERROR_CONV) + sprintf(msg,"[Method did not converge] "); +} + +int HYPRE_GetErrorArg() +{ + return (hypre_error_flag>>3 & 31); +} Added: test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/hypre_memory.c URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/hypre_memory.c?rev=59793&view=auto ============================================================================== --- test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/hypre_memory.c (added) +++ test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/hypre_memory.c Fri Nov 21 00:17:30 2008 @@ -0,0 +1,338 @@ +/*BHEADER********************************************************************** + * Copyright (c) 2006 The Regents of the University of California. + * Produced at the Lawrence Livermore National Laboratory. + * Written by the HYPRE team, UCRL-CODE-222953. + * All rights reserved. + * + * This file is part of HYPRE (see http://www.llnl.gov/CASC/hypre/). + * Please see the COPYRIGHT_and_LICENSE file for the copyright notice, + * disclaimer and the GNU Lesser General Public License. + * + * 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) version 2.1 dated February 1999. + * + * 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 terms and conditions of the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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 + * + * $Revision: 2.4 $ + ***********************************************************************EHEADER*/ + + +/****************************************************************************** + * + * Memory management utilities + * + *****************************************************************************/ +#include +#include +#include "utilities.h" + +#ifdef HYPRE_USE_PTHREADS +#include "threading.h" + +#ifdef HYPRE_USE_UMALLOC +#include "umalloc_local.h" + +#define _umalloc_(size) (threadid == hypre_NumThreads) ? \ + (char *) malloc(size) : \ + (char *) _umalloc(_uparam[threadid].myheap, size) +#define _ucalloc_(count, size) (threadid == hypre_NumThreads) ? \ + (char *) calloc(count, size) : \ + (char *) _ucalloc(_uparam[threadid].myheap,\ + count, size) +#define _urealloc_(ptr, size) (threadid == hypre_NumThreads) ? \ + (char *) realloc(ptr, size) : \ + (char *) _urealloc(ptr, size) +#define _ufree_(ptr) (threadid == hypre_NumThreads) ? \ + free(ptr) : _ufree(ptr) +#endif +#else +#ifdef HYPRE_USE_UMALLOC +#undef HYPRE_USE_UMALLOC +#endif +#endif + +/****************************************************************************** + * + * Standard routines + * + *****************************************************************************/ + +/*-------------------------------------------------------------------------- + * hypre_OutOfMemory + *--------------------------------------------------------------------------*/ + +int +hypre_OutOfMemory( int size ) +{ + printf("Out of memory trying to allocate %d bytes\n", size); + fflush(stdout); + + hypre_error(HYPRE_ERROR_MEMORY); + + return 0; +} + +/*-------------------------------------------------------------------------- + * hypre_MAlloc + *--------------------------------------------------------------------------*/ + +char * +hypre_MAlloc( int size ) +{ + char *ptr; + + if (size > 0) + { +#ifdef HYPRE_USE_UMALLOC + int threadid = hypre_GetThreadID(); + + ptr = _umalloc_(size); +#else + ptr = malloc(size); +#endif + +#if 1 + if (ptr == NULL) + { + hypre_OutOfMemory(size); + } +#endif + } + else + { + ptr = NULL; + } + + return ptr; +} + +/*-------------------------------------------------------------------------- + * hypre_CAlloc + *--------------------------------------------------------------------------*/ + +char * +hypre_CAlloc( int count, + int elt_size ) +{ + char *ptr; + int size = count*elt_size; + + if (size > 0) + { +#ifdef HYPRE_USE_UMALLOC + int threadid = hypre_GetThreadID(); + + ptr = _ucalloc_(count, elt_size); +#else + ptr = calloc(count, elt_size); +#endif + +#if 1 + if (ptr == NULL) + { + hypre_OutOfMemory(size); + } +#endif + } + else + { + ptr = NULL; + } + + return ptr; +} + +/*-------------------------------------------------------------------------- + * hypre_ReAlloc + *--------------------------------------------------------------------------*/ + +char * +hypre_ReAlloc( char *ptr, + int size ) +{ +#ifdef HYPRE_USE_UMALLOC + if (ptr == NULL) + { + ptr = hypre_MAlloc(size); + } + else if (size == 0) + { + hypre_Free(ptr); + } + else + { + int threadid = hypre_GetThreadID(); + ptr = _urealloc_(ptr, size); + } +#else + if (ptr == NULL) + { + ptr = malloc(size); + } + else + { + ptr = realloc(ptr, size); + } +#endif + +#if 1 + if ((ptr == NULL) && (size > 0)) + { + hypre_OutOfMemory(size); + } +#endif + + return ptr; +} + +/*-------------------------------------------------------------------------- + * hypre_Free + *--------------------------------------------------------------------------*/ + +void +hypre_Free( char *ptr ) +{ + if (ptr) + { +#ifdef HYPRE_USE_UMALLOC + int threadid = hypre_GetThreadID(); + + _ufree_(ptr); +#else + free(ptr); +#endif + } +} + + +/*-------------------------------------------------------------------------- + * These Shared routines are for one thread to allocate memory for data + * will be visible to all threads. The file-scope pointer + * global_alloc_ptr is used in these routines. + *--------------------------------------------------------------------------*/ + +#ifdef HYPRE_USE_PTHREADS + +char *global_alloc_ptr; +double *global_data_ptr; + +/*-------------------------------------------------------------------------- + * hypre_SharedMAlloc + *--------------------------------------------------------------------------*/ + +char * +hypre_SharedMAlloc( int size ) +{ + char *ptr; + int unthreaded = pthread_equal(initial_thread, pthread_self()); + int I_call_malloc = unthreaded || + pthread_equal(hypre_thread[0],pthread_self()); + + if (I_call_malloc) { + global_alloc_ptr = hypre_MAlloc( size ); + } + + hypre_barrier(&talloc_mtx, unthreaded); + ptr = global_alloc_ptr; + hypre_barrier(&talloc_mtx, unthreaded); + + return ptr; +} + +/*-------------------------------------------------------------------------- + * hypre_SharedCAlloc + *--------------------------------------------------------------------------*/ + +char * +hypre_SharedCAlloc( int count, + int elt_size ) +{ + char *ptr; + int unthreaded = pthread_equal(initial_thread, pthread_self()); + int I_call_calloc = unthreaded || + pthread_equal(hypre_thread[0],pthread_self()); + + if (I_call_calloc) { + global_alloc_ptr = hypre_CAlloc( count, elt_size ); + } + + hypre_barrier(&talloc_mtx, unthreaded); + ptr = global_alloc_ptr; + hypre_barrier(&talloc_mtx, unthreaded); + + return ptr; +} + +/*-------------------------------------------------------------------------- + * hypre_SharedReAlloc + *--------------------------------------------------------------------------*/ + +char * +hypre_SharedReAlloc( char *ptr, + int size ) +{ + int unthreaded = pthread_equal(initial_thread, pthread_self()); + int I_call_realloc = unthreaded || + pthread_equal(hypre_thread[0],pthread_self()); + + if (I_call_realloc) { + global_alloc_ptr = hypre_ReAlloc( ptr, size ); + } + + hypre_barrier(&talloc_mtx, unthreaded); + ptr = global_alloc_ptr; + hypre_barrier(&talloc_mtx, unthreaded); + + return ptr; +} + +/*-------------------------------------------------------------------------- + * hypre_SharedFree + *--------------------------------------------------------------------------*/ + +void +hypre_SharedFree( char *ptr ) +{ + int unthreaded = pthread_equal(initial_thread, pthread_self()); + int I_call_free = unthreaded || + pthread_equal(hypre_thread[0],pthread_self()); + + hypre_barrier(&talloc_mtx, unthreaded); + if (I_call_free) { + hypre_Free(ptr); + } + hypre_barrier(&talloc_mtx, unthreaded); +} + +/*-------------------------------------------------------------------------- + * hypre_IncrementSharedDataPtr + *--------------------------------------------------------------------------*/ + +double * +hypre_IncrementSharedDataPtr( double *ptr, int size ) +{ + int unthreaded = pthread_equal(initial_thread, pthread_self()); + int I_increment = unthreaded || + pthread_equal(hypre_thread[0],pthread_self()); + + if (I_increment) { + global_data_ptr = ptr + size; + } + + hypre_barrier(&talloc_mtx, unthreaded); + ptr = global_data_ptr; + hypre_barrier(&talloc_mtx, unthreaded); + + return ptr; +} + +#endif + Added: test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/laplace.c URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/laplace.c?rev=59793&view=auto ============================================================================== --- test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/laplace.c (added) +++ test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/laplace.c Fri Nov 21 00:17:30 2008 @@ -0,0 +1,181 @@ +/*BHEADER********************************************************************** + * Copyright (c) 2006 The Regents of the University of California. + * Produced at the Lawrence Livermore National Laboratory. + * Written by the HYPRE team. UCRL-CODE-222953. + * All rights reserved. + * + * This file is part of HYPRE (see http://www.llnl.gov/CASC/hypre/). + * Please see the COPYRIGHT_and_LICENSE file for the copyright notice, + * disclaimer, contact information and the GNU Lesser General Public License. + * + * HYPRE 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) version 2.1 dated February 1999. + * + * HYPRE 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 terms and conditions of the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU Lesser 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 + * + * $Revision: 2.10 $ + ***********************************************************************EHEADER*/ + + + + +#include "headers.h" + +/*-------------------------------------------------------------------------- + * hypre_GenerateLaplacian + *--------------------------------------------------------------------------*/ + +hypre_CSRMatrix * +GenerateSeqLaplacian( int nx, + + int ny, + int nz, + double *value, + hypre_Vector **rhs_ptr, + hypre_Vector **x_ptr, + hypre_Vector **sol_ptr) +{ + hypre_CSRMatrix *A; + hypre_Vector *rhs; + hypre_Vector *x; + hypre_Vector *sol; + double *rhs_data; + double *x_data; + double *sol_data; + + int *A_i; + int *A_j; + double *A_data; + + int ix, iy, iz; + int cnt; + int row_index; + int i, j; + + int grid_size; + + + grid_size = nx*ny*nz; + + A_i = hypre_CTAlloc(int, grid_size+1); + rhs_data = hypre_CTAlloc(double, grid_size); + x_data = hypre_CTAlloc(double, grid_size); + sol_data = hypre_CTAlloc(double, grid_size); + + for (i=0; i < grid_size; i++) + { + x_data[i] = 0.0; + sol_data[i] = 0.0; + rhs_data[i] = 1.0; + } + + cnt = 1; + A_i[0] = 0; + for (iz = 0; iz < nz; iz++) + { + for (iy = 0; iy < ny; iy++) + { + for (ix = 0; ix < nx; ix++) + { + A_i[cnt] = A_i[cnt-1]; + A_i[cnt]++; + if (iz) + A_i[cnt]++; + if (iy) + A_i[cnt]++; + if (ix) + A_i[cnt]++; + if (ix+1 < nx) + A_i[cnt]++; + if (iy+1 < ny) + A_i[cnt]++; + if (iz+1 < nz) + A_i[cnt]++; + cnt++; + } + } + } + + A_j = hypre_CTAlloc(int, A_i[grid_size]); + A_data = hypre_CTAlloc(double, A_i[grid_size]); + + row_index = 0; + cnt = 0; + for (iz = 0; iz < nz; iz++) + { + for (iy = 0; iy < ny; iy++) + { + for (ix = 0; ix < nx; ix++) + { + A_j[cnt] = row_index; + A_data[cnt++] = value[0]; + if (iz) + { + A_j[cnt] = row_index-nx*ny; + A_data[cnt++] = value[3]; + } + if (iy) + { + A_j[cnt] = row_index-nx; + A_data[cnt++] = value[2]; + } + if (ix) + { + A_j[cnt] = row_index-1; + A_data[cnt++] = value[1]; + } + if (ix+1 < nx) + { + A_j[cnt] = row_index+1; + A_data[cnt++] = value[1]; + } + if (iy+1 < ny) + { + A_j[cnt] = row_index+nx; + A_data[cnt++] = value[2]; + } + if (iz+1 < nz) + { + A_j[cnt] = row_index+nx*ny; + A_data[cnt++] = value[3]; + } + row_index++; + } + } + } + + A = hypre_CSRMatrixCreate(grid_size, grid_size, + A_i[grid_size]); + + + rhs = hypre_SeqVectorCreate(grid_size); + hypre_VectorData(rhs) = rhs_data; + + x = hypre_SeqVectorCreate(grid_size); + hypre_VectorData(x) = x_data; + + for (i=0; i < grid_size; i++) + for (j=A_i[i]; j < A_i[i+1]; j++) + sol_data[i] += A_data[j]; + + sol = hypre_SeqVectorCreate(grid_size); + hypre_VectorData(sol) = sol_data; + + hypre_CSRMatrixI(A) = A_i; + hypre_CSRMatrixJ(A) = A_j; + hypre_CSRMatrixData(A) = A_data; + + *rhs_ptr = rhs; + *x_ptr = x; + *sol_ptr = sol; + + return A; +} Added: test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/main.c URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/main.c?rev=59793&view=auto ============================================================================== --- test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/main.c (added) +++ test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/main.c Fri Nov 21 00:17:30 2008 @@ -0,0 +1,286 @@ +/*BHEADER**************************************************************** + * (c) 2007 The Regents of the University of California * + * * + * See the file COPYRIGHT_and_DISCLAIMER for a complete copyright * + * notice and disclaimer. * + * * + *EHEADER****************************************************************/ + +//-------------- +// A micro kernel +//-------------- +#include +#include +#include +#include + +#include "headers.h" + +// +const int testIter = 2000; +double totalWallTime = 0.0; +double totalCPUTime = 0.0; + +// +void test_Matvec(); +void test_Relax(); +void test_Axpy(); + +// +int main(int argc, char *argv[]) +{ + struct timeval t0, t1; + clock_t t0_cpu = 0, + t1_cpu = 0; + + double del_wtime = 0.0; + + + printf("\n"); + printf("//------------ \n"); + printf("// \n"); + printf("// Sequoia Benchmark Version 1.0 \n"); + printf("// \n"); + printf("//------------ \n"); + + gettimeofday(&t0, ((void *)0)); + t0_cpu = clock(); + + // Matvec + totalWallTime = 0.0; + totalCPUTime = 0.0; + + test_Matvec(); + + printf("\n"); + printf("//------------ \n"); + printf("// \n"); + printf("// MATVEC\n"); + printf("// \n"); + printf("//------------ \n"); + +// printf("\nTotal Wall time = %f seconds. \n", totalWallTime); + +// printf("\nTotal CPU time = %f seconds. \n\n", totalCPUTime); + + // Relax + totalWallTime = 0.0; + totalCPUTime = 0.0; + + test_Relax(); + + printf("\n"); + printf("//------------ \n"); + printf("// \n"); + printf("// Relax\n"); + printf("// \n"); + printf("//------------ \n"); + +// printf("\nTotal Wall time = %f seconds. \n", totalWallTime); + +// printf("\nTotal CPU time = %f seconds. \n\n", totalCPUTime); + + // Axpy + totalWallTime = 0.0; + totalCPUTime = 0.0; + + test_Axpy(); + + printf("\n"); + printf("//------------ \n"); + printf("// \n"); + printf("// Axpy\n"); + printf("// \n"); + printf("//------------ \n"); + +// printf("\nTotal Wall time = %f seconds. \n", totalWallTime); + +// printf("\nTotal CPU time = %f seconds. \n\n", totalCPUTime); + + + gettimeofday(&t1, ((void *)0)); + t1_cpu = clock(); + + del_wtime = (double)(t1.tv_sec - t0.tv_sec) + + (double)(t1.tv_usec - t0.tv_usec)/1000000.0; + +// printf("\nTotal Wall time = %f seconds. \n", del_wtime); +// printf("\nTotal CPU time = %f seconds. \n", ((double) (t1_cpu - t0_cpu))/CLOCKS_PER_SEC); + + return 0; + +} + +void test_Matvec() +{ + struct timeval t0, t1; + clock_t t0_cpu = 0, + t1_cpu = 0; + + hypre_CSRMatrix *A; + hypre_Vector *x, *y, *sol; + int nx, ny, nz, i; + double *values; + double *y_data, *sol_data; + double error, diff; + + nx = 50; /* size per proc nx*ny*nz */ + ny = 50; + nz = 50; + + values = hypre_CTAlloc(double, 4); + values[0] = 6; + values[1] = -1; + values[2] = -1; + values[3] = -1; + + A = GenerateSeqLaplacian(nx, ny, nz, values, &y, &x, &sol); + + hypre_SeqVectorSetConstantValues(x,1); + hypre_SeqVectorSetConstantValues(y,0); + + gettimeofday(&t0, ((void *)0)); + t0_cpu = clock(); + + for (i=0; i error) error = diff; + } + + if (error > 0) printf(" \n Matvec: error: %e\n", error); + + hypre_TFree(values); + hypre_CSRMatrixDestroy(A); + hypre_SeqVectorDestroy(x); + hypre_SeqVectorDestroy(y); + hypre_SeqVectorDestroy(sol); + +} + +void test_Relax() +{ + struct timeval t0, t1; + clock_t t0_cpu = 0, + t1_cpu = 0; + + hypre_CSRMatrix *A; + hypre_Vector *x, *y, *sol; + int nx, ny, nz, i; + double *values; + double *x_data; + double diff, error; + + nx = 50; /* size per proc nx*ny*nz */ + ny = 50; + nz = 50; + + values = hypre_CTAlloc(double, 4); + values[0] = 6; + values[1] = -1; + values[2] = -1; + values[3] = -1; + + A = GenerateSeqLaplacian(nx, ny, nz, values, &y, &x, &sol); + + hypre_SeqVectorSetConstantValues(x,1); + + gettimeofday(&t0, ((void *)0)); + t0_cpu = clock(); + + for (i=0; i error) error = diff; + } + + if (error > 0) printf(" \n Relax: error: %e\n", error); + + hypre_TFree(values); + hypre_CSRMatrixDestroy(A); + hypre_SeqVectorDestroy(x); + hypre_SeqVectorDestroy(y); + hypre_SeqVectorDestroy(sol); + +} + +void test_Axpy() +{ + struct timeval t0, t1; + clock_t t0_cpu = 0, + t1_cpu = 0; + + hypre_Vector *x, *y; + int nx, i; + double alpha=0.5; + double diff, error; + double *y_data; + + nx = 125000; /* size per proc */ + + x = hypre_SeqVectorCreate(nx); + y = hypre_SeqVectorCreate(nx); + + hypre_SeqVectorInitialize(x); + hypre_SeqVectorInitialize(y); + + hypre_SeqVectorSetConstantValues(x,1); + hypre_SeqVectorSetConstantValues(y,1); + + gettimeofday(&t0, ((void *)0)); + t0_cpu = clock(); + + for (i=0; i error) error = diff; + } + + if (error > 0) printf(" \n Axpy: error: %e\n", error); + + totalWallTime += (double)(t1.tv_sec - t0.tv_sec) + + (double)(t1.tv_usec - t0.tv_usec)/1000000.0; + + totalCPUTime += ((double) (t1_cpu - t0_cpu))/CLOCKS_PER_SEC; + + hypre_SeqVectorDestroy(x); + hypre_SeqVectorDestroy(y); + +} + Added: test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/relax.c URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/relax.c?rev=59793&view=auto ============================================================================== --- test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/relax.c (added) +++ test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/relax.c Fri Nov 21 00:17:30 2008 @@ -0,0 +1,154 @@ +/*BHEADER********************************************************************** + * Copyright (c) 2006 The Regents of the University of California. + * Produced at the Lawrence Livermore National Laboratory. + * Written by the HYPRE team. UCRL-CODE-222953. + * All rights reserved. + * + * This file is part of HYPRE (see http://www.llnl.gov/CASC/hypre/). + * Please see the COPYRIGHT_and_LICENSE file for the copyright notice, + * disclaimer, contact information and the GNU Lesser General Public License. + * + * HYPRE 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) version 2.1 dated February 1999. + * + * HYPRE 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 terms and conditions of the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU Lesser 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 + * + * $Revision: 2.8 $ + ***********************************************************************EHEADER*/ + + + + +/****************************************************************************** + * + * Relaxation scheme + * + *****************************************************************************/ + +#include "headers.h" +#include "omp.h" + +/*-------------------------------------------------------------------------- + * hypre_BoomerAMGSeqRelax + *--------------------------------------------------------------------------*/ + +int hypre_BoomerAMGSeqRelax( hypre_CSRMatrix *A, + hypre_Vector *f, + hypre_Vector *u) +{ + double *A_diag_data = hypre_CSRMatrixData(A); + int *A_diag_i = hypre_CSRMatrixI(A); + int *A_diag_j = hypre_CSRMatrixJ(A); + + int n = hypre_CSRMatrixNumRows(A); + + double *u_data = hypre_VectorData(u); + + double *f_data = hypre_VectorData(f); + + double *tmp_data; + + double res; + + + int i, j; + int ii, jj; + int ns, ne, size, rest; + int relax_error = 0; + // int index, start; + int num_threads; + + num_threads = hypre_NumThreads(); + /*----------------------------------------------------------------------- + * Switch statement to direct control based on relax_type: + * relax_type = 3 -> hybrid: SOR-J mix off-processor, SOR on-processor + * with outer relaxation parameters (forward solve) + *-----------------------------------------------------------------------*/ + + /*----------------------------------------------------------------- + * Relax all points. + *-----------------------------------------------------------------*/ + + if (1) + { + tmp_data = hypre_CTAlloc(double,n); +#pragma omp parallel private(num_threads) + { + num_threads = 1; /* omp_get_num_threads(); */ + +#pragma omp for private(i) + for (i = 0; i < n; i++) + tmp_data[i] = u_data[i]; + +#pragma omp for private(i,ii,j,jj,ns,ne,res,rest,size) + for (j = 0; j < num_threads; j++) + { + size = n/num_threads; + rest = n - size*num_threads; + if (j < rest) + { + ns = j*size+j; + ne = (j+1)*size+j+1; + } + else + { + ns = j*size+rest; + ne = (j+1)*size+rest; + } + for (i = ns; i < ne; i++) /* interior points first */ + { + + /*----------------------------------------------------------- + * If diagonal is nonzero, relax point i; otherwise, skip it. + *-----------------------------------------------------------*/ + + if ( A_diag_data[A_diag_i[i]] != 0.0) + { + res = f_data[i]; + for (jj = A_diag_i[i]+1; jj < A_diag_i[i+1]; jj++) + { + ii = A_diag_j[jj]; + if (ii >= ns && ii < ne) + res -= A_diag_data[jj] * u_data[ii]; + else + res -= A_diag_data[jj] * tmp_data[ii]; + } + u_data[i] = res / A_diag_data[A_diag_i[i]]; + } + } + } + } + hypre_TFree(tmp_data); + } + else + { + for (i = 0; i < n; i++) /* interior points first */ + { + + /*----------------------------------------------------------- + * If diagonal is nonzero, relax point i; otherwise, skip it. + *-----------------------------------------------------------*/ + + if ( A_diag_data[A_diag_i[i]] != 0.0) + { + res = f_data[i]; + for (jj = A_diag_i[i]+1; jj < A_diag_i[i+1]; jj++) + { + ii = A_diag_j[jj]; + res -= A_diag_data[jj] * u_data[ii]; + } + u_data[i] = res / A_diag_data[A_diag_i[i]]; + } + } + } + + return(relax_error); +} Added: test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/seq_mv.h URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/seq_mv.h?rev=59793&view=auto ============================================================================== --- test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/seq_mv.h (added) +++ test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/seq_mv.h Fri Nov 21 00:17:30 2008 @@ -0,0 +1,183 @@ +/*BHEADER********************************************************************** + * Copyright (c) 2006 The Regents of the University of California. + * Produced at the Lawrence Livermore National Laboratory. + * Written by the HYPRE team. UCRL-CODE-222953. + * All rights reserved. + * + * This file is part of HYPRE (see http://www.llnl.gov/CASC/hypre/). + * Please see the COPYRIGHT_and_LICENSE file for the copyright notice, + * disclaimer, contact information and the GNU Lesser General Public License. + * + * HYPRE 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) version 2.1 dated February 1999. + * + * HYPRE 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 terms and conditions of the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU Lesser 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 + * + * $Revision: 2.14 $ + ***********************************************************************EHEADER*/ + + + + + +#ifndef hypre_MV_HEADER +#define hypre_MV_HEADER + +#include "utilities.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/****************************************************************************** + * + * Header info for CSR Matrix data structures + * + * Note: this matrix currently uses 0-based indexing. + * + *****************************************************************************/ + +#ifndef hypre_CSR_MATRIX_HEADER +#define hypre_CSR_MATRIX_HEADER + +/*-------------------------------------------------------------------------- + * CSR Matrix + *--------------------------------------------------------------------------*/ + +typedef struct +{ + double *data; + int *i; + int *j; + int num_rows; + int num_cols; + int num_nonzeros; + + /* for compressing rows in matrix multiplication */ + int *rownnz; + int num_rownnz; + + /* Does the CSRMatrix create/destroy `data', `i', `j'? */ + int owns_data; + +} hypre_CSRMatrix; + +/*-------------------------------------------------------------------------- + * Accessor functions for the CSR Matrix structure + *--------------------------------------------------------------------------*/ + +#define hypre_CSRMatrixData(matrix) ((matrix) -> data) +#define hypre_CSRMatrixI(matrix) ((matrix) -> i) +#define hypre_CSRMatrixJ(matrix) ((matrix) -> j) +#define hypre_CSRMatrixNumRows(matrix) ((matrix) -> num_rows) +#define hypre_CSRMatrixNumCols(matrix) ((matrix) -> num_cols) +#define hypre_CSRMatrixNumNonzeros(matrix) ((matrix) -> num_nonzeros) +#define hypre_CSRMatrixRownnz(matrix) ((matrix) -> rownnz) +#define hypre_CSRMatrixNumRownnz(matrix) ((matrix) -> num_rownnz) +#define hypre_CSRMatrixOwnsData(matrix) ((matrix) -> owns_data) + +#endif + + +/****************************************************************************** + * + * Header info for Vector data structure + * + *****************************************************************************/ + +#ifndef hypre_VECTOR_HEADER +#define hypre_VECTOR_HEADER + +/*-------------------------------------------------------------------------- + * hypre_Vector + *--------------------------------------------------------------------------*/ + +typedef struct +{ + double *data; + int size; + + /* Does the Vector create/destroy `data'? */ + int owns_data; + + /* For multivectors...*/ + int num_vectors; /* the above "size" is size of one vector */ + int multivec_storage_method; + /* ...if 0, store colwise v0[0], v0[1], ..., v1[0], v1[1], ... v2[0]... */ + /* ...if 1, store rowwise v0[0], v1[0], ..., v0[1], v1[1], ... */ + /* With colwise storage, vj[i] = data[ j*size + i] + With rowwise storage, vj[i] = data[ j + num_vectors*i] */ + int vecstride, idxstride; + /* ... so vj[i] = data[ j*vecstride + i*idxstride ] regardless of row_storage.*/ + +} hypre_Vector; + +/*-------------------------------------------------------------------------- + * Accessor functions for the Vector structure + *--------------------------------------------------------------------------*/ + +#define hypre_VectorData(vector) ((vector) -> data) +#define hypre_VectorSize(vector) ((vector) -> size) +#define hypre_VectorOwnsData(vector) ((vector) -> owns_data) +#define hypre_VectorNumVectors(vector) ((vector) -> num_vectors) +#define hypre_VectorMultiVecStorageMethod(vector) ((vector) -> multivec_storage_method) +#define hypre_VectorVectorStride(vector) ((vector) -> vecstride ) +#define hypre_VectorIndexStride(vector) ((vector) -> idxstride ) + +#endif + +/* csr_matrix.c */ +hypre_CSRMatrix *hypre_CSRMatrixCreate ( int num_rows , int num_cols , int num_nonzeros ); +int hypre_CSRMatrixDestroy ( hypre_CSRMatrix *matrix ); +int hypre_CSRMatrixInitialize ( hypre_CSRMatrix *matrix ); +int hypre_CSRMatrixSetDataOwner ( hypre_CSRMatrix *matrix , int owns_data ); +int hypre_CSRMatrixSetRownnz ( hypre_CSRMatrix *matrix ); +hypre_CSRMatrix *hypre_CSRMatrixRead ( char *file_name ); +int hypre_CSRMatrixPrint ( hypre_CSRMatrix *matrix , char *file_name ); +int hypre_CSRMatrixCopy ( hypre_CSRMatrix *A , hypre_CSRMatrix *B , int copy_data ); +hypre_CSRMatrix *hypre_CSRMatrixClone ( hypre_CSRMatrix *A ); +hypre_CSRMatrix *hypre_CSRMatrixUnion ( hypre_CSRMatrix *A , hypre_CSRMatrix *B , int *col_map_offd_A , int *col_map_offd_B , int **col_map_offd_C ); + +/* csr_matvec.c */ +int hypre_CSRMatrixMatvec ( double alpha , hypre_CSRMatrix *A , hypre_Vector *x , double beta , hypre_Vector *y ); +int hypre_CSRMatrixMatvecT ( double alpha , hypre_CSRMatrix *A , hypre_Vector *x , double beta , hypre_Vector *y ); +int hypre_CSRMatrixMatvec_FF( double alpha , hypre_CSRMatrix *A , hypre_Vector *x , double beta , hypre_Vector *y , int *CF_marker_x , int *CF_marker_y , int fpt ); + +/* vector.c */ +hypre_Vector *hypre_SeqVectorCreate ( int size ); +hypre_Vector *hypre_SeqMultiVectorCreate ( int size , int num_vectors ); +int hypre_SeqVectorDestroy ( hypre_Vector *vector ); +int hypre_SeqVectorInitialize ( hypre_Vector *vector ); +int hypre_SeqVectorSetDataOwner ( hypre_Vector *vector , int owns_data ); +hypre_Vector *hypre_SeqVectorRead ( char *file_name ); +int hypre_SeqVectorPrint ( hypre_Vector *vector , char *file_name ); +int hypre_SeqVectorSetConstantValues ( hypre_Vector *v , double value ); +int hypre_SeqVectorCopy ( hypre_Vector *x , hypre_Vector *y ); +hypre_Vector *hypre_SeqVectorCloneDeep ( hypre_Vector *x ); +hypre_Vector *hypre_SeqVectorCloneShallow ( hypre_Vector *x ); +int hypre_SeqVectorScale ( double alpha , hypre_Vector *y ); +int hypre_SeqVectorAxpy ( double alpha , hypre_Vector *x , hypre_Vector *y ); +double hypre_SeqVectorInnerProd ( hypre_Vector *x , hypre_Vector *y ); +double hypre_VectorSumElts ( hypre_Vector *vector ); + +/* laplace.c */ +hypre_CSRMatrix *GenerateSeqLaplacian(int nx, int ny , int nz , double *values , hypre_Vector **x_ptr, hypre_Vector **y_ptr, hypre_Vector **sol_ptr) ; + +/* relax.c */ +int hypre_BoomerAMGSeqRelax( hypre_CSRMatrix *A , hypre_Vector *x, hypre_Vector *y) ; + +#ifdef __cplusplus +} +#endif + +#endif + Added: test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/utilities.h URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/utilities.h?rev=59793&view=auto ============================================================================== --- test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/utilities.h (added) +++ test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/utilities.h Fri Nov 21 00:17:30 2008 @@ -0,0 +1,375 @@ + +#ifndef hypre_UTILITIES_HEADER +#define hypre_UTILITIES_HEADER + +#ifdef __cplusplus +extern "C" { +#endif + +/*BHEADER********************************************************************** + * Copyright (c) 2006 The Regents of the University of California. + * Produced at the Lawrence Livermore National Laboratory. + * Written by the HYPRE team, UCRL-CODE-222953. + * All rights reserved. + * + * This file is part of HYPRE (see http://www.llnl.gov/CASC/hypre/). + * Please see the COPYRIGHT_and_LICENSE file for the copyright notice, + * disclaimer and the GNU Lesser General Public License. + * + * 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) version 2.1 dated February 1999. + * + * 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 terms and conditions of the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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 + * + * $Revision: 2.24 $ + ***********************************************************************EHEADER*/ + +/****************************************************************************** + * + * General structures and values + * + *****************************************************************************/ + +#ifndef hypre_GENERAL_HEADER +#define hypre_GENERAL_HEADER + +/*-------------------------------------------------------------------------- + * Define various functions + *--------------------------------------------------------------------------*/ + +#ifndef hypre_max +#define hypre_max(a,b) (((a)<(b)) ? (b) : (a)) +#endif +#ifndef hypre_min +#define hypre_min(a,b) (((a)<(b)) ? (a) : (b)) +#endif + +#ifndef hypre_round +#define hypre_round(x) ( ((x) < 0.0) ? ((int)(x - 0.5)) : ((int)(x + 0.5)) ) +#endif + +#endif +/*BHEADER********************************************************************** + * Copyright (c) 2006 The Regents of the University of California. + * Produced at the Lawrence Livermore National Laboratory. + * Written by the HYPRE team, UCRL-CODE-222953. + * All rights reserved. + * + * This file is part of HYPRE (see http://www.llnl.gov/CASC/hypre/). + * Please see the COPYRIGHT_and_LICENSE file for the copyright notice, + * disclaimer and the GNU Lesser General Public License. + * + * 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) version 2.1 dated February 1999. + * + * 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 terms and conditions of the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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 + * + * $Revision: 2.24 $ + ***********************************************************************EHEADER*/ + +/****************************************************************************** + * + * Header file for memory management utilities + * + *****************************************************************************/ + +#ifndef hypre_MEMORY_HEADER +#define hypre_MEMORY_HEADER + +#ifdef __cplusplus +extern "C" { +#endif + +/*-------------------------------------------------------------------------- + * Use "Debug Malloc Library", dmalloc + *--------------------------------------------------------------------------*/ + +#ifdef HYPRE_MEMORY_DMALLOC + +#define hypre_InitMemoryDebug(id) hypre_InitMemoryDebugDML(id) +#define hypre_FinalizeMemoryDebug() hypre_FinalizeMemoryDebugDML() + +#define hypre_TAlloc(type, count) \ +( (type *)hypre_MAllocDML((unsigned int)(sizeof(type) * (count)),\ + __FILE__, __LINE__) ) + +#define hypre_CTAlloc(type, count) \ +( (type *)hypre_CAllocDML((unsigned int)(count), (unsigned int)sizeof(type),\ + __FILE__, __LINE__) ) + +#define hypre_TReAlloc(ptr, type, count) \ +( (type *)hypre_ReAllocDML((char *)ptr,\ + (unsigned int)(sizeof(type) * (count)),\ + __FILE__, __LINE__) ) + +#define hypre_TFree(ptr) \ +( hypre_FreeDML((char *)ptr, __FILE__, __LINE__), ptr = NULL ) + +/*-------------------------------------------------------------------------- + * Use standard memory routines + *--------------------------------------------------------------------------*/ + +#else + +#define hypre_InitMemoryDebug(id) +#define hypre_FinalizeMemoryDebug() + +#define hypre_TAlloc(type, count) \ +( (type *)hypre_MAlloc((unsigned int)(sizeof(type) * (count))) ) + +#define hypre_CTAlloc(type, count) \ +( (type *)hypre_CAlloc((unsigned int)(count), (unsigned int)sizeof(type)) ) + +#define hypre_TReAlloc(ptr, type, count) \ +( (type *)hypre_ReAlloc((char *)ptr, (unsigned int)(sizeof(type) * (count))) ) + +#define hypre_TFree(ptr) \ +( hypre_Free((char *)ptr), ptr = NULL ) + +#endif + + +#ifdef HYPRE_USE_PTHREADS + +#define hypre_SharedTAlloc(type, count) \ +( (type *)hypre_SharedMAlloc((unsigned int)(sizeof(type) * (count))) ) + + +#define hypre_SharedCTAlloc(type, count) \ +( (type *)hypre_SharedCAlloc((unsigned int)(count),\ + (unsigned int)sizeof(type)) ) + +#define hypre_SharedTReAlloc(ptr, type, count) \ +( (type *)hypre_SharedReAlloc((char *)ptr,\ + (unsigned int)(sizeof(type) * (count))) ) + +#define hypre_SharedTFree(ptr) \ +( hypre_SharedFree((char *)ptr), ptr = NULL ) + +#else + +#define hypre_SharedTAlloc(type, count) hypre_TAlloc(type, (count)) +#define hypre_SharedCTAlloc(type, count) hypre_CTAlloc(type, (count)) +#define hypre_SharedTReAlloc(type, count) hypre_TReAlloc(type, (count)) +#define hypre_SharedTFree(ptr) hypre_TFree(ptr) + +#endif + +/*-------------------------------------------------------------------------- + * Prototypes + *--------------------------------------------------------------------------*/ + +/* hypre_memory.c */ +int hypre_OutOfMemory( int size ); +char *hypre_MAlloc( int size ); +char *hypre_CAlloc( int count , int elt_size ); +char *hypre_ReAlloc( char *ptr , int size ); +void hypre_Free( char *ptr ); +char *hypre_SharedMAlloc( int size ); +char *hypre_SharedCAlloc( int count , int elt_size ); +char *hypre_SharedReAlloc( char *ptr , int size ); +void hypre_SharedFree( char *ptr ); +double *hypre_IncrementSharedDataPtr( double *ptr , int size ); + +#ifdef __cplusplus +} +#endif + +#endif + +/*BHEADER********************************************************************** + * Copyright (c) 2006 The Regents of the University of California. + * Produced at the Lawrence Livermore National Laboratory. + * Written by the HYPRE team, UCRL-CODE-222953. + * All rights reserved. + * + * This file is part of HYPRE (see http://www.llnl.gov/CASC/hypre/). + * Please see the COPYRIGHT_and_LICENSE file for the copyright notice, + * disclaimer and the GNU Lesser General Public License. + * + * 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) version 2.1 dated February 1999. + * + * 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 terms and conditions of the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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 + * + * $Revision: 2.24 $ + ***********************************************************************EHEADER*/ + + +#ifndef hypre_THREADING_HEADER +#define hypre_THREADING_HEADER + +#if defined(HYPRE_USING_OPENMP) || defined (HYPRE_USING_PGCC_SMP) + +int hypre_NumThreads( void ); + +#else + +#define hypre_NumThreads() 1 + +#endif + + +/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ +/* The pthreads stuff needs to be reworked */ + +#ifdef HYPRE_USE_PTHREADS + +#ifndef MAX_QUEUE +#define MAX_QUEUE 256 +#endif + +#include + +/* hypre_work_proc_t typedef'd to be a pointer to a function with a void* + argument and a void return type */ +typedef void (*hypre_work_proc_t)(void *); + +typedef struct hypre_workqueue_struct { + pthread_mutex_t lock; + pthread_cond_t work_wait; + pthread_cond_t finish_wait; + hypre_work_proc_t worker_proc_queue[MAX_QUEUE]; + int n_working; + int n_waiting; + int n_queue; + int inp; + int outp; + void *argqueue[MAX_QUEUE]; +} *hypre_workqueue_t; + +void hypre_work_put( hypre_work_proc_t funcptr, void *argptr ); +void hypre_work_wait( void ); +int HYPRE_InitPthreads( int num_threads ); +void HYPRE_DestroyPthreads( void ); +void hypre_pthread_worker( int threadid ); +int ifetchadd( int *w, pthread_mutex_t *mutex_fetchadd ); +int hypre_fetch_and_add( int *w ); +void hypre_barrier(pthread_mutex_t *mpi_mtx, int unthreaded); +int hypre_GetThreadID( void ); + +pthread_t initial_thread; +pthread_t hypre_thread[hypre_MAX_THREADS]; +pthread_mutex_t hypre_mutex_boxloops; +pthread_mutex_t talloc_mtx; +pthread_mutex_t worker_mtx; +hypre_workqueue_t hypre_qptr; +pthread_mutex_t mpi_mtx; +pthread_mutex_t time_mtx; +volatile int hypre_thread_release; + +#ifdef HYPRE_THREAD_GLOBALS +int hypre_NumThreads = 4; +#else +extern int hypre_NumThreads; +#endif + +#endif +/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ + +#endif + +/*BHEADER********************************************************************** + * Copyright (c) 2006 The Regents of the University of California. + * Produced at the Lawrence Livermore National Laboratory. + * Written by the HYPRE team, UCRL-CODE-222953. + * All rights reserved. + * + * This file is part of HYPRE (see http://www.llnl.gov/CASC/hypre/). + * Please see the COPYRIGHT_and_LICENSE file for the copyright notice, + * disclaimer and the GNU Lesser General Public License. + * + * 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) version 2.1 dated February 1999. + * + * 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 terms and conditions of the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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 + * + * $Revision: 2.24 $ + ***********************************************************************EHEADER*/ + + +#ifndef hypre_ERROR_HEADER +#define hypre_ERROR_HEADER + +/*-------------------------------------------------------------------------- + * HYPRE error codes + *--------------------------------------------------------------------------*/ + +#define HYPRE_ERROR_GENERIC 1 /* generic error */ +#define HYPRE_ERROR_MEMORY 2 /* unable to allocate memory */ +#define HYPRE_ERROR_ARG 4 /* argument error */ +/* bits 4-8 are reserved for the index of the argument error */ +#define HYPRE_ERROR_CONV 256 /* method did not converge as expected */ + +/*-------------------------------------------------------------------------- + * Global variable used in hypre error checking + *--------------------------------------------------------------------------*/ + +extern int hypre__global_error; +#define hypre_error_flag hypre__global_error + +/*-------------------------------------------------------------------------- + * HYPRE error macros + *--------------------------------------------------------------------------*/ + +void hypre_error_handler(char *filename, int line, int ierr); +#define hypre_error(IERR) hypre_error_handler(__FILE__, __LINE__, IERR) +#define hypre_error_in_arg(IARG) hypre_error(HYPRE_ERROR_ARG | IARG<<3) +#ifdef NDEBUG +#define hypre_assert(EX) +#else +#define hypre_assert(EX) if (!(EX)) {fprintf(stderr,"hypre_assert failed: %s\n", #EX); hypre_error(1);} +#endif +/*-------------------------------------------------------------------------- + * HYPRE error user functions + *--------------------------------------------------------------------------*/ + +/* Return the current hypre error flag */ +int HYPRE_GetError(); + +/* Check if the given error flag contains the given error code */ +int HYPRE_CheckError(int hypre_ierr, int hypre_error_code); + +/* Return the index of the argument (counting from 1) where + argument error (HYPRE_ERROR_ARG) has occured */ +int HYPRE_GetErrorArg(); + +/* Describe the given error flag in the given string */ +void HYPRE_DescribeError(int hypre_ierr, char *descr); + + +#endif + +#endif Added: test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/vector.c URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/vector.c?rev=59793&view=auto ============================================================================== --- test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/vector.c (added) +++ test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/vector.c Fri Nov 21 00:17:30 2008 @@ -0,0 +1,429 @@ +/*BHEADER********************************************************************** + * Copyright (c) 2006 The Regents of the University of California. + * Produced at the Lawrence Livermore National Laboratory. + * Written by the HYPRE team. UCRL-CODE-222953. + * All rights reserved. + * + * This file is part of HYPRE (see http://www.llnl.gov/CASC/hypre/). + * Please see the COPYRIGHT_and_LICENSE file for the copyright notice, + * disclaimer, contact information and the GNU Lesser General Public License. + * + * HYPRE 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) version 2.1 dated February 1999. + * + * HYPRE 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 terms and conditions of the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU Lesser 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 + * + * $Revision: 2.8 $ + ***********************************************************************EHEADER*/ + + + +/****************************************************************************** + * + * Member functions for hypre_Vector class. + * + *****************************************************************************/ + +#include "headers.h" +#include + +/*-------------------------------------------------------------------------- + * hypre_SeqVectorCreate + *--------------------------------------------------------------------------*/ + +hypre_Vector * +hypre_SeqVectorCreate( int size ) +{ + hypre_Vector *vector; + + vector = hypre_CTAlloc(hypre_Vector, 1); + + hypre_VectorData(vector) = NULL; + hypre_VectorSize(vector) = size; + + hypre_VectorNumVectors(vector) = 1; + hypre_VectorMultiVecStorageMethod(vector) = 0; + + /* set defaults */ + hypre_VectorOwnsData(vector) = 1; + + return vector; +} + +/*-------------------------------------------------------------------------- + * hypre_SeqMultiVectorCreate + *--------------------------------------------------------------------------*/ + +hypre_Vector * +hypre_SeqMultiVectorCreate( int size, int num_vectors ) +{ + hypre_Vector *vector = hypre_SeqVectorCreate(size); + hypre_VectorNumVectors(vector) = num_vectors; + return vector; +} + +/*-------------------------------------------------------------------------- + * hypre_SeqVectorDestroy + *--------------------------------------------------------------------------*/ + +int +hypre_SeqVectorDestroy( hypre_Vector *vector ) +{ + int ierr=0; + + if (vector) + { + if ( hypre_VectorOwnsData(vector) ) + { + hypre_TFree(hypre_VectorData(vector)); + } + hypre_TFree(vector); + } + + return ierr; +} + +/*-------------------------------------------------------------------------- + * hypre_SeqVectorInitialize + *--------------------------------------------------------------------------*/ + +int +hypre_SeqVectorInitialize( hypre_Vector *vector ) +{ + int size = hypre_VectorSize(vector); + int ierr = 0; + int num_vectors = hypre_VectorNumVectors(vector); + int multivec_storage_method = hypre_VectorMultiVecStorageMethod(vector); + + if ( ! hypre_VectorData(vector) ) + hypre_VectorData(vector) = hypre_CTAlloc(double, num_vectors*size); + + if ( multivec_storage_method == 0 ) + { + hypre_VectorVectorStride(vector) = size; + hypre_VectorIndexStride(vector) = 1; + } + else if ( multivec_storage_method == 1 ) + { + hypre_VectorVectorStride(vector) = 1; + hypre_VectorIndexStride(vector) = num_vectors; + } + else + ++ierr; + + + return ierr; +} + +/*-------------------------------------------------------------------------- + * hypre_SeqVectorSetDataOwner + *--------------------------------------------------------------------------*/ + +int +hypre_SeqVectorSetDataOwner( hypre_Vector *vector, + int owns_data ) +{ + int ierr=0; + + hypre_VectorOwnsData(vector) = owns_data; + + return ierr; +} + +/*-------------------------------------------------------------------------- + * ReadVector + *--------------------------------------------------------------------------*/ + +hypre_Vector * +hypre_SeqVectorRead( char *file_name ) +{ + hypre_Vector *vector; + + FILE *fp; + + double *data; + int size; + + int j; + + /*---------------------------------------------------------- + * Read in the data + *----------------------------------------------------------*/ + + fp = fopen(file_name, "r"); + + fscanf(fp, "%d", &size); + + vector = hypre_SeqVectorCreate(size); + hypre_SeqVectorInitialize(vector); + + data = hypre_VectorData(vector); + for (j = 0; j < size; j++) + { + fscanf(fp, "%le", &data[j]); + } + + fclose(fp); + + /* multivector code not written yet >>> */ + hypre_assert( hypre_VectorNumVectors(vector) == 1 ); + + return vector; +} + +/*-------------------------------------------------------------------------- + * hypre_SeqVectorPrint + *--------------------------------------------------------------------------*/ + +int +hypre_SeqVectorPrint( hypre_Vector *vector, + char *file_name ) +{ + FILE *fp; + + double *data; + int size, num_vectors, vecstride, idxstride; + + int i, j; + + int ierr = 0; + + num_vectors = hypre_VectorNumVectors(vector); + vecstride = hypre_VectorVectorStride(vector); + idxstride = hypre_VectorIndexStride(vector); + + /*---------------------------------------------------------- + * Print in the data + *----------------------------------------------------------*/ + + data = hypre_VectorData(vector); + size = hypre_VectorSize(vector); + + fp = fopen(file_name, "w"); + + if ( hypre_VectorNumVectors(vector) == 1 ) + { + fprintf(fp, "%d\n", size); + } + else + { + fprintf(fp, "%d vectors of size %d\n", num_vectors, size ); + } + + if ( num_vectors>1 ) + { + for ( j=0; j +#include +#include +#include +#include "irsmk.h" + + +void allocMem(RadiationData_t *); +void init(Domain_t *, RadiationData_t *, double *, double *); +void readInput(); +void rmatmult3(Domain_t *, RadiationData_t *, double *, double *); + + +int main() +{ + Domain_t domain; + Domain_t *domain_ptr = &domain; + + RadiationData_t rblk; + RadiationData_t *rblk_ptr = &rblk; + + struct timeval t0, t1; + clock_t t0_cpu = 0, + t1_cpu = 0; + + double del_wtime = 0.0; + double *x; + double *b; + + int i = 0; + const int noIter = 5000; + + printf ("\nSequoia Benchmark Version 1.0\n\n"); + + // + readInput(); + + b = (double *)malloc(i_ub*sizeof(double)); + x = (double *)malloc(x_size*sizeof(double)); + + allocMem(rblk_ptr); + + init(domain_ptr, rblk_ptr, x, b); + + gettimeofday(&t0, ((void *)0)); + t0_cpu = clock(); + for (i=0; iimin ; + int imax = domain->imax ; + int jmin = domain->jmin ; + int jmax = domain->jmax ; + int kmin = domain->kmin ; + int kmax = domain->kmax ; + int jp = domain->jp ; + int kp = domain->kp ; + double *dbl = rblk->dbl ; + double *dbc = rblk->dbc ; + double *dbr = rblk->dbr ; + double *dcl = rblk->dcl ; + double *dcc = rblk->dcc ; + double *dcr = rblk->dcr ; + double *dfl = rblk->dfl ; + double *dfc = rblk->dfc ; + double *dfr = rblk->dfr ; + double *cbl = rblk->cbl ; + double *cbc = rblk->cbc ; + double *cbr = rblk->cbr ; + double *ccl = rblk->ccl ; + double *ccc = rblk->ccc ; + double *ccr = rblk->ccr ; + double *cfl = rblk->cfl ; + double *cfc = rblk->cfc ; + double *cfr = rblk->cfr ; + double *ubl = rblk->ubl ; + double *ubc = rblk->ubc ; + double *ubr = rblk->ubr ; + double *ucl = rblk->ucl ; + double *ucc = rblk->ucc ; + double *ucr = rblk->ucr ; + double *ufl = rblk->ufl ; + double *ufc = rblk->ufc ; + double *ufr = rblk->ufr ; + double *xdbl = x - kp - jp - 1 ; + double *xdbc = x - kp - jp ; + double *xdbr = x - kp - jp + 1 ; + double *xdcl = x - kp - 1 ; + double *xdcc = x - kp ; + double *xdcr = x - kp + 1 ; + double *xdfl = x - kp + jp - 1 ; + double *xdfc = x - kp + jp ; + double *xdfr = x - kp + jp + 1 ; + double *xcbl = x - jp - 1 ; + double *xcbc = x - jp ; + double *xcbr = x - jp + 1 ; + double *xccl = x - 1 ; + double *xccc = x ; + double *xccr = x + 1 ; + double *xcfl = x + jp - 1 ; + double *xcfc = x + jp ; + double *xcfr = x + jp + 1 ; + double *xubl = x + kp - jp - 1 ; + double *xubc = x + kp - jp ; + double *xubr = x + kp - jp + 1 ; + double *xucl = x + kp - 1 ; + double *xucc = x + kp ; + double *xucr = x + kp + 1 ; + double *xufl = x + kp + jp - 1 ; + double *xufc = x + kp + jp ; + double *xufr = x + kp + jp + 1 ; + + + for ( kk = kmin ; kk < kmax ; kk++ ) { + for ( jj = jmin ; jj < jmax ; jj++ ) { + for ( ii = imin ; ii < imax ; ii++ ) { + i = ii + jj * jp + kk * kp ; + b[i] = dbl[i] * xdbl[i] + dbc[i] * xdbc[i] + dbr[i] * xdbr[i] + + dcl[i] * xdcl[i] + dcc[i] * xdcc[i] + dcr[i] * xdcr[i] + + dfl[i] * xdfl[i] + dfc[i] * xdfc[i] + dfr[i] * xdfr[i] + + cbl[i] * xcbl[i] + cbc[i] * xcbc[i] + cbr[i] * xcbr[i] + + ccl[i] * xccl[i] + ccc[i] * xccc[i] + ccr[i] * xccr[i] + + cfl[i] * xcfl[i] + cfc[i] * xcfc[i] + cfr[i] * xcfr[i] + + ubl[i] * xubl[i] + ubc[i] * xubc[i] + ubr[i] * xubr[i] + + ucl[i] * xucl[i] + ucc[i] * xucc[i] + ucr[i] * xucr[i] + + ufl[i] * xufl[i] + ufc[i] * xufc[i] + ufr[i] * xufr[i] ; + } + } + } + +} Added: test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/IRSmk/utility.c URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/IRSmk/utility.c?rev=59793&view=auto ============================================================================== --- test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/IRSmk/utility.c (added) +++ test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/IRSmk/utility.c Fri Nov 21 00:17:30 2008 @@ -0,0 +1,191 @@ +/*BHEADER**************************************************************** + * (c) 2006 The Regents of the University of California * + * * + * See the file COPYRIGHT_and_DISCLAIMER for a complete copyright * + * notice and disclaimer. * + * * + *EHEADER****************************************************************/ + +#include +#include +#include "irsmk.h" + + +//-------------- +// read input date +//-------------- +void readInput() +{ + FILE *fp; + if ((fp = fopen("irsmk_input", "r"))==NULL) { + printf("***** ERROR \n"); + printf(" Cannot open input file irsmk_input \n"); + exit(1); + } + + fscanf(fp, "%d %d %d %d %d %d %d %d", + &kmin, &kmax, &jmin, &jmax, &imin, &imax, &kp, &jp); + + printf("***** input \n"); + printf("kmin = %8d kmax = %8d \n" + "jmin = %8d jmax = %8d \n" + "imin = %8d imax = %8d \n" + "kp = %8d jp = %8d \n \n \n", + kmin, kmax, jmin, jmax, imin, imax, kp, jp); + + + //----- + // set array size + //----- + i_lb = imin + jmin*jp + kmin*kp; + i_ub = (imax - 1) + (jmax -1)*jp + (kmax - 1)*kp + 1; + + //----- + // sanity check for xdbl + //----- + if ((i_lb - kp - jp - 1) < 0) { + printf("***** ERROR \n"); + printf(" lb of xdbl < 0 \n"); + exit(1); + } + + //----- + // in theory + // x_size = i_ub + + // kp + jp + 1 + // for xdbl + // kp + jp + 1 // for xufr + // I just add 10 elements for safety + //----- + x_size = i_ub + 2*(kp + jp + 1) + 10; + + printf("***** array bounds \n"); + printf("i_lb = %10d i_ub = %10d x_size = %10d \n \n \n", + i_lb, i_ub, x_size); + + fclose(fp); + +} + + +//-------------- +// alloc memory +//-------------- +void allocMem(RadiationData_t *rblk) +{ + int size; + + size = i_ub*sizeof(double); + + rblk->dbl = (double *)malloc(size); + rblk->dbc = (double *)malloc(size); + rblk->dbr = (double *)malloc(size); + rblk->dcl = (double *)malloc(size); + rblk->dcc = (double *)malloc(size); + rblk->dcr = (double *)malloc(size); + rblk->dfl = (double *)malloc(size); + rblk->dfc = (double *)malloc(size); + rblk->dfr = (double *)malloc(size); + rblk->cbl = (double *)malloc(size); + rblk->cbc = (double *)malloc(size); + rblk->cbr = (double *)malloc(size); + rblk->ccl = (double *)malloc(size); + rblk->ccc = (double *)malloc(size); + rblk->ccr = (double *)malloc(size); + rblk->cfl = (double *)malloc(size); + rblk->cfc = (double *)malloc(size); + rblk->cfr = (double *)malloc(size); + rblk->ubl = (double *)malloc(size); + rblk->ubc = (double *)malloc(size); + rblk->ubr = (double *)malloc(size); + rblk->ucl = (double *)malloc(size); + rblk->ucc = (double *)malloc(size); + rblk->ucr = (double *)malloc(size); + rblk->ufl = (double *)malloc(size); + rblk->ufc = (double *)malloc(size); + rblk->ufr = (double *)malloc(size); + + if ( (rblk->ufr)== NULL) printf("*****ERROR: allocMem out of memory \n"); + +} + + +//-------------- +// init +//-------------- +void init(Domain_t *domain, RadiationData_t *rblk, double *x, double *b ) +{ + int i; + + domain->imin = imin; + domain->imax = imax; + domain->jmin = jmin; + domain->jmax = jmax; + domain->kmin = kmin; + domain->kmax = kmax; + domain->jp = jp; + domain->kp = kp; + double *dbl = rblk->dbl ; + double *dbc = rblk->dbc ; + double *dbr = rblk->dbr ; + double *dcl = rblk->dcl ; + double *dcc = rblk->dcc ; + double *dcr = rblk->dcr ; + double *dfl = rblk->dfl ; + double *dfc = rblk->dfc ; + double *dfr = rblk->dfr ; + double *cbl = rblk->cbl ; + double *cbc = rblk->cbc ; + double *cbr = rblk->cbr ; + double *ccl = rblk->ccl ; + double *ccc = rblk->ccc ; + double *ccr = rblk->ccr ; + double *cfl = rblk->cfl ; + double *cfc = rblk->cfc ; + double *cfr = rblk->cfr ; + double *ubl = rblk->ubl ; + double *ubc = rblk->ubc ; + double *ubr = rblk->ubr ; + double *ucl = rblk->ucl ; + double *ucc = rblk->ucc ; + double *ucr = rblk->ucr ; + double *ufl = rblk->ufl ; + double *ufc = rblk->ufc ; + double *ufr = rblk->ufr ; + + + for (i = 0 ; i < i_ub; i++ ) { + *b++ = 0.0; + *dbl++ = i; + *dbc++ = i+1; + *dbr++ = i+2; + *dcl++ = i+3; + *dcc++ = i+4; + *dcr++ = i+5; + *dfl++ = i+6; + *dfc++ = i+7; + *dfr++ = i+8; + *cbl++ = i+9; + *cbc++ = i+10; + *cbr++ = i+11; + *ccl++ = i+12; + *ccc++ = i+13; + *ccr++ = i+14; + *cfl++ = i+15; + *cfc++ = i+16; + *cfr++ = i+17; + *ubl++ = i+18; + *ubc++ = i+19; + *ubr++ = i+20; + *ucl++ = i+21; + *ucc++ = i+22; + *ucr++ = i+23; + *ufl++ = i+24; + *ufc++ = i+25; + *ufr++ = i+26; + } + + for (i=0; i no intersection, => skip + d = sqrt(disc) + + l1 = (d - bb)/aa + if (l1 .ge. 1.0d-10) then + z1 = z + w*l1 + zzidks = zz(id,ks) + zzidks1= zz(id,ks+1) + isign = (z1.lt.zzidks .and. z1.lt.zzidks1 ) .or. + | (z1.gt.zzidks1 .and. z1.gt.zzidks ) + if (isign) l1 = 1000.0d0 + if (l1 .lt. lmin) lmin = l1 + endif + + l2 = (-bb - d)/aa + if (l2 .ge. 1.0d-10) then + z2 = z + w*l2 + zzidks = zz(id,ks) + zzidks1= zz(id,ks+1) + isign = (z2.lt.zzidks .and. z2.lt.zzidks1 ) .or. + | (z2.gt.zzidks1 .and. z2.gt.zzidks ) + if (isign) l2 = 1000.0d0 + if (l2 .lt. lmin) lmin = l2 + endif + go to 44 ! to test against minimum intersection distance + +c------------------- vertical zone side + 10 lmin = (zz(id,ks) - z) / w + x1 = x + u*lmin + y1 = y + v*lmin + r1 = sqrt(x1*x1 + y1*y1) + isign = (r1.lt.rr(id,ks ) .and. r1.lt.rr(id,ks+1)) + | .or. (r1.gt.rr(id,ks+1) .and. r1.gt.rr(id,ks )) + if (isign) lmin = 1000.0d0 + go to 44 ! to test against minimum intersection distance + +c------------------- horizontal zone side + 30 aa = 1.0d0 - w*w + bb = x*u + y*v + cc = x*v - y*u + disc = aa*rr(id,ks)*rr(id,ks) - cc*cc + if (disc .lt. 0.0d0) go to 4 + d = sqrt(disc) + + l1 = (d - bb)/aa + if (l1 .ge. 1.0d-10) then + z1 = z + w*l1 + isign = (z1.lt.zz(id,ks ) .and. z1.lt.zz(id,ks+1)) + | .or. (z1.gt.zz(id,ks+1) .and. z1.gt.zz(id,ks )) + if (isign) l1 = 1000.0d0 + if (l1 .lt. lmin) lmin = l1 + endif + + l2 = (-bb - d)/aa + if (l2 .ge. 1.0d-10) then + z2 = z + w*l2 + isign = (z2.lt.zz(id,ks ) .and. z2.lt.zz(id,ks+1)) + | .or. (z2.gt.zz(id,ks+1) .and. z2.gt.zz(id,ks )) + if (isign) l2 = 1000.0d0 + if (l2 .lt. lmin) lmin = l2 + endif + go to 44 ! to test against minimum intersection distance + + 44 if ((lmin .le. l ) .and. + | (lmin .gt. 0.0d0)) then ! new minimum distance found + l = lmin ! remember the distance + iside = ks ! and the side of closest intersection + endif + + 4 continue ! end of section testing intersection with edges + +c----- DETERMINE THE FATE OF THE PARTICLE: +c absorbed, escaped, moved, scattered or censused + + if (l .eq. 1000.0d0) then ! no intersection found! => LOST + nlost = nlost + 1 + wlost = wlost + newgt + go to 15 ! to check for saved photon to track + endif + + dist = -log(ranf(mySeed)) / sig(ir,ig) ! distance to collision + dcen = (tcen - age) * 2.99793d10 ! distance to census (i.e., end of time step) + + if (l .lt. dist .and. l .lt. dcen) go to 26 ! move to the boundary intersection + + if (dist .lt. dcen) then + noscat = ranf(mySeed) .gt. scrat(ir,ig) ! probability of scattering vis. absorption + if (noscat) then +c------------------------------absorption + nabs = nabs + 1 + wabs = wabs + newgt +c.....DEPOSITION..... +!$OMP ATOMIC + depArray(id) = depArray(id) + newgt ! deposit absorbed energy in the zone + +c.....END DEPOSITION + + else +c------------------------------Thomson scattering + nscat = nscat + 1 ! count the scatters + x = x + u*dist ! move in 3D to the point of scattering + y = y + v*dist + z = z + w*dist + age = age + dist*3.3356349d-11 ! advance the "age" of the photon + CALL thom (u, v, w, mySeed) + ! + + if (irr .eq. 2) go to 525 ! rr/splitting via relative bundle size + go to 45 ! to continue tracking + end if + else +c------------------------------Census time. Fake putting the particle into storage + +!$OMP critical + + DummyArray(10) = x + DummyArray(10) = y + DummyArray(10) = z + DummyArray(10) = u + DummyArray(10) = v + DummyArray(10) = w + DummyArray(10) = age + DummyArray(10) = newgt + +!$OMP end critical + + ncen = ncen + 1 + wcen = wcen + newgt + + end if + go to 15 ! to check for saved photon to track + +c-------------------------------------------------- MOVE THE PARTICLE TO THE CORRECT BOUNDARY + 26 idold = id + id = id + ng_incr(iside) ! zone ID changed according to which side was crossed + + if ( id .gt. nzones ) then +c-------------------------------------------------- Escaped + nescgp(ig) = nescgp(ig) + 1 + enesc (ig) = enesc (ig) + newgt + go to 15 ! to check for saved photon to track + endif + + ir = mid (id) + x = x + u*l ! what about right on the side? + y = y + v*l + z = z + w*l + age = age + l*3.3356349d-11 ! distance divided by the speed of light + +c--------------------russian roulette/splitting options + +c irr = 0 no rr/splitting +c irr = 1 rr/splitting via relative zone importances +c irr = 2 rr/splitting via relative bundle size + + if (irr .eq. 0) go to 45 ! to continue tracking + if (irr .eq. 2) go to 525 ! rr/splitting via relative bundle size + +c-------------------- rr/splitting via zone importances +c (only applies to particles which cross zone boundaries) + + if (ximp(id) .eq. ximp(idold)) go to 45 ! NO change in zone importance. => continue tracking + r = ximp(id) / ximp(idold) + + zeta = ranf(mySeed) + ir1 = r + r1 = dble(ir1) + ir0 = ir1 - 1 + r0 = r - r1 + + if (r .lt. 1.0d0) then +c------------------------------russian roulette + if (zeta .lt. r0) then +c------------------------------ survive + rinv = 1.0d0 / r + wrr = wrr + newgt * (rinv - 1.0d0) + newgt = newgt * rinv + go to 45 ! to continue tracking + endif +c------------------------------ kill + nrr = nrr + 1 + wrr = wrr - newgt + go to 15 ! to check for saved photon to track + endif + +c------------------------------ split + if (zeta .lt. r0) then +c------------------------------ split high + newgt = newgt / (r1 + 1.0d0) + isplt = isplt + ir1 + nsplt = nsplt + ir1 + go to 415 ! to save new photon in storage + endif +c-----------------------------split low + if (ir0 .le. 0) go to 45 ! to continue tracking + r1 = dble(ir0) + isplt = isplt + ir0 + nsplt = nsplt + ir0 + newgt = newgt / (r1 + 1.0d0) + go to 415 ! to save new photon in storage + +c------------------------------ rr/splitting via relative bundle size + 525 r = newgt + if (r .lt. wmin) then +c------------------------------russian roulette + if (ranf(mySeed) .lt. r) then +c------------------------------survive + wrr = wrr + 1.0d0 - r + newgt = 1.0d0 + go to 45 ! to continue tracking + endif +c------------------------------kill + nrr = nrr + 1 + wrr = wrr - newgt + go to 15 ! to check for saved photon to track + endif +c------------------------------split + if (r .lt. wmax) go to 45 ! to continue tracking + ir0 = r + ir1 = ir0 - 1 + if (ir1 .le. 0) go to 45 ! to continue tracking + + r1 = dble(ir1) + newgt = newgt/(r1 + 1.0) + isplt = isplt + ir1 + nsplt = nsplt + ir1 + +c------------------------------save position, direction, age, zone and weight +c of cloned particles + 415 iend = isplt + do 317 i1 = ibegin,iend + xsv (i1) = x + ysv (i1) = y + zsv (i1) = z + usv (i1) = u + vsv (i1) = v + wsv (i1) = w + agesv(i1) = age + wgtsv(i1) = newgt + idsv (i1) = id + irsv (i1) = ir + 317 continue + + ibegin = iend + 1 + go to 45 ! to continue tracking + + 15 if (isplt .ne. 0) then +c------------------------------now dispense split particles from group ig + x = xsv (isplt) + y = ysv (isplt) + z = zsv (isplt) + u = usv (isplt) + v = vsv (isplt) + w = wsv (isplt) + age = agesv(isplt) + newgt = wgtsv(isplt) + id = idsv (isplt) + ir = irsv (isplt) + isplt = isplt - 1 + ibegin = ibegin - 1 + go to 45 ! to continue tracking + endif + + 159 continue ! end of loop over the number of photons emitted in zone iz and group ig + + 150 continue ! end of loop over energy groups + + 400 continue ! end of loop over zones + + return + end Added: test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/genmesh.f URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/genmesh.f?rev=59793&view=auto ============================================================================== --- test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/genmesh.f (added) +++ test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/genmesh.f Fri Nov 21 00:17:30 2008 @@ -0,0 +1,144 @@ + + subroutine genmesh +c---------------------------------------------------------------------- +c A simple polar mesh is generated. +c---------------------------------------------------------------------- + include 'params.inc' + include 'geomz.inc' + include 'globals.inc' + + double precision m +c--------------------initialize variables + pi = 3.141592653589793238d0 + ng_incr(1) = 1 + ng_incr(2) = -naxl + ng_incr(3) = -1 + ng_incr(4) = naxl + + if (irr .ne. 0) then +c--------------------assign cell importances (or weight limits) for rr + +cc.....Seems that impl decreases geometrically with radius....MJC + if (irr .eq. 1) then + + g_ximpl(1) = 1.0d0 + do 221 i = 2,nradl + g_ximpl(i) = xmult * g_ximpl(i-1) + 221 continue + +c...fill a polar array with these values, equal azumuthally MJC + do 222 i = 1,nradl + do 223 k = 1,naxl + iz = k + (i-1)*naxl + g_ximp(iz) = g_ximpl(i) + 223 continue + 222 continue + + else + wmin = wcut + wmax= 1.0d0 / wcut + endif + + endif + +c..The number above implies that the center node is #1 and that the next +c..layer of nodes around is is numbered increasingly either clockwise or +c..counter clockwise. MJC + + +c--------------------assign cell numbers and cell coordinates + + nzones = nradl * naxl + hr = radl / nradl + ha = (axl*pi)/(naxl*180.0d0) + naxpls = naxl + 1 + do 1 iang = 1,naxpls + ang = (iang-1)*ha + cs = cos(ang) + sn = sin(ang) + do 2 ird=1,nradl + r = (ird*hr)*sn + z = (ird*hr)*cs + + if (iang .le. 1) goto 50 + jc = ird*naxl - iang + 2 + g_zz(jc,4) = z + g_rr(jc,4) = r + + if (ird .ge. nradl) goto 50 + jc = jc+naxl + g_zz(jc,3) = z + g_rr(jc,3) = r + + 50 continue + + if (iang .ge. naxpls) goto 51 + jc = ird*naxl - iang + 1 + g_zz(jc,1) = z + g_rr(jc,1) = r + if (ird .ge. nradl) goto 51 + jc = jc+naxl + g_zz(jc,2) = z + g_rr(jc,2) = r + + 51 continue + + 2 continue + 1 continue + + do 3 ii = 1,nzones + do 8 ij = 1,4 + if (abs(g_zz(ii,ij)) .lt. 1.0e-9) g_zz(ii,ij) = 0.0d0 + if (abs(g_rr(ii,ij)) .lt. 1.0e-9) g_rr(ii,ij) = 0.0d0 + 8 continue + g_zz(ii,5) = g_zz(ii,1) + g_rr(ii,5) = g_rr(ii,1) + 3 continue + + +c------------------------------compute SLOPE and INTERCEPT of cell sides, +c and categorize special cases: +c 1 = normal cell, +c 2 = cell on z-axis, +c 3 = horizontal side, +c 4 = vertical side + + do 60 i = 1,nzones + do 61 ks = 1,4 + rdif = g_rr(i,ks+1) - g_rr(i,ks) + zdif = g_zz(i,ks+1) - g_zz(i,ks) + + if ((g_rr(i,ks).eq.0.0d0).and.(g_rr(i,ks+1).eq.0.0d0)) then + ng_itype(i,ks) = 2 + else if (abs(rdif) .lt. 1.0d-9) then + ng_itype(i,ks) = 3 + else if (abs(zdif) .lt. 1.0d-9) then + ng_itype(i,ks) = 4 + else + ng_itype(i,ks) = 1 + end if + + if (ng_itype(i,ks) .eq. 1) then + + if ((ks .eq. 1) .or. (ks .eq. 3)) then + m = rdif/zdif + b = 0.0d0 + g_sqm(i,ks) = m*m + g_bom(i,ks) = 0.0d0 + + else + b = (g_rr(i,ks)*g_zz(i,ks+1) + & -g_rr(i,ks+1)*g_zz(i,ks))/zdif + m = rdif/zdif + g_sqm(i,ks) = m*m + g_bom(i,ks) = b/m + endif + + endif + 61 continue + 60 continue + + CALL zonevols + + return + end Added: test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/genxsec.f URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/genxsec.f?rev=59793&view=auto ============================================================================== --- test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/genxsec.f (added) +++ test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/genxsec.f Fri Nov 21 00:17:30 2008 @@ -0,0 +1,93 @@ + + subroutine genxsec +c---------------------------------------------------------------------- +c Setup the opacity data by group (13) and region (nreg). +c ixopec .eq. 0 : use library opacities from subroutine interp +c ixopec .eq. 1 : all opacities = opec (input opacity) +c ixopec .eq. 2 : use opacities from data statement (sigdat), +c which means that formatted library on unit 4 +c or binary library on unit 15 are not needed for +c this particular case (see data sigdat) + +c igroup = 0 : normal 12 group opacity tables used +c igroup = 1 - 12 : opacity from that group is used +c igroup = 13 : opacity from group 13 is used (rosseland mean) + +c CALL subroutine interp for each material (nreg) +c---------------------------------------------------------------------- + include 'params.inc' + include 'geomz.inc' + include 'globals.inc' + include 'mpif.h' + + INTEGER MPIid, ierr + +c common /xsecdat/ sigdat(2,negp1) + REAL *8 sigdat(2,negp1) + + data sigdat/ .1395449d+06,.8093366d+06,.2022023d+05, + | .1344934d+06,.4188673d+04,.4467951d+05,.1033437d+04, + | .3250243d+05,.4297604d+03,.1237669d+05,.2235549d+03, + | .5984154d+04,.1270899d+03,.3111531d+04,.7992034d+02, + | .1722049d+04,.4425178d+02,.9100233d+03,.1456625d+02, + | .3776509d+03,.7138723d+00,.7534896d+02,.4231184d-01, + | .1032693d+01,.7666376d+01,.6094672d+04/ + + + CALL MPI_COMM_RANK( MPI_COMM_WORLD, MPIid, ierr ) + + xthom = 0.0d0 +c*** ithom non-zero implies that thomson scattering is used + if (ithom .ne. 0) xthom = 1.0d0 + + do 75 i = 1,nreg + if (ixopec .eq. 0) then +c--------------------ixopec = 0 means opacity library is used + CALL interp (mtl(i),dns(i),tmp(i),opcv) + endif + +c-----store the thomson scattering cross section. +c - thomson cross section depends only on the material, +c - and not on the energy group + + sigth(i) = .4006*atrat(i)*dns(i)*xthom + + do 69 ig = 1,13 + if( igroup.ne.0 .and. ixopec.eq.0) opcv(ig) = opcv(igroup) + +c-----store total cross section without thomson. +c - first index in cross section is the material id, +c - the second is the energy group + + if (ixopec .eq. 1) then + sigtot(i,ig) = opec + else if (ixopec .eq. 2) then + sigtot(i,ig) = sigdat(i,ig) + else + sigtot(i,ig) = dns(i) * opcv(ig) + endif + + sig (i,ig) = sigtot(i,ig) + sigth(i) + scrat(i,ig) = sigth(i) / sig(i,ig) + 69 continue + 75 continue + + + if (icross .ne. 0 .and. MPIid .eq. 0) then +c--------------------print edit of total and thomson cross sections + do 76 i=1,nreg + write (6,207) i, sigth(i) + 207 format(//' material',i3,' with thomson cross section (1/cm) ' + . ,e15.7/) + write (6,208) + 208 format(10x,'group',15x,'sigtot (1/cm)',15x,'scat ratio'/) + + write (6,209) (j, sigtot(i,j), scrat(i,j), + | j=1,13) + 209 format(12x,i2,14x,e15.7,10x,e15.7) + 76 continue + endif + + + return + end Added: test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/geomz.inc URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/geomz.inc?rev=59793&view=auto ============================================================================== --- test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/geomz.inc (added) +++ test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/geomz.inc Fri Nov 21 00:17:30 2008 @@ -0,0 +1,55 @@ +c This is 'geomz.inc' +c +c scatter, shared + dimension + . ng_incr (5), + . g_rr (nzmax,5), + . g_zz (nzmax,5), + . ng_itype(nzmax,5), + . g_bom (nzmax,5), + . g_sqm (nzmax,5), + . g_ximp (nzmax), + . ng_mid (nzmax), + . g_volcl(nzmax), + . g_ximpl(nrzmax) + + dimension + . incr (5), + . rr (nzmax,5), + . zz (nzmax,5), + . itype(nzmax,5), + . bom(nzmax,5), + . sqm(nzmax,5), + . ximp (nzmax), + . mid (nzmax), + . volcl(nzmax), + . ximpl(nrzmax) + +c common, shared /geomz/ naxl,axl,nradl,radl,nzones + common /geomz/ axl,naxl,nradl,radl,nzones + + +c common, private/pgeomz/ + common /pgeomz/ + . rr , + . g_rr , + . zz , + . g_zz , + . bom , + . g_bom, + . sqm , + . g_sqm, + . ximp , + . g_ximp, + . mid , + . volcl, + . g_volcl, + . ximpl, + . g_ximpl, + . itype, + . ng_itype, + . ng_mid, + . incr, + . ng_incr + + Added: test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/globals.inc URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/globals.inc?rev=59793&view=auto ============================================================================== --- test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/globals.inc (added) +++ test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/globals.inc Fri Nov 21 00:17:30 2008 @@ -0,0 +1,58 @@ +c This is 'globals.inc' +c +c scatter, shared + dimension + . mtl (nmrmax), + . dns (nmrmax), + . tmp (nmrmax), + . atrat(nmrmax), + . sig (nmrmax,negp1), + . scrat (nmrmax,negp1), + . sigtot(nmrmax,negp1), + . sigth (nmrmax), + . opcv ( negp1) + +c common, shared /material/ nreg + common /material/ nreg + +c common, private /pmaterial/ + common /pmaterial/ + . mtl , + . dns , + . tmp , + . atrat +c common, shared /xsec/ opec + common /xsec/ opec + +c common, private /pxsec/ + common /pxsec/ + . sig , + . scrat , + . sigtot, + . sigth , + . opcv + +c common, shared /controls/ igroup,ixopec,isorst,irr,ithom,icross, + common /controls/ igroup,ixopec,isorst,irr,ithom,icross, + . dtol,tcen,xmult,ilib,illib,title(20) + +c common, shared /newcom/ bwgt !Formerly 1st item in /samples/. + common /newcom/ bwgt !Formerly 1st item in /samples/. + + +c common /samples/ nescgp(negrps), enesc(negrps), wcut, wmin, wmax, +c . wlost, wesc, wrr, wabs, wcen, epgain, etot, +c . npart, nphtot, nploss, +c . nlost, nesc, nrr, nabs, ncen, +c . nscat, nsplt, ntrac + + +c +c O nothing +c 1 summary only +c 2 full output +c + integer print_flag + common /output_flags/ + . print_flag + Added: test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/input.dat URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/input.dat?rev=59793&view=auto ============================================================================== --- test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/input.dat (added) +++ test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/input.dat Fri Nov 21 00:17:30 2008 @@ -0,0 +1,14 @@ + 16 +BENCHMARK CASE NO THOMS, NO RR/SPLIT: 49X40, BWGT=3.12e+14 + 1 0 + 4000 0 0 0 0 0 0 + 49 40 2 + 1.00e-10 7.50e-01 1.00e-12 1.05e+00 + 1.80e+02 1.00e-03 5.00e-01 3.12e+12 + 1 980 + 981 1960 + 3 4.000e-01 1.000e+03 2.000e+04 + 2 5.000e-01 1.000e+02 1.000e+03 + 0 1 + + Added: test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/interp.f URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/interp.f?rev=59793&view=auto ============================================================================== --- test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/interp.f (added) +++ test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/interp.f Fri Nov 21 00:17:30 2008 @@ -0,0 +1,52 @@ + + subroutine interp (matl,dnt,temp,opacity) +c*********************************************************************** +c calculates material opacities as a function of temperature and +c density by interpolating in the llnl library. +c arguments: +c matl: material number +c temp: temperature (units?), +c dnt : density (units?) +c returns: 13 group opacity vector into array opacity. +c*********************************************************************** + implicit double precision (a-h,o-z) + + common /opactab/ x(14,32,13,4), t(32,2), d(14) + dimension opacity(13) +c scatter, shared opacity + + + ityp = 1 + if (matl .eq. 2 .or. matl .eq. 4) ityp = 2 + +c--------------------find bounding temperatures + do 20 it = 1,32 + if (temp .lt. t(it,ityp)) goto 30 + 20 continue + 30 tmax = t(it,ityp) + it1 = it-1 + tmin = t(it1,ityp) + trat = (temp - tmin)/(tmax - tmin) + +c--------------------find bounding densities + do 40 id = 1,14 +c if (dnt .lt. d(id)) goto 50 Replaced with following due to +c addressing problems + if (dnt .le. d(id)) goto 50 + 40 continue + 50 dmax = d(id) + id1 = id-1 + dmin = d(id1) + drat = (dnt - dmin)/(dmax - dmin) + +c--------------------interpolate + do 60 ie = 1,13 + xt = x(id1,it,ie,matl) + (x(id,it,ie,matl)-x(id1,it,ie,matl)) + | * drat + xt1 = x(id1,it1,ie,matl) + | + (x(id,it1,ie,matl)-x(id1,it1,ie,matl))*drat + opacity (ie) = exp(xt1 + (xt-xt1)*trat) + 60 continue + + return + end Added: test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/iranfeven.f URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/iranfeven.f?rev=59793&view=auto ============================================================================== --- test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/iranfeven.f (added) +++ test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/iranfeven.f Fri Nov 21 00:17:30 2008 @@ -0,0 +1,28 @@ +c ranfatok + +c============================================================================== + + function iranfeven( N ) + +c------------------------------------------------------------------------------ +c +c This function checks the parity of the argument integer. +c +c It returns one if the argument is even and zero otherwise. +c +c------------------------------------------------------------------------------ + + include 'pranf.inc' + + integer N + +c------------------------------------------------------------------------------ + + if( mod( N, 2 ) .eq. 0 ) then + iranfeven = 1 + else + iranfeven = 0 + endif + + return + end Added: test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/iranfodd.f URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/iranfodd.f?rev=59793&view=auto ============================================================================== --- test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/iranfodd.f (added) +++ test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/iranfodd.f Fri Nov 21 00:17:30 2008 @@ -0,0 +1,29 @@ +c end ranfmodmult + +c============================================================================== + + function iranfodd( N ) + +c------------------------------------------------------------------------------ +c +c This function checks the parity of the argument integer. +c +c It returns one if the argument is odd and zero otherwise. +c +c------------------------------------------------------------------------------ + + include 'pranf.inc' + + integer N + +c------------------------------------------------------------------------------ + + if( mod( N, 2 ) .eq. 1 ) then + iranfeven = 0 + else + iranfeven = 1 + endif + + iranfodd = 1 - iranfeven + return + end Added: test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/mpi_stubs.f URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/mpi_stubs.f?rev=59793&view=auto ============================================================================== --- test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/mpi_stubs.f (added) +++ test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/mpi_stubs.f Fri Nov 21 00:17:30 2008 @@ -0,0 +1,2269 @@ + subroutine mpi_abort ( comm, errorcode, ierror ) + +c*********************************************************************72 +c +cc MPI_ABORT shuts down the processes in a given communicator. +c +c Modified: +c +c 08 February 2007 +c +c Author: +c +c John Burkardt +c +c Reference: +c +c William Gropp, Ewing Lusk, Anthony Skjellum, +c Using MPI: Portable Parallel Programming with the +c Message-Passing Interface, +c Second Edition, +c MIT Press, 1999, +c ISBN: 0262571323. +c +c Parameters: +c +c Input, integer COMM, the MPI communicator. +c +c Input, integer ERRORCODE, the error code to be returned. +c +c Output, integer IERROR, an error code. +c + implicit none + + integer comm + integer errorcode + integer ierror + integer MPI_FAILURE + parameter ( MPI_FAILURE = 1 ) + integer MPI_SUCCESS + parameter ( MPI_SUCCESS = 0 ) + + ierror = MPI_SUCCESS + + write ( *, '(a)' ) ' ' + write ( *, '(a)' ) 'MPI_ABORT:' + write ( *, '(a,i12)' ) + & ' Shut down with error code = ', errorcode + + stop + end + subroutine mpi_allgather ( data1, nsend, sendtype, data2, + & nrecv, recvtype, comm, ierror ) + +c*********************************************************************72 +c +cc MPI_ALLGATHER gathers data from all the processes in a communicator. +c +c Discussion: +c +c This single processor version will copy values from DATA1 to DATA2. +c +c The data to be transferred can be integer, real, or double precision. +c In this routine, it is declared and documented as INTEGER type, +c but using the other types should generally not cause a problem. +c +c Modified: +c +c 05 February 2007 +c +c Author: +c +c John Burkardt +c +c Reference: +c +c William Gropp, Ewing Lusk, Anthony Skjellum, +c Using MPI: Portable Parallel Programming with the +c Message-Passing Interface, +c Second Edition, +c MIT Press, 1999, +c ISBN: 0262571323. +c +c Parameters: +c +c Input, integer DATA1(NSEND), the data to be sent. +c +c Input, integer NSEND, the number of data items to be sent. +c +c Input, integer SENDTYPE, the MPI datatype of the data being sent. +c +c Output, integer DATA2(NSEND*NUM_PROCS), the gathered data +c that is received. +c +c Input, integer NRECV, the number of data items to be received +c from each process. +c +c Input, integer RECVTYPE, the MPI datatype of the data being received. +c +c Input, integer COMM, the MPI communicator. +c +c Output, integer IERROR, is nonzero if an error occurred. +c + implicit none + + include "mpi_stubs_f77.h" + + integer nsend + + integer comm + integer data1(nsend) + integer data2(nsend) + integer ierror + integer nrecv + integer recvtype + integer sendtype + + ierror = MPI_SUCCESS + + if ( sendtype .eq. mpi_double_precision ) then + call mpi_copy_double_precision ( data1, data2, nsend, ierror ) + else if ( sendtype .eq. mpi_integer ) then + call mpi_copy_integer ( data1, data2, nsend, ierror ) + else if ( sendtype .eq. mpi_real ) then + call mpi_copy_real ( data1, data2, nsend, ierror ) + else + ierror = MPI_FAILURE + end if + + return + end + subroutine mpi_allgatherv ( data1, nsend, sendtype, + & data2, nrecv, ndispls, recvtype, comm, ierror ) + +c*********************************************************************72 +c +cc MPI_ALLGATHERV gathers data from all the processes in a communicator. +c +c Discussion: +c +c This single processor version will copy values from DATA1 to DATA2. +c +c The data to be transferred can be integer, real, or double precision. +c In this routine, it is declared and documented as INTEGER type, +c but using the other types should generally not cause a problem. +c +c Modified: +c +c 05 February 2007 +c +c Author: +c +c John Burkardt +c +c Reference: +c +c William Gropp, Ewing Lusk, Anthony Skjellum, +c Using MPI: Portable Parallel Programming with the +c Message-Passing Interface, +c Second Edition, +c MIT Press, 1999, +c ISBN: 0262571323. +c +c Parameters: +c +c Input, integer COMM, the MPI communicator. +c +c Output, integer IERROR, is nonzero if an error occurred. +c + implicit none + + include "mpi_stubs_f77.h" + + integer nsend + + integer comm + integer data1(nsend) + integer data2(nsend) + integer ierror + integer ndispls + integer nrecv + integer recvtype + integer sendtype + + ierror = MPI_SUCCESS + + if ( sendtype .eq. mpi_double_precision ) then + call mpi_copy_double_precision ( data1, data2, nsend, ierror ) + else if ( sendtype .eq. mpi_integer ) then + call mpi_copy_integer ( data1, data2, nsend, ierror ) + else if ( sendtype .eq. mpi_real ) then + call mpi_copy_real ( data1, data2, nsend, ierror ) + else + ierror = MPI_FAILURE + end if + + return + end + subroutine mpi_allreduce ( data1, data2, n, datatype, + & operation, comm, ierror ) + +c*********************************************************************72 +c +cc MPI_ALLREDUCE carries out a reduction operation. +c +c Discussion: +c +c The reduction operations are MAXIMUM, MINIMUM, PRODUCT and SUM. +c +c The data to be transferred can be integer, real, or double precision. +c In this routine, it is declared and documented as INTEGER type, +c but using the other types should generally not cause a problem. +c +c Modified: +c +c 07 February 2007 +c +c Author: +c +c John Burkardt +c +c Reference: +c +c William Gropp, Ewing Lusk, Anthony Skjellum, +c Using MPI: Portable Parallel Programming with the +c Message-Passing Interface, +c Second Edition, +c MIT Press, 1999, +c ISBN: 0262571323. +c +c Parameters: +c +c Input, DATATYPE DATA1(N), the data to be processed. +c +c Output, DATATYPE DATA2, the value of the reduction operation. +c +c Input, integer N, the number of items in DATA1. +c +c Input, integer DATATYPE, indicates the datatype of DATA1 and DATA2. +c +c Input, integer OPERATION, should have the value of one of the symbolic +c constants MPI_MAX, MPI_MIN, MPI_PRODUCT or MPI_SUM. +c +c Input, integer COMM, the MPI communicator. +c +c Output, integer IERROR, is nonzero if an error occurred. +c + implicit none + + include "mpi_stubs_f77.h" + + integer n + + integer comm + integer data1(n) + integer data2(n) + integer datatype + integer ierror + integer operation + + ierror = MPI_SUCCESS + + if ( datatype .eq. mpi_double_precision ) then + + call mpi_reduce_double_precision ( + & data1, data2, n, operation, ierror ) + + else if ( datatype .eq. mpi_integer ) then + + call mpi_reduce_integer ( + & data1, data2, n, operation, ierror ) + + else if ( datatype .eq. mpi_real ) then + + call mpi_reduce_real ( + & data1, data2, n, operation, ierror ) + + else + + ierror = MPI_FAILURE + + end if + + return + end + subroutine mpi_barrier ( comm, ierror ) + +c*********************************************************************72 +c +cc MPI_BARRIER forces processes within a communicator to wait together. +c +c Modified: +c +c 05 February 2007 +c +c Author: +c +c John Burkardt +c +c Reference: +c +c William Gropp, Ewing Lusk, Anthony Skjellum, +c Using MPI: Portable Parallel Programming with the +c Message-Passing Interface, +c Second Edition, +c MIT Press, 1999, +c ISBN: 0262571323. +c +c Parameters: +c +c Input, integer COMM, the MPI communicator. +c +c Output, integer IERROR, is nonzero if an error occurred. +c + implicit none + + integer comm + integer ierror + integer MPI_FAILURE + parameter ( MPI_FAILURE = 1 ) + integer MPI_SUCCESS + parameter ( MPI_SUCCESS = 0 ) + + ierror = MPI_FAILURE + + return + end + subroutine mpi_bcast ( data, n, datatype, node, comm, ierror ) + +c*********************************************************************72 +c +cc MPI_BCAST broadcasts data from one process to all others. +c +c Discussion: +c +c The data to be transferred can be integer, real, or double precision. +c In this routine, it is declared and documented as INTEGER type, +c but using the other types should generally not cause a problem. +c +c Modified: +c +c 06 February 2007 +c +c Author: +c +c John Burkardt +c +c Reference: +c +c William Gropp, Ewing Lusk, Anthony Skjellum, +c Using MPI: Portable Parallel Programming with the +c Message-Passing Interface, +c Second Edition, +c MIT Press, 1999, +c ISBN: 0262571323. +c +c Parameters: +c +c Input, datatype DATA(N), the data to be broadcast. +c +c Input, integer N, the number of items of data. +c +c Input, integer DATATYPE, the MPI code for the datatype of the data. +c +c Input, integer NODE, the rank of the sending process within the +c given communicator. +c +c Input, integer COMM, the MPI communicator. +c +c Output, integer IERROR, is nonzero if an error occurred. +c + implicit none + + integer n + + integer comm + integer data(n) + integer datatype + integer ierror + integer MPI_FAILURE + parameter ( MPI_FAILURE = 1 ) + integer MPI_SUCCESS + parameter ( MPI_SUCCESS = 0 ) + integer node + + ierror = MPI_SUCCESS + + return + end + subroutine mpi_bsend ( data, n, datatype, iproc, itag, + & comm, ierror ) + +c*********************************************************************72 +c +cc MPI_BSEND sends data from one process to another, using buffering. +c +c Discussion: +c +c Warn against sending message to self, since no data copy is done. +c +c The data to be transferred can be integer, real, or double precision. +c In this routine, it is declared and documented as INTEGER type, +c but using the other types should generally not cause a problem. +c +c Modified: +c +c 06 February 2007 +c +c Author: +c +c John Burkardt +c +c Reference: +c +c William Gropp, Ewing Lusk, Anthony Skjellum, +c Using MPI: Portable Parallel Programming with the +c Message-Passing Interface, +c Second Edition, +c MIT Press, 1999, +c ISBN: 0262571323. +c +c Parameters: +c +c Input, datatype DATA(N), the data to be sent. +c +c Input, integer N, the number of data items to send. +c +c Input, integer DATAYTPE, the MPI code for the datatype. +c +c Input, integer IPROC, the rank of the process within the communicator +c that is to receive the message. +c +c Input, integer ITAG, a tag for the message. +c +c Input, integer COMM, the MPI communicator. +c +c Output, integer IERROR, is nonzero if an error occurred. +c + implicit none + + integer n + + integer comm + integer data(n) + integer datatype + integer ierror + integer iproc + integer itag + integer MPI_FAILURE + parameter ( MPI_FAILURE = 1 ) + integer MPI_SUCCESS + parameter ( MPI_SUCCESS = 0 ) + + ierror = MPI_FAILURE + + write ( *, '(a)' ) ' ' + write ( *, '(a)' ) 'MPI_BSEND - Error!' + write ( *, '(a)' ) ' Should not send message to self.' + + return + end + subroutine mpi_cart_create ( comm, ndims, dims, periods, + & reorder, comm_cart, ierror ) + +c*********************************************************************72 +c +cc MPI_CART_CREATE creates a communicator for a Cartesian topology. +c +c Modified: +c +c 05 February 2007 +c +c Author: +c +c John Burkardt +c +c Reference: +c +c William Gropp, Ewing Lusk, Anthony Skjellum, +c Using MPI: Portable Parallel Programming with the +c Message-Passing Interface, +c Second Edition, +c MIT Press, 1999, +c ISBN: 0262571323. +c +c Parameters: +c +c Input, integer COMM, the MPI communicator. +c +c Output, integer COMM_CART, the new MPI communicator. +c +c Output, integer IERROR, is nonzero if an error occurred. +c + implicit none + + integer ndims + + integer comm + integer comm_cart + integer dims(*) + integer ierror + integer MPI_FAILURE + parameter ( MPI_FAILURE = 1 ) + integer MPI_SUCCESS + parameter ( MPI_SUCCESS = 0 ) + logical periods(*) + logical reorder + + ierror = MPI_SUCCESS + + return + end + subroutine mpi_cart_get ( comm, ndims, dims, periods, + & coords, ierror ) + +c*********************************************************************72 +c +cc MPI_CART_GET returns the "Cartesian coordinates" of the calling process. +c +c Discussion: +c +c Set all coordinates to 0. +c +c Modified: +c +c 05 February 2007 +c +c Author: +c +c John Burkardt +c +c Reference: +c +c William Gropp, Ewing Lusk, Anthony Skjellum, +c Using MPI: Portable Parallel Programming with the +c Message-Passing Interface, +c Second Edition, +c MIT Press, 1999, +c ISBN: 0262571323. +c +c Parameters: +c +c Input, integer COMM, the MPI communicator. +c +c Output, integer IERROR, is nonzero if an error occurred. +c + implicit none + + integer ndims + + integer comm + integer coords(*) + integer dims(*) + integer i + integer ierror + integer MPI_FAILURE + parameter ( MPI_FAILURE = 1 ) + integer MPI_SUCCESS + parameter ( MPI_SUCCESS = 0 ) + logical periods(*) + + ierror = MPI_SUCCESS + + do i = 1, ndims + coords(i) = 0 + end do + + return + end + subroutine mpi_cart_shift ( comm, idir, idisp, isource, + & idest, ierror ) + +c*********************************************************************72 +c +cc MPI_CART_SHIFT finds the destination and source for Cartesian shifts. +c +c Discussion: +c +c Set ISOURCE = IDEST = SELF = 0. +c +c Modified: +c +c 05 February 2007 +c +c Author: +c +c John Burkardt +c +c Reference: +c +c William Gropp, Ewing Lusk, Anthony Skjellum, +c Using MPI: Portable Parallel Programming with the +c Message-Passing Interface, +c Second Edition, +c MIT Press, 1999, +c ISBN: 0262571323. +c +c Parameters: +c +c Input, integer COMM, the MPI communicator. +c +c Output, integer IERROR, is nonzero if an error occurred. +c + implicit none + + integer comm + integer idest + integer idir + integer idisp + integer ierror + integer isource + integer MPI_FAILURE + parameter ( MPI_FAILURE = 1 ) + integer MPI_SUCCESS + parameter ( MPI_SUCCESS = 0 ) + + ierror = MPI_SUCCESS + isource = 0 + idest = 0 + + return + end + subroutine mpi_comm_dup ( comm, comm_out, ierror ) + +c*********************************************************************72 +c +cc MPI_COMM_DUP duplicates a communicator. +c +c Modified: +c +c 05 February 2007 +c +c Author: +c +c John Burkardt +c +c Reference: +c +c William Gropp, Ewing Lusk, Anthony Skjellum, +c Using MPI: Portable Parallel Programming with the +c Message-Passing Interface, +c Second Edition, +c MIT Press, 1999, +c ISBN: 0262571323. +c +c Parameters: +c +c Input, integer COMM, the MPI communicator. +c +c Output, integer COMM_OUT, the new MPI communicator. +c +c Output, integer IERROR, is nonzero if an error occurred. +c + implicit none + + integer comm + integer comm_out + integer ierror + integer MPI_FAILURE + parameter ( MPI_FAILURE = 1 ) + integer MPI_SUCCESS + parameter ( MPI_SUCCESS = 0 ) + + ierror = MPI_SUCCESS + comm_out = comm + + return + end + subroutine mpi_comm_free ( comm, ierror ) + +c*********************************************************************72 +c +cc MPI_COMM_FREE "frees" a communicator. +c +c Modified: +c +c 05 February 2007 +c +c Author: +c +c John Burkardt +c +c Reference: +c +c William Gropp, Ewing Lusk, Anthony Skjellum, +c Using MPI: Portable Parallel Programming with the +c Message-Passing Interface, +c Second Edition, +c MIT Press, 1999, +c ISBN: 0262571323. +c +c Parameters: +c +c Input, integer COMM, the MPI communicator. +c +c Output, integer IERROR, is nonzero if an error occurred. +c + implicit none + + integer comm + integer ierror + integer MPI_FAILURE + parameter ( MPI_FAILURE = 1 ) + integer MPI_SUCCESS + parameter ( MPI_SUCCESS = 0 ) + + ierror = MPI_SUCCESS + + return + end + subroutine mpi_comm_rank ( comm, me, ierror ) + +c*********************************************************************72 +c +cc MPI_COMM_RANK reports the rank of the calling process. +c +c Modified: +c +c 05 February 2007 +c +c Author: +c +c John Burkardt +c +c Reference: +c +c William Gropp, Ewing Lusk, Anthony Skjellum, +c Using MPI: Portable Parallel Programming with the +c Message-Passing Interface, +c Second Edition, +c MIT Press, 1999, +c ISBN: 0262571323. +c +c Parameters: +c +c Input, integer COMM, the MPI communicator. +c +c Output, integer IERROR, is nonzero if an error occurred. +c + implicit none + + integer comm + integer ierror + integer me + integer MPI_FAILURE + parameter ( MPI_FAILURE = 1 ) + integer MPI_SUCCESS + parameter ( MPI_SUCCESS = 0 ) + + ierror = MPI_SUCCESS + me = 0 + + return + end + subroutine mpi_comm_size ( comm, nprocs, ierror ) + +c*********************************************************************72 +c +cc MPI_COMM_SIZE reports the number of processes in a communicator. +c +c Discussion: +c +c The routine simply returns NPROCS = 1. +c +c Modified: +c +c 05 February 2007 +c +c Author: +c +c John Burkardt +c +c Reference: +c +c William Gropp, Ewing Lusk, Anthony Skjellum, +c Using MPI: Portable Parallel Programming with the +c Message-Passing Interface, +c Second Edition, +c MIT Press, 1999, +c ISBN: 0262571323. +c +c Parameters: +c +c Input, integer COMM, the MPI communicator. +c +c Output, integer IERROR, is nonzero if an error occurred. +c + implicit none + + integer comm + integer ierror + integer MPI_FAILURE + parameter ( MPI_FAILURE = 1 ) + integer MPI_SUCCESS + parameter ( MPI_SUCCESS = 0 ) + integer nprocs + + ierror = MPI_SUCCESS + nprocs = 1 + + return + end + subroutine mpi_comm_split ( comm, icolor, ikey, comm_new, + & ierror ) + +c*********************************************************************72 +c +cc MPI_COMM_SPLIT splits up a communicator based on a key. +c +c Modified: +c +c 05 February 2007 +c +c Author: +c +c John Burkardt +c +c Reference: +c +c William Gropp, Ewing Lusk, Anthony Skjellum, +c Using MPI: Portable Parallel Programming with the +c Message-Passing Interface, +c Second Edition, +c MIT Press, 1999, +c ISBN: 0262571323. +c +c Parameters: +c +c Input, integer COMM, the MPI communicator. +c +c Input, integer COMM_NEW, the new MPI communicator. +c +c Output, integer IERROR, is nonzero if an error occurred. +c + implicit none + + integer comm + integer comm_new + integer icolor + integer ierror + integer ikey + integer MPI_FAILURE + parameter ( MPI_FAILURE = 1 ) + integer MPI_SUCCESS + parameter ( MPI_SUCCESS = 0 ) + + ierror = MPI_SUCCESS + + return + end + subroutine mpi_copy_double_precision ( data1, data2, n, ierror ) + +c*********************************************************************72 +c +cc MPI_COPY_DOUBLE copies a double precision vector. +c +c Discussion: +c +c This routine is not part of the MPI standard. However, it is +c needed by other routines which do emulate standard MPI routines. +c +c Modified: +c +c 05 February 2007 +c +c Author: +c +c John Burkardt +c +c Reference: +c +c William Gropp, Ewing Lusk, Anthony Skjellum, +c Using MPI: Portable Parallel Programming with the +c Message-Passing Interface, +c Second Edition, +c MIT Press, 1999, +c ISBN: 0262571323. +c +c Parameters: +c +c Input, double precision DATA1(N), the data to be copied. +c +c Output, double precision DATA2(N), the copied data. +c +c Input, integer N, the number of items of data. +c +c Output, integer IERROR, is nonzero if an error occurred. +c + implicit none + + integer n + + double precision data1(n) + double precision data2(n) + integer i + integer ierror + integer MPI_FAILURE + parameter ( MPI_FAILURE = 1 ) + integer MPI_SUCCESS + parameter ( MPI_SUCCESS = 0 ) + + ierror = MPI_SUCCESS + + do i = 1, n + data2(i) = data1(i) + end do + + return + end + subroutine mpi_copy_integer ( data1, data2, n, ierror ) + +c*********************************************************************72 +c +cc MPI_COPY_INTEGER copies an integer vector. +c +c Discussion: +c +c This routine is not part of the MPI standard. However, it is +c needed by other routines which do emulate standard MPI routines. +c +c Modified: +c +c 05 February 2007 +c +c Author: +c +c John Burkardt +c +c Reference: +c +c William Gropp, Ewing Lusk, Anthony Skjellum, +c Using MPI: Portable Parallel Programming with the +c Message-Passing Interface, +c Second Edition, +c MIT Press, 1999, +c ISBN: 0262571323. +c +c Parameters: +c +c Input, integer DATA1(N), the data to be copied. +c +c Output, integer DATA2(N), the copied data. +c +c Input, integer N, the number of items of data. +c +c Output, integer IERROR, is nonzero if an error occurred. +c + implicit none + + integer n + + integer data1(n) + integer data2(n) + integer i + integer ierror + integer MPI_FAILURE + parameter ( MPI_FAILURE = 1 ) + integer MPI_SUCCESS + parameter ( MPI_SUCCESS = 0 ) + + ierror = MPI_SUCCESS + + do i = 1, n + data2(i) = data1(i) + end do + + return + end + subroutine mpi_copy_real ( data1, data2, n, ierror ) + +c*********************************************************************72 +c +cc MPI_COPY_REAL copies a real vector. +c +c Discussion: +c +c This routine is not part of the MPI standard. However, it is +c needed by other routines which do emulate standard MPI routines. +c +c Modified: +c +c 05 February 2007 +c +c Author: +c +c John Burkardt +c +c Reference: +c +c William Gropp, Ewing Lusk, Anthony Skjellum, +c Using MPI: Portable Parallel Programming with the +c Message-Passing Interface, +c Second Edition, +c MIT Press, 1999, +c ISBN: 0262571323. +c +c Parameters: +c +c Input, real DATA1(N), the data to be copied. +c +c Output, real DATA2(N), the copied data. +c +c Input, integer N, the number of items of data. +c +c Output, integer IERROR, is nonzero if an error occurred. +c + implicit none + + integer n + + real data1(n) + real data2(n) + integer i + integer ierror + integer MPI_FAILURE + parameter ( MPI_FAILURE = 1 ) + integer MPI_SUCCESS + parameter ( MPI_SUCCESS = 0 ) + + ierror = MPI_SUCCESS + + do i = 1, n + data2(i) = data1(i) + end do + + return + end + subroutine mpi_finalize ( ierror ) + +c*********************************************************************72 +c +cc MPI_FINALIZE shuts down the MPI library. +c +c Modified: +c +c 05 February 2007 +c +c Author: +c +c John Burkardt +c +c Reference: +c +c William Gropp, Ewing Lusk, Anthony Skjellum, +c Using MPI: Portable Parallel Programming with the +c Message-Passing Interface, +c Second Edition, +c MIT Press, 1999, +c ISBN: 0262571323. +c +c Parameters: +c +c Output, integer IERROR, is nonzero if an error occurred. +c + implicit none + + integer ierror + integer MPI_FAILURE + parameter ( MPI_FAILURE = 1 ) + integer MPI_SUCCESS + parameter ( MPI_SUCCESS = 0 ) + + ierror = MPI_SUCCESS + + return + end + subroutine mpi_get_count ( istatus, datatype, icount, ierror ) + +c*********************************************************************72 +c +cc MPI_GET_COUNT reports the actual number of items transmitted. +c +c Discussion: +c +c Warn against querying message from self, since no data copy is done. +c +c Modified: +c +c 05 February 2007 +c +c Author: +c +c John Burkardt +c +c Reference: +c +c William Gropp, Ewing Lusk, Anthony Skjellum, +c Using MPI: Portable Parallel Programming with the +c Message-Passing Interface, +c Second Edition, +c MIT Press, 1999, +c ISBN: 0262571323. +c +c Parameters: +c +c Output, integer IERROR, is nonzero if an error occurred. +c + implicit none + + integer datatype + integer icount + integer ierror + integer istatus + integer MPI_FAILURE + parameter ( MPI_FAILURE = 1 ) + integer MPI_SUCCESS + parameter ( MPI_SUCCESS = 0 ) + + ierror = MPI_FAILURE + + write ( *, '(a)' ) ' ' + write ( *, '(a)' ) 'MPI_GET_COUNT - Error!' + write ( *, '(a)' ) ' Should not query message from self.' + + return + end + subroutine mpi_init ( ierror ) + +c*********************************************************************72 +c +cc MPI_INIT initializes the MPI library. +c +c Modified: +c +c 05 February 2007 +c +c Author: +c +c John Burkardt +c +c Reference: +c +c William Gropp, Ewing Lusk, Anthony Skjellum, +c Using MPI: Portable Parallel Programming with the +c Message-Passing Interface, +c Second Edition, +c MIT Press, 1999, +c ISBN: 0262571323. +c +c Parameters: +c +c Output, integer IERROR, is nonzero if an error occurred. +c + implicit none + + integer ierror + integer MPI_FAILURE + parameter ( MPI_FAILURE = 1 ) + integer MPI_SUCCESS + parameter ( MPI_SUCCESS = 0 ) + + ierror = MPI_SUCCESS + + return + end + subroutine mpi_irecv ( data, n, datatype, iproc, itag, + & comm, irequest, ierror ) + +c*********************************************************************72 +c +cc MPI_IRECV receives data from another process. +c +c Discussion: +c +c Warn against receiving message from self, since no data copy is done. +c +c The data to be transferred can be integer, real, or double precision. +c In this routine, it is declared and documented as INTEGER type, +c but using the other types should generally not cause a problem. +c +c Modified: +c +c 05 February 2007 +c +c Author: +c +c John Burkardt +c +c Reference: +c +c William Gropp, Ewing Lusk, Anthony Skjellum, +c Using MPI: Portable Parallel Programming with the +c Message-Passing Interface, +c Second Edition, +c MIT Press, 1999, +c ISBN: 0262571323. +c +c Parameters: +c +c Input, integer COMM, the MPI communicator. +c +c Output, integer IERROR, is nonzero if an error occurred. +c + implicit none + + integer n + + integer comm + integer data(n) + integer datatype + integer ierror + integer iproc + integer irequest + integer itag + integer MPI_FAILURE + parameter ( MPI_FAILURE = 1 ) + integer MPI_SUCCESS + parameter ( MPI_SUCCESS = 0 ) + + ierror = MPI_FAILURE + + write ( *, '(a)' ) ' ' + write ( *, '(a)' ) 'MPI_IRECV - Error!' + write ( *, '(a)' ) ' Should not recv message from self.' + + return + end + subroutine mpi_isend ( data, n, datatype, iproc, itag, + & comm, request, ierror ) + +c*********************************************************************72 +c +cc MPI_ISEND sends data from one process to another using nonblocking transmission. +c +c Discussion: +c +c Warn against sending message to self, since no data copy is done. +c +c The data to be transferred can be integer, real, or double precision. +c In this routine, it is declared and documented as INTEGER type, +c but using the other types should generally not cause a problem. +c +c Modified: +c +c 15 August 2008 +c +c Author: +c +c John Burkardt +c +c Reference: +c +c William Gropp, Ewing Lusk, Anthony Skjellum, +c Using MPI: Portable Parallel Programming with the +c Message-Passing Interface, +c Second Edition, +c MIT Press, 1999, +c ISBN: 0262571323. +c +c Parameters: +c +c Input, datatype DATA(N), the data to be sent. +c +c Input, integer N, the number of data items to send. +c +c Input, integer DATAYTPE, the MPI code for the datatype. +c +c Input, integer IPROC, the rank of the process within the communicator +c that is to receive the message. +c +c Input, integer ITAG, a tag for the message. +c +c Input, integer COMM, the MPI communicator. +c +c Output, integer REQUEST, a handle. To determine if the data has been received +c yet, call MPI_Test or MPI_Wait, including the value of REQUEST. +c +c Output, integer IERROR, is nonzero if an error occurred. +c + implicit none + + integer n + + integer comm + integer data(n) + integer datatype + integer ierror + integer iproc + integer itag + integer MPI_FAILURE + parameter ( MPI_FAILURE = 1 ) + integer MPI_SUCCESS + parameter ( MPI_SUCCESS = 0 ) + integer request + + request = 0 + ierror = MPI_FAILURE + + write ( *, '(a)' ) ' ' + write ( *, '(a)' ) 'MPI_ISEND - Error!' + write ( *, '(a)' ) ' Should not send message to self.' + + return + end + subroutine mpi_recv ( data, n, datatype, iproc, itag, + & comm, istatus, ierror ) + +c*********************************************************************72 +c +cc MPI_RECV receives data from another process within a communicator. +c +c Discussion: +c +c Warn against receiving message from self, since no data copy is done. +c +c The data to be transferred can be integer, real, or double precision. +c In this routine, it is declared and documented as INTEGER type, +c but using the other types should generally not cause a problem. +c +c Modified: +c +c 05 February 2007 +c +c Author: +c +c John Burkardt +c +c Reference: +c +c William Gropp, Ewing Lusk, Anthony Skjellum, +c Using MPI: Portable Parallel Programming with the +c Message-Passing Interface, +c Second Edition, +c MIT Press, 1999, +c ISBN: 0262571323. +c +c Parameters: +c +c Input, integer COMM, the MPI communicator. +c +c Output, integer IERROR, is nonzero if an error occurred. +c + implicit none + + integer n + + integer comm + integer data(n) + integer datatype + integer ierror + integer iproc + integer istatus + integer itag + integer MPI_FAILURE + parameter ( MPI_FAILURE = 1 ) + integer MPI_SUCCESS + parameter ( MPI_SUCCESS = 0 ) + + ierror = MPI_FAILURE + + write ( *, '(a)' ) ' ' + write ( *, '(a)' ) 'MPI_RECV - Error!' + write ( *, '(a)' ) ' Should not recv message from self.' + + return + end + subroutine mpi_reduce ( data1, data2, n, datatype, operation, + & receiver, comm, ierror ) + +c*********************************************************************72 +c +cc MPI_REDUCE carries out a reduction operation. +c +c Discussion: +c +c The reduction operations are sum, maximum, minimum, product. +c +c The first two arguments must not overlap or share memory in any way. +c +c The data to be transferred can be integer, real, or double precision. +c In this routine, it is declared and documented as INTEGER type, +c but using the other types should generally not cause a problem. +c +c Modified: +c +c 05 February 2007 +c +c Author: +c +c John Burkardt +c +c Reference: +c +c William Gropp, Ewing Lusk, Anthony Skjellum, +c Using MPI: Portable Parallel Programming with the +c Message-Passing Interface, +c Second Edition, +c MIT Press, 1999, +c ISBN: 0262571323. +c +c Parameters: +c +c Input, DATATYPE DATA1(N), the data to be processed. +c +c Output (to RECEIVER only), DATATYPE DATA2, the value of the +c reduction operation. +c +c Input, integer N, the number of items in DATA1. +c +c Input, integer DATATYPE, indicates the datatype of DATA1 and DATA2. +c +c Input, integer OPERATION, should have the value of one of the symbolic +c constants MPI_MAX, MPI_MIN, MPI_PRODUCT or MPI_SUM. +c +c Input, integer RECEIVER, the the process that is to receive the +c result. +c +c Input, integer COMM, the MPI communicator. +c +c Output, integer IERROR, is nonzero if an error occurred. +c + implicit none + + include "mpi_stubs_f77.h" + + integer n + + integer comm + integer data1(n) + integer data2 + integer datatype + integer ierror + integer operation + integer receiver + + ierror = MPI_SUCCESS + + if ( datatype .eq. mpi_double_precision ) then + + call mpi_reduce_double_precision ( + & data1, data2, n, operation, ierror ) + + else if ( datatype .eq. mpi_integer ) then + + call mpi_reduce_integer ( + & data1, data2, n, operation, ierror ) + + else if ( datatype .eq. mpi_real ) then + + call mpi_reduce_real ( + & data1, data2, n, operation, ierror ) + + else + + ierror = MPI_FAILURE + + end if + + return + end + subroutine mpi_reduce_double_precision ( + & data1, data2, n, operation, ierror ) + +c*********************************************************************72 +c +cc MPI_REDUCE_DOUBLE_PRECISION carries out a reduction operation on double precision values. +c +c Discussion: +c +c The reduction operations are sum, maximum, minimum, product. +c +c Modified: +c +c 05 February 2007 +c +c Author: +c +c John Burkardt +c +c Reference: +c +c William Gropp, Ewing Lusk, Anthony Skjellum, +c Using MPI: Portable Parallel Programming with the +c Message-Passing Interface, +c Second Edition, +c MIT Press, 1999, +c ISBN: 0262571323. +c +c Parameters: +c +c Input, double precision DATA1(N), the data to be processed. +c +c Output, double precision DATA2, the value of the reduction operation. +c +c Input, integer N, the number of items in DATA1. +c +c Input, integer OPERATION, should have the value of one of the symbolic +c constants MPI_MAX, MPI_MIN, MPI_PRODUCT or MPI_SUM. +c +c Output, integer IERROR, is nonzero if an error occurred. +c + implicit none + + include "mpi_stubs_f77.h" + + integer n + + double precision data1(n) + double precision data2 + integer i + integer ierror + integer operation + + + ierror = MPI_SUCCESS + + if ( operation .eq. mpi_max ) then + + data2 = data1(1) + do i = 2, n + data2 = max ( data2, data1(i) ) + end do + + else if ( operation .eq. mpi_min ) then + + data2 = data1(1) + do i = 2, n + data2 = min ( data2, data1(i) ) + end do + + else if ( operation .eq. mpi_product ) then + + data2 = data1(1) + do i = 2, n + data2 = data2 * data1(i) + end do + + else if ( operation .eq. mpi_sum ) then + + data2 = data1(1) + do i = 2, n + data2 = data2 + data1(i) + end do + + else + + ierror = MPI_FAILURE + + end if + + return + end + subroutine mpi_reduce_integer ( + & data1, data2, n, operation, ierror ) + +c*********************************************************************72 +c +cc MPI_REDUCE_INTEGER carries out a reduction operation on integers. +c +c Discussion: +c +c The reduction operations are sum, maximum, minimum, product. +c +c Modified: +c +c 05 February 2007 +c +c Author: +c +c John Burkardt +c +c Reference: +c +c William Gropp, Ewing Lusk, Anthony Skjellum, +c Using MPI: Portable Parallel Programming with the +c Message-Passing Interface, +c Second Edition, +c MIT Press, 1999, +c ISBN: 0262571323. +c +c Parameters: +c +c Input, integer DATA1(N), the data to be processed. +c +c Output, integer DATA2, the value of the reduction operation. +c +c Input, integer N, the number of items in DATA1. +c +c Input, integer OPERATION, should have the value of one of the symbolic +c constants MPI_MAX, MPI_MIN, MPI_PRODUCT or MPI_SUM. +c +c Output, integer IERROR, is nonzero if an error occurred. +c + implicit none + + include "mpi_stubs_f77.h" + + integer n + + integer data1(n) + integer data2 + integer i + integer ierror + integer operation + + ierror = MPI_SUCCESS + + if ( operation .eq. mpi_max ) then + + data2 = data1(1) + do i = 2, n + data2 = max ( data2, data1(i) ) + end do + + else if ( operation .eq. mpi_min ) then + + data2 = data1(1) + do i = 2, n + data2 = min ( data2, data1(i) ) + end do + + else if ( operation .eq. mpi_product ) then + + data2 = data1(1) + do i = 2, n + data2 = data2 * data1(i) + end do + + else if ( operation .eq. mpi_sum ) then + + data2 = data1(1) + do i = 2, n + data2 = data2 + data1(i) + end do + + else + + ierror = MPI_FAILURE + + end if + + return + end + subroutine mpi_reduce_real ( + & data1, data2, n, operation, ierror ) + +c*********************************************************************72 +c +cc MPI_REDUCE_REAL carries out a reduction operation on reals. +c +c Discussion: +c +c The reduction operations are sum, maximum, minimum, product. +c +c Modified: +c +c 05 February 2007 +c +c Author: +c +c John Burkardt +c +c Reference: +c +c William Gropp, Ewing Lusk, Anthony Skjellum, +c Using MPI: Portable Parallel Programming with the +c Message-Passing Interface, +c Second Edition, +c MIT Press, 1999, +c ISBN: 0262571323. +c +c Parameters: +c +c Input, real DATA1(N), the data to be processed. +c +c Output, real DATA2, the value of the reduction operation. +c +c Input, integer N, the number of items in DATA1. +c +c Input, integer OPERATION, should have the value of one of the symbolic +c constants MPI_MAX, MPI_MIN, MPI_PRODUCT or MPI_SUM. +c +c Output, integer IERROR, is nonzero if an error occurred. +c + implicit none + + include "mpi_stubs_f77.h" + + integer n + + real data1(n) + real data2 + integer i + integer ierror + integer operation + + ierror = MPI_SUCCESS + + if ( operation .eq. mpi_max ) then + + data2 = data1(1) + do i = 2, n + data2 = max ( data2, data1(i) ) + end do + + else if ( operation .eq. mpi_min ) then + + data2 = data1(1) + do i = 2, n + data2 = min ( data2, data1(i) ) + end do + + else if ( operation .eq. mpi_product ) then + + data2 = data1(1) + do i = 2, n + data2 = data2 * data1(i) + end do + + else if ( operation .eq. mpi_sum ) then + + data2 = data1(1) + do i = 2, n + data2 = data2 + data1(i) + end do + + else + + ierror = MPI_FAILURE + + end if + + return + end + subroutine mpi_reduce_scatter ( data1, data2, n, datatype, + & operation, comm, ierror ) + +c*********************************************************************72 +c +cc MPI_REDUCE_SCATTER collects a message of the same length from each process. +c +c Discussion: +c +c Copy values from DATA1 to DATA2. +c +c The data to be transferred can be integer, real, or double precision. +c In this routine, it is declared and documented as INTEGER type, +c but using the other types should generally not cause a problem. +c +c Modified: +c +c 05 February 2007 +c +c Author: +c +c John Burkardt +c +c Reference: +c +c William Gropp, Ewing Lusk, Anthony Skjellum, +c Using MPI: Portable Parallel Programming with the +c Message-Passing Interface, +c Second Edition, +c MIT Press, 1999, +c ISBN: 0262571323. +c +c Parameters: +c +c Input, DATATYPE DATA1(N), the data to be processed. +c +c Output, DATATYPE DATA2, the value of the reduction operation. +c +c Input, integer N, the number of items in DATA1. +c +c Input, integer DATATYPE, indicates the datatype of DATA1 and DATA2. +c +c Input, integer OPERATION, should have the value of one of the symbolic +c constants MPI_MAX, MPI_MIN, MPI_PRODUCT or MPI_SUM. +c +c Input, integer COMM, the MPI communicator. +c +c Output, integer IERROR, is nonzero if an error occurred. +c + implicit none + + include "mpi_stubs_f77.h" + + integer n + + integer comm + integer data1(n) + integer data2(n) + integer datatype + integer ierror + integer operation + + ierror = MPI_SUCCESS + + if ( datatype .eq. mpi_double_precision ) then + call mpi_copy_double_precision ( data1, data2, n, ierror ) + else if ( datatype .eq. mpi_integer ) then + call mpi_copy_integer ( data1, data2, n, ierror ) + else if ( datatype .eq. mpi_real ) then + call mpi_copy_real ( data1, data2, n, ierror ) + else + ierror = MPI_FAILURE + end if + + return + end + subroutine mpi_rsend ( data, n, datatype, iproc, itag, + & comm, ierror ) + +c*********************************************************************72 +c +cc MPI_RSEND "ready sends" data from one process to another. +c +c Discussion: +c +c Warn against sending message to self, since no data copy is done. +c +c The data to be transferred can be integer, real, or double precision. +c In this routine, it is declared and documented as INTEGER type, +c but using the other types should generally not cause a problem. +c +c Modified: +c +c 05 February 2007 +c +c Author: +c +c John Burkardt +c +c Reference: +c +c William Gropp, Ewing Lusk, Anthony Skjellum, +c Using MPI: Portable Parallel Programming with the +c Message-Passing Interface, +c Second Edition, +c MIT Press, 1999, +c ISBN: 0262571323. +c +c Parameters: +c +c Input, datatype DATA(N), the data to be sent. +c +c Input, integer N, the number of data items to send. +c +c Input, integer DATAYTPE, the MPI code for the datatype. +c +c Input, integer IPROC, the rank of the process within the communicator +c that is to receive the message. +c +c Input, integer ITAG, a tag for the message. +c +c Input, integer COMM, the MPI communicator. +c +c Output, integer IERROR, is nonzero if an error occurred. +c + implicit none + + integer n + + integer comm + integer data(n) + integer datatype + integer ierror + integer iproc + integer itag + integer MPI_FAILURE + parameter ( MPI_FAILURE = 1 ) + integer MPI_SUCCESS + parameter ( MPI_SUCCESS = 0 ) + + ierror = MPI_FAILURE + + write ( *, '(a)' ) ' ' + write ( *, '(a)' ) 'MPI_RSEND - Error!' + write ( *, '(a)' ) ' Should not send message to self.' + + return + end + subroutine mpi_send ( data, n, datatype, iproc, itag, + & comm, ierror ) + +c*********************************************************************72 +c +cc MPI_SEND sends data from one process to another. +c +c Discussion: +c +c Warn against sending message to self, since no data copy is done. +c +c The data to be transferred can be integer, real, or double precision. +c In this routine, it is declared and documented as INTEGER type, +c but using the other types should generally not cause a problem. +c +c Modified: +c +c 05 February 2007 +c +c Author: +c +c John Burkardt +c +c Reference: +c +c William Gropp, Ewing Lusk, Anthony Skjellum, +c Using MPI: Portable Parallel Programming with the +c Message-Passing Interface, +c Second Edition, +c MIT Press, 1999, +c ISBN: 0262571323. +c +c Parameters: +c +c Input, datatype DATA(N), the data to be sent. +c +c Input, integer N, the number of data items to send. +c +c Input, integer DATAYTPE, the MPI code for the datatype. +c +c Input, integer IPROC, the rank of the process within the communicator +c that is to receive the message. +c +c Input, integer ITAG, a tag for the message. +c +c Input, integer COMM, the MPI communicator. +c +c Output, integer IERROR, is nonzero if an error occurred. +c + implicit none + + integer n + + integer comm + integer data(n) + integer datatype + integer ierror + integer iproc + integer itag + integer MPI_FAILURE + parameter ( MPI_FAILURE = 1 ) + integer MPI_SUCCESS + parameter ( MPI_SUCCESS = 0 ) + + ierror = MPI_FAILURE + + write ( *, '(a)' ) ' ' + write ( *, '(a)' ) 'MPI_SEND - Error!' + write ( *, '(a)' ) ' Should not send message to self.' + + return + end + subroutine mpi_wait ( irequest, istatus, ierror ) + +c*********************************************************************72 +c +cc MPI_WAIT waits for an I/O request to complete. +c +c Discussion: +c +c Warn against waiting on message from self, since no data copy is done. +c +c Modified: +c +c 04 October 2007 +c +c Author: +c +c John Burkardt +c +c Reference: +c +c William Gropp, Ewing Lusk, Anthony Skjellum, +c Using MPI: Portable Parallel Programming with the +c Message-Passing Interface, +c Second Edition, +c MIT Press, 1999, +c ISBN: 0262571323. +c +c Parameters: +c +c Output, integer IERROR, is nonzero if an error occurred. +c + implicit none + + integer ierror + integer irequest + integer istatus + integer MPI_FAILURE + parameter ( MPI_FAILURE = 1 ) + integer MPI_SUCCESS + parameter ( MPI_SUCCESS = 0 ) + + ierror = MPI_FAILURE + + write ( *, '(a)' ) ' ' + write ( *, '(a)' ) 'MPI_WAIT - Error!' + write ( *, '(a)' ) ' Should not wait on message from self.' + + return + end + subroutine mpi_waitall ( icount, irequest, istatus, ierror ) + +c*********************************************************************72 +c +cc MPI_WAITALL waits until all I/O requests have completed. +c +c Discussion: +c +c Warn against waiting on message from self, since no data copy is done. +c +c Modified: +c +c 05 February 2007 +c +c Author: +c +c John Burkardt +c +c Reference: +c +c William Gropp, Ewing Lusk, Anthony Skjellum, +c Using MPI: Portable Parallel Programming with the +c Message-Passing Interface, +c Second Edition, +c MIT Press, 1999, +c ISBN: 0262571323. +c +c Parameters: +c +c Output, integer IERROR, is nonzero if an error occurred. +c + implicit none + + integer icount + integer ierror + integer irequest + integer istatus + integer MPI_FAILURE + parameter ( MPI_FAILURE = 1 ) + integer MPI_SUCCESS + parameter ( MPI_SUCCESS = 0 ) + + ierror = MPI_FAILURE + + write ( *, '(a)' ) ' ' + write ( *, '(a)' ) 'MPI_WAITALL - Error!' + write ( *, '(a)' ) ' Should not wait on message from self.' + + return + end + subroutine mpi_waitany ( icount, array_of_requests, index, + & istatus, ierror ) + +c*********************************************************************72 +c +cc MPI_WAITANY waits until one I/O requests has completed. +c +c Discussion: +c +c Warn against waiting on message from self, since no data copy is done. +c +c Modified: +c +c 05 February 2007 +c +c Author: +c +c John Burkardt +c +c Reference: +c +c William Gropp, Ewing Lusk, Anthony Skjellum, +c Using MPI: Portable Parallel Programming with the +c Message-Passing Interface, +c Second Edition, +c MIT Press, 1999, +c ISBN: 0262571323. +c +c Parameters: +c +c Output, integer IERROR, is nonzero if an error occurred. +c + implicit none + + integer array_of_requests(*) + integer icount + integer ierror + integer index + integer istatus + integer MPI_FAILURE + parameter ( MPI_FAILURE = 1 ) + integer MPI_SUCCESS + parameter ( MPI_SUCCESS = 0 ) + + ierror = MPI_FAILURE + + write ( *, '(a)' ) ' ' + write ( *, '(a)' ) 'MPI_WAITANY - Error!' + write ( *, '(a)' ) ' Should not wait on message from self.' + + return + end + function mpi_wtick ( ) + +c*********************************************************************72 +c +cc MPI_WTICK returns the time between clock ticks. +c +c Modified: +c +c 05 February 2007 +c +c Author: +c +c John Burkardt +c +c Reference: +c +c William Gropp, Ewing Lusk, Anthony Skjellum, +c Using MPI: Portable Parallel Programming with the +c Message-Passing Interface, +c Second Edition, +c MIT Press, 1999, +c ISBN: 0262571323. +c +c Parameters: +c +c Output, double precision MPI_WTICK, the time, in seconds, between +c successive clock ticks. +c + implicit none + + double precision mpi_wtick + + mpi_wtick = 1.0D+00 + + return + end + function mpi_wtime ( ) + +c*********************************************************************72 +c +cc MPI_WTIME returns the elapsed wall clock time. +c +c Discussion: +c +c While you might be able to get a wall clock reading if you +c happen to know the peculiarities of the extra routines in your +c own FORTRAN77 compiler, there is no standard way to do this, +c and I am tired of trying to make up for this. +c +c Modified: +c +c 05 February 2007 +c +c Author: +c +c John Burkardt +c +c Reference: +c +c William Gropp, Ewing Lusk, Anthony Skjellum, +c Using MPI: Portable Parallel Programming with the +c Message-Passing Interface, +c Second Edition, +c MIT Press, 1999, +c ISBN: 0262571323. +c +c Parameters: +c +c Output, double precision MPI_WTIME, the elapsed wall clock time. +c + implicit none + + double precision fake_time + double precision mpi_wtime + + save fake_time + + data fake_time / 0.0D+00 / + + mpi_wtime = fake_time + + fake_time = fake_time + 1.0D+00 + + return + end + subroutine timestamp ( ) + +c*********************************************************************72 +c +cc TIMESTAMP prints out the current YMDHMS date as a timestamp. +c +c Discussion: +c +c This FORTRAN77 version is made available for cases where the +c FORTRAN90 version cannot be used. +c +c Modified: +c +c 12 January 2007 +c +c Author: +c +c John Burkardt +c +c Parameters: +c +c None +c + implicit none + + character * ( 8 ) ampm + integer d + character * ( 8 ) date + integer h + integer m + integer mm + character * ( 9 ) month(12) + integer n + integer s + character * ( 10 ) time + integer y + + save month + + data month / + & 'January ', 'February ', 'March ', 'April ', + & 'May ', 'June ', 'July ', 'August ', + & 'September', 'October ', 'November ', 'December ' / + + call date_and_time ( date, time ) + + read ( date, '(i4,i2,i2)' ) y, m, d + read ( time, '(i2,i2,i2,1x,i3)' ) h, n, s, mm + + if ( h .lt. 12 ) then + ampm = 'AM' + else if ( h .eq. 12 ) then + if ( n .eq. 0 .and. s .eq. 0 ) then + ampm = 'Noon' + else + ampm = 'PM' + end if + else + h = h - 12 + if ( h .lt. 12 ) then + ampm = 'PM' + else if ( h .eq. 12 ) then + if ( n .eq. 0 .and. s .eq. 0 ) then + ampm = 'Midnight' + else + ampm = 'AM' + end if + end if + end if + + write ( *, + & '(i2,1x,a,1x,i4,2x,i2,a1,i2.2,a1,i2.2,a1,i3.3,1x,a)' ) + & d, month(m), y, h, ':', n, ':', s, '.', mm, ampm + + return + end + +cccccccccccccccccc fake openmp crud + function omp_get_num_threads() + integer omp_get_num_threads + omp_get_num_threads = 1 + return + end + + function omp_get_thread_num() + integer omp_get_thread_num + omp_get_thread_num = 0 + return + end + Added: test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/mpi_stubs_f77.h URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/mpi_stubs_f77.h?rev=59793&view=auto ============================================================================== --- test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/mpi_stubs_f77.h (added) +++ test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/mpi_stubs_f77.h Fri Nov 21 00:17:30 2008 @@ -0,0 +1,58 @@ +c +c Dummy parameters for MPI F77 stubs +c + integer mpi_comm_world + parameter ( mpi_comm_world = 0 ) +c +c Return values. +c + integer mpi_failure + parameter ( mpi_failure = 1 ) + integer mpi_success + parameter ( mpi_success = 0 ) +c +c recv message status +c + integer mpi_status_size + parameter ( mpi_status_size = 3 ) + integer mpi_source + parameter ( mpi_source = 1 ) + integer mpi_tag + parameter ( mpi_tag = 2 ) + integer mpi_count + parameter ( mpi_count = 3 ) +c +c recv flags +c + integer mpi_any_source + parameter ( mpi_any_source = -1 ) + integer mpi_any_tag + parameter ( mpi_any_tag = -1 ) +c +c data types and sizes +c + integer mpi_integer + parameter ( mpi_integer = 1 ) + integer mpi_real + parameter ( mpi_real = 2 ) + integer mpi_double_precision + parameter ( mpi_double_precision = 3 ) + integer mpi_logical + parameter ( mpi_logical = 4 ) + integer mpi_character + parameter ( mpi_character = 5 ) +c +c allreduce operations +c + integer mpi_sum + parameter ( mpi_sum = 1 ) + integer mpi_max + parameter ( mpi_max = 2 ) + integer mpi_min + parameter ( mpi_min = 3 ) + integer mpi_product + parameter ( mpi_product = 4 ) +c +c timer +c + double precision mpi_wtime Added: test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/mpif.h URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/mpif.h?rev=59793&view=auto ============================================================================== --- test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/mpif.h (added) +++ test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/mpif.h Fri Nov 21 00:17:30 2008 @@ -0,0 +1,306 @@ +! -*- fortran -*- +! +! Copyright 1998-2001, University of Notre Dame. +! Authors: Jeffrey M. Squyres, Arun Rodrigues, and Brian Barrett with +! Kinis L. Meyer, M. D. McNally, and Andrew Lumsdaine +! +! This file is part of the Notre Dame LAM implementation of MPI. +! +! You should have received a copy of the License Agreement for the Notre +! Dame LAM implementation of MPI along with the software; see the file +! LICENSE. If not, contact Office of Research, University of Notre +! Dame, Notre Dame, IN 46556. +! +! Redistribution and use in source and binary forms, with or without +! modification, are permitted subject to the conditions specified in the +! LICENSE file. +! +! THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +! IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +! WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +! DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, +! INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +! (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +! SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +! HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +! STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +! IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +! POSSIBILITY OF SUCH DAMAGE. +! +! Additional copyrights may follow. +! +! +! $Id: mpif.h.in,v 1.2 2000/09/20 05:03:21 jsquyres Exp $ +! +! Function: - LAM/MPI F77 header file +! +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +! WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +! +! Do ***not*** copy this file to the directory where your Fortran +! fortran application is compiled unless it is absolutely necessary! Most +! modern Fortran compilers now support the -I command line flag, which +! tells the compiler where to find .h files (specifically, this one). For +! example: +! +! unix% mpif77 foo.f -o foo -I$LAMHOME/include +! +! will probably do the trick (assuming that you have set LAMHOME +! properly). +! +! That being said, LAM's "mpif77" wrapper compiler should +! automatically include the -I option for you. The following command +! should be equivalent to the command listed above: +! +! unix% mpif77 foo.f -o foo +! +! You should not copy this file to your local directory because it is +! possible that this file will be changed between versions of LAM/MPI. +! Indeed, this mpif.h is incompatible with the mpif.f of other +! implementations of MPI. Using this mpif.h with other implementations +! of MPI, or with other versions of LAM/MPI will result in undefined +! behavior (to include incorrect results, segmentation faults, +! unexplainable "hanging" in your application, etc.). Always use the +! -I command line option instead (or let mpif77 do it for you). +! +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +! WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +! +! LAM version +! This file is generated from configure; do not edit it manually. +! + integer LAM_MAJOR_VERSION, LAM_MINOR_VERSION + integer LAM_RELEASE_VERSION + integer LAM_ALPHA_VERSION, LAM_BETA_VERSION + parameter (LAM_MAJOR_VERSION=6) + parameter (LAM_MINOR_VERSION=5) + parameter (LAM_RELEASE_VERSION=6) + parameter (LAM_ALPHA_VERSION=0) + parameter (LAM_BETA_VERSION=0) +! +! MPI version +! + integer MPI_VERSION, MPI_SUBVERSION + + parameter (MPI_VERSION=1) + parameter (MPI_SUBVERSION=2) +! +! misc. constants +! + integer MPI_SUCCESS, MPI_ANY_SOURCE, MPI_ANY_TAG + integer MPI_PROC_NULL, MPI_MAX_PROCESSOR_NAME + integer MPI_MAX_ERROR_STRING, MPI_UNDEFINED + integer MPI_CART, MPI_GRAPH, MPI_KEYVAL_INVALID + integer MPI_STATUS_SIZE, MPI_SOURCE, MPI_TAG, MPI_ERROR + integer MPI_TAG_UB, MPI_HOST, MPI_IO, MPI_WTIME_IS_GLOBAL + integer MPI_UNIVERSE_SIZE, MPI_APPNUM, MPI_WIN_BASE + integer MPI_WIN_SIZE, MPI_WIN_DISP_UNIT, MPI_BSEND_OVERHEAD + integer MPI_MAX_INFO_KEY, MPI_MAX_INFO_VAL + integer MPI_MAX_PORT_NAME, MPI_MAX_OBJECT_NAME + integer MPI_ORDER_C, MPI_ORDER_FORTRAN + integer MPI_DISTRIBUTE_BLOCK, MPI_DISTRIBUTE_CYCLIC + integer MPI_DISTRIBUTE_NONE, MPI_DISTRIBUTE_DFLT_DARG + + parameter (MPI_SUCCESS=0) + parameter (MPI_ANY_SOURCE=-1) + parameter (MPI_ANY_TAG=-1) + parameter (MPI_PROC_NULL=-2) + parameter (MPI_MAX_PROCESSOR_NAME=255) + parameter (MPI_MAX_ERROR_STRING=255) + parameter (MPI_UNDEFINED=-32766) + parameter (MPI_CART=1) + parameter (MPI_GRAPH=2) + parameter (MPI_KEYVAL_INVALID=-1) + parameter (MPI_STATUS_SIZE=4) + parameter (MPI_SOURCE=1) + parameter (MPI_TAG=2) + parameter (MPI_ERROR=3) + parameter (MPI_TAG_UB=0) + parameter (MPI_HOST=1) + parameter (MPI_IO=2) + parameter (MPI_WTIME_IS_GLOBAL=3) + parameter (MPI_UNIVERSE_SIZE=4) + parameter (MPI_APPNUM=5) + parameter (MPI_WIN_BASE=6) + parameter (MPI_WIN_SIZE=7) + parameter (MPI_WIN_DISP_UNIT=8) + parameter (MPI_BSEND_OVERHEAD=40) + parameter (MPI_MAX_INFO_KEY=35) + parameter (MPI_MAX_INFO_VAL=255) + parameter (MPI_MAX_PORT_NAME=35) + parameter (MPI_MAX_OBJECT_NAME=63) + parameter (MPI_ORDER_C=0) + parameter (MPI_ORDER_FORTRAN=1) + parameter (MPI_DISTRIBUTE_BLOCK=0) + parameter (MPI_DISTRIBUTE_CYCLIC=1) + parameter (MPI_DISTRIBUTE_NONE=2) + parameter (MPI_DISTRIBUTE_DFLT_DARG=-1) +! +! global variables +! + double complex MPI_BOTTOM, MPI_ARGV_NULL + double complex MPI_ARGVS_NULL, MPI_ERRCODES_IGNORE + double complex MPI_STATUS_IGNORE, MPI_STATUSES_IGNORE + common/mpi_bottom/MPI_BOTTOM + common/mpi_argv_null/MPI_ARGV_NULL + common/mpi_argvs_null/MPI_ARGVS_NULL + common/mpi_errcodes_ignore/MPI_ERRCODES_IGNORE + common/mpi_status_ignore/MPI_STATUS_IGNORE + common/mpi_statuses_ignore/MPI_STATUSES_IGNORE +! +! NULL "handles" (indices) +! + integer MPI_GROUP_NULL, MPI_COMM_NULL, MPI_DATATYPE_NULL + integer MPI_REQUEST_NULL, MPI_OP_NULL, MPI_ERRHANDLER_NULL + integer MPI_INFO_NULL + + parameter (MPI_GROUP_NULL=-1) + parameter (MPI_COMM_NULL=-1) + parameter (MPI_DATATYPE_NULL=-1) + parameter (MPI_REQUEST_NULL=-1) + parameter (MPI_OP_NULL=-1) + parameter (MPI_ERRHANDLER_NULL=-1) + parameter (MPI_INFO_NULL=-1) +! +! MPI_Init_thread constants +! + integer MPI_THREAD_SINGLE, MPI_THREAD_FUNNELED + integer MPI_THREAD_SERIALIZED, MPI_THREAD_MULTIPLE + + parameter (MPI_THREAD_SINGLE=0) + parameter (MPI_THREAD_FUNNELED=1) + parameter (MPI_THREAD_SERIALIZED=2) + parameter (MPI_THREAD_MULTIPLE=3) +! +! error classes +! + integer MPI_ERR_BUFFER, MPI_ERR_COUNT, MPI_ERR_TYPE + integer MPI_ERR_TAG, MPI_ERR_COMM, MPI_ERR_RANK + integer MPI_ERR_REQUEST, MPI_ERR_ROOT, MPI_ERR_GROUP + integer MPI_ERR_OP, MPI_ERR_TOPOLOGY, MPI_ERR_DIMS + integer MPI_ERR_ARG, MPI_ERR_UNKNOWN, MPI_ERR_TRUNCATE + integer MPI_ERR_OTHER, MPI_ERR_INTERN, MPI_ERR_IN_STATUS + integer MPI_ERR_PENDING, MPI_ERR_SYSRESOURCE + integer MPI_ERR_LOCALDEAD, MPI_ERR_REMOTEDEAD + integer MPI_ERR_VALUE, MPI_ERR_FLAGS, MPI_ERR_SERVICE + integer MPI_ERR_NAME, MPI_ERR_SPAWN, MPI_ERR_KEYVAL + integer MPI_ERR_INFO_NOKEY, MPI_ERR_WIN + integer MPI_ERR_EPOCH, MPI_ERR_TYPENOTSUP + integer MPI_ERR_INFO_KEY, MPI_ERR_INFO_VALUE + integer MPI_ERR_NO_MEM, MPI_ERR_BASE + integer MPI_ERR_LASTCODE + + parameter (MPI_ERR_BUFFER=1) + parameter (MPI_ERR_COUNT=2) + parameter (MPI_ERR_TYPE=3) + parameter (MPI_ERR_TAG=4) + parameter (MPI_ERR_COMM=5) + parameter (MPI_ERR_RANK=6) + parameter (MPI_ERR_REQUEST=7) + parameter (MPI_ERR_ROOT=8) + parameter (MPI_ERR_GROUP=9) + parameter (MPI_ERR_OP=10) + parameter (MPI_ERR_TOPOLOGY=11) + parameter (MPI_ERR_DIMS=12) + parameter (MPI_ERR_ARG=13) + parameter (MPI_ERR_UNKNOWN=14) + parameter (MPI_ERR_TRUNCATE=15) + parameter (MPI_ERR_OTHER=16) + parameter (MPI_ERR_INTERN=17) + parameter (MPI_ERR_IN_STATUS=18) + parameter (MPI_ERR_PENDING=19) + parameter (MPI_ERR_SYSRESOURCE=20) + parameter (MPI_ERR_LOCALDEAD=21) + parameter (MPI_ERR_REMOTEDEAD=22) + parameter (MPI_ERR_VALUE=23) + parameter (MPI_ERR_FLAGS=24) + parameter (MPI_ERR_SERVICE=25) + parameter (MPI_ERR_NAME=26) + parameter (MPI_ERR_SPAWN=27) + parameter (MPI_ERR_KEYVAL=28) + parameter (MPI_ERR_INFO_NOKEY=29) + parameter (MPI_ERR_WIN=30) + parameter (MPI_ERR_EPOCH=31) + parameter (MPI_ERR_TYPENOTSUP=32) + parameter (MPI_ERR_INFO_KEY=33) + parameter (MPI_ERR_INFO_VALUE=34) + parameter (MPI_ERR_NO_MEM=35) + parameter (MPI_ERR_BASE=36) + parameter (MPI_ERR_LASTCODE=37) +! +! comparison results +! + integer MPI_IDENT, MPI_CONGRUENT, MPI_SIMILAR, MPI_UNEQUAL + + parameter (MPI_IDENT=1) + parameter (MPI_CONGRUENT=2) + parameter (MPI_SIMILAR=3) + parameter (MPI_UNEQUAL=4) +! +! lookup table indices +! + integer MPI_COMM_WORLD, MPI_COMM_SELF + integer MPI_GROUP_EMPTY + integer MPI_ERRORS_ARE_FATAL, MPI_ERRORS_RETURN + + parameter (MPI_COMM_WORLD=0) + parameter (MPI_COMM_SELF=1) + parameter (MPI_GROUP_EMPTY=2) + parameter (MPI_ERRORS_ARE_FATAL=3) + parameter (MPI_ERRORS_RETURN=4) + + integer MPI_INTEGER, MPI_REAL, MPI_DOUBLE_PRECISION + integer MPI_COMPLEX, MPI_LOGICAL, MPI_CHARACTER + integer MPI_BYTE, MPI_PACKED, MPI_UB, MPI_LB, MPI_2REAL + integer MPI_2DOUBLE_PRECISION, MPI_2INTEGER + integer MPI_DOUBLE_COMPLEX + + parameter (MPI_BYTE=5) + parameter (MPI_PACKED=6) + parameter (MPI_UB=7) + parameter (MPI_LB=8) + parameter (MPI_CHARACTER=9) + parameter (MPI_LOGICAL=10) + parameter (MPI_INTEGER=11) + parameter (MPI_REAL=12) + parameter (MPI_DOUBLE_PRECISION=13) + parameter (MPI_COMPLEX=14) + parameter (MPI_DOUBLE_COMPLEX=15) + parameter (MPI_2REAL=16) + parameter (MPI_2DOUBLE_PRECISION=17) + parameter (MPI_2INTEGER=18) + + integer MPI_MAX, MPI_MIN, MPI_SUM, MPI_PROD, MPI_LAND + integer MPI_BAND, MPI_LOR, MPI_BOR, MPI_LXOR, MPI_BXOR + integer MPI_MAXLOC, MPI_MINLOC, MPI_REPLACE + + parameter (MPI_MAX=19) + parameter (MPI_MIN=20) + parameter (MPI_SUM=21) + parameter (MPI_PROD=22) + parameter (MPI_LAND=23) + parameter (MPI_BAND=24) + parameter (MPI_LOR=25) + parameter (MPI_BOR=26) + parameter (MPI_LXOR=27) + parameter (MPI_BXOR=28) + parameter (MPI_MAXLOC=29) + parameter (MPI_MINLOC=30) + parameter (MPI_REPLACE=31) +! +! attribute functions +! + external MPI_NULL_COPY_FN, MPI_NULL_DELETE_FN + external MPI_COMM_NULL_COPY_FN, MPI_COMM_NULL_DELETE_FN + external MPI_TYPE_NULL_COPY_FN, MPI_TYPE_NULL_DELETE_FN + external MPI_WIN_NULL_COPY_FN, MPI_WIN_NULL_DELETE_FN + external MPI_DUP_FN, MPI_COMM_DUP_FN + external MPI_TYPE_DUP_FN, MPI_WIN_DUP_FN +! +! double precision functions +! + double precision MPI_WTIME, MPI_WTICK, PMPI_WTIME, PMPI_WTICK + external MPI_WTIME, MPI_WTICK, PMPI_WTIME, PMPI_WTICK Added: test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/opac.txt URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/opac.txt?rev=59793&view=auto ============================================================================== --- test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/opac.txt (added) +++ test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/sphot/opac.txt Fri Nov 21 00:17:30 2008 @@ -0,0 +1,23296 @@ +-.13015000000000E+01 +-.39945000000000E+00 +0.57578000000000E+00 +0.16245000000000E+01 +0.27018000000000E+01 +0.37584000000000E+01 +0.47910000000000E+01 +0.58290000000000E+01 +0.68268000000000E+01 +0.76145000000000E+01 +0.79950000000000E+01 +0.80635000000000E+01 +0.80688000000000E+01 +0.80703000000000E+01 +-.16232000000000E+01 +-.70277000000000E+00 +0.28029000000000E+00 +0.13337000000000E+01 +0.24211000000000E+01 +0.34997000000000E+01 +0.45627000000000E+01 +0.56287000000000E+01 +0.66600000000000E+01 +0.75219000000000E+01 +0.80151000000000E+01 +0.81377000000000E+01 +0.81467000000000E+01 +0.81482000000000E+01 +-.18928000000000E+01 +-.95293000000000E+00 +0.38838000000000E-01 +0.10962000000000E+01 +0.21908000000000E+01 +0.32851000000000E+01 +0.43701000000000E+01 +0.54572000000000E+01 +0.65165000000000E+01 +0.74419000000000E+01 +0.80476000000000E+01 +0.82493000000000E+01 +0.82688000000000E+01 +0.82703000000000E+01 +-.21338000000000E+01 +-.11762000000000E+01 +-.17716000000000E+00 +0.88231000000000E+00 +0.19813000000000E+01 +0.30863000000000E+01 +0.41870000000000E+01 +0.52898000000000E+01 +0.63716000000000E+01 +0.73499000000000E+01 +0.80613000000000E+01 +0.83635000000000E+01 +0.84075000000000E+01 +0.84094000000000E+01 +-.23597000000000E+01 +-.13865000000000E+01 +-.38189000000000E+00 +0.67792000000000E+00 +0.17790000000000E+01 +0.28917000000000E+01 +0.40039000000000E+01 +0.51187000000000E+01 +0.62179000000000E+01 +0.72386000000000E+01 +0.80439000000000E+01 +0.84612000000000E+01 +0.85493000000000E+01 +0.85537000000000E+01 +-.25383000000000E+01 +-.15514000000000E+01 +-.54070000000000E+00 +0.52029000000000E+00 +0.16234000000000E+01 +0.27421000000000E+01 +0.38637000000000E+01 +0.49879000000000E+01 +0.61008000000000E+01 +0.71552000000000E+01 +0.80398000000000E+01 +0.85776000000000E+01 +0.87346000000000E+01 +0.87463000000000E+01 +-.26945000000000E+01 +-.16960000000000E+01 +-.67999000000000E+00 +0.38177000000000E+00 +0.14860000000000E+01 +0.26092000000000E+01 +0.37376000000000E+01 +0.48689000000000E+01 +0.59923000000000E+01 +0.70723000000000E+01 +0.80220000000000E+01 +0.86758000000000E+01 +0.89265000000000E+01 +0.89565000000000E+01 +-.28793000000000E+01 +-.18708000000000E+01 +-.85175000000000E+00 +0.20809000000000E+00 +0.13109000000000E+01 +0.24360000000000E+01 +0.35687000000000E+01 +0.47050000000000E+01 +0.58357000000000E+01 +0.69351000000000E+01 +0.79363000000000E+01 +0.86951000000000E+01 +0.90581000000000E+01 +0.91243000000000E+01 +-.30890000000000E+01 +-.20713000000000E+01 +-.10501000000000E+01 +0.60034000000000E-02 +0.11053000000000E+01 +0.22305000000000E+01 +0.33657000000000E+01 +0.45051000000000E+01 +0.56414000000000E+01 +0.67550000000000E+01 +0.77958000000000E+01 +0.86448000000000E+01 +0.91296000000000E+01 +0.92559000000000E+01 +-.33200000000000E+01 +-.22934000000000E+01 +-.12702000000000E+01 +-.21888000000000E+00 +0.87515000000000E+00 +0.19986000000000E+01 +0.31349000000000E+01 +0.42765000000000E+01 +0.54166000000000E+01 +0.65406000000000E+01 +0.76115000000000E+01 +0.85342000000000E+01 +0.91404000000000E+01 +0.93521000000000E+01 +-.35693000000000E+01 +-.25338000000000E+01 +-.15081000000000E+01 +-.46178000000000E+00 +0.62543000000000E+00 +0.17457000000000E+01 +0.28819000000000E+01 +0.40248000000000E+01 +0.51675000000000E+01 +0.62991000000000E+01 +0.73921000000000E+01 +0.83735000000000E+01 +0.90916000000000E+01 +0.94104000000000E+01 +-.38341000000000E+01 +-.27896000000000E+01 +-.17604000000000E+01 +-.71873000000000E+00 +0.36050000000000E+00 +0.14759000000000E+01 +0.26110000000000E+01 +0.37543000000000E+01 +0.48988000000000E+01 +0.60358000000000E+01 +0.71451000000000E+01 +0.81716000000000E+01 +0.89875000000000E+01 +0.94268000000000E+01 +-.41121000000000E+01 +-.30584000000000E+01 +-.20245000000000E+01 +-.98651000000000E+00 +0.84082000000000E-01 +0.11931000000000E+01 +0.23257000000000E+01 +0.34689000000000E+01 +0.46145000000000E+01 +0.57554000000000E+01 +0.68765000000000E+01 +0.79371000000000E+01 +0.88340000000000E+01 +0.93967000000000E+01 +-.44010000000000E+01 +-.33383000000000E+01 +-.22987000000000E+01 +-.12626000000000E+01 +-.20073000000000E+00 +0.90039000000000E+00 +0.20294000000000E+01 +0.31716000000000E+01 +0.43177000000000E+01 +0.54613000000000E+01 +0.65909000000000E+01 +0.76768000000000E+01 +0.86384000000000E+01 +0.93179000000000E+01 +-.46992000000000E+01 +-.36276000000000E+01 +-.25812000000000E+01 +-.15453000000000E+01 +-.49140000000000E+00 +0.60054000000000E+00 +0.17246000000000E+01 +0.28651000000000E+01 +0.40112000000000E+01 +0.51565000000000E+01 +0.62922000000000E+01 +0.73965000000000E+01 +0.84084000000000E+01 +0.91917000000000E+01 +-.49633000000000E+01 +-.38842000000000E+01 +-.28311000000000E+01 +-.17935000000000E+01 +-.74527000000000E+00 +0.33823000000000E+00 +0.14569000000000E+01 +0.25953000000000E+01 +0.37412000000000E+01 +0.48876000000000E+01 +0.60277000000000E+01 +0.71453000000000E+01 +0.81951000000000E+01 +0.90659000000000E+01 +-.52113000000000E+01 +-.41254000000000E+01 +-.30659000000000E+01 +-.20255000000000E+01 +-.98129000000000E+00 +0.94242000000000E-01 +0.12070000000000E+01 +0.23428000000000E+01 +0.34880000000000E+01 +0.46351000000000E+01 +0.57783000000000E+01 +0.69054000000000E+01 +0.79835000000000E+01 +0.89248000000000E+01 +-.54805000000000E+01 +-.43881000000000E+01 +-.33215000000000E+01 +-.22772000000000E+01 +-.12357000000000E+01 +-.16870000000000E+00 +0.93657000000000E+00 +0.20687000000000E+01 +0.32128000000000E+01 +0.43601000000000E+01 +0.55054000000000E+01 +0.66394000000000E+01 +0.77380000000000E+01 +0.87344000000000E+01 +-.57654000000000E+01 +-.46665000000000E+01 +-.35927000000000E+01 +-.25431000000000E+01 +-.15030000000000E+01 +-.44412000000000E+00 +0.65231000000000E+00 +0.17796000000000E+01 +0.29219000000000E+01 +0.40691000000000E+01 +0.52156000000000E+01 +0.63545000000000E+01 +0.74681000000000E+01 +0.85063000000000E+01 +-.60619000000000E+01 +-.49572000000000E+01 +-.38759000000000E+01 +-.28201000000000E+01 +-.17793000000000E+01 +-.72768000000000E+00 +0.35893000000000E+00 +0.14799000000000E+01 +0.26197000000000E+01 +0.37663000000000E+01 +0.49137000000000E+01 +0.60560000000000E+01 +0.71803000000000E+01 +0.82500000000000E+01 +-.63671000000000E+01 +-.52571000000000E+01 +-.41686000000000E+01 +-.31058000000000E+01 +-.20626000000000E+01 +-.10164000000000E+01 +0.59909000000000E-01 +0.11732000000000E+01 +0.23094000000000E+01 +0.34551000000000E+01 +0.46028000000000E+01 +0.57474000000000E+01 +0.68795000000000E+01 +0.79720000000000E+01 +-.66788000000000E+01 +-.55642000000000E+01 +-.44687000000000E+01 +-.33987000000000E+01 +-.23512000000000E+01 +-.13085000000000E+01 +-.24214000000000E+00 +0.86208000000000E+00 +0.19938000000000E+01 +0.31378000000000E+01 +0.42854000000000E+01 +0.54318000000000E+01 +0.65692000000000E+01 +0.76785000000000E+01 +-.69956000000000E+01 +-.58768000000000E+01 +-.47750000000000E+01 +-.36973000000000E+01 +-.26443000000000E+01 +-.16027000000000E+01 +-.54529000000000E+00 +0.54874000000000E+00 +0.16745000000000E+01 +0.28163000000000E+01 +0.39636000000000E+01 +0.51108000000000E+01 +0.62522000000000E+01 +0.73734000000000E+01 +-.73157000000000E+01 +-.61934000000000E+01 +-.50859000000000E+01 +-.40007000000000E+01 +-.29411000000000E+01 +-.18984000000000E+01 +-.84819000000000E+00 +0.23504000000000E+00 +0.13535000000000E+01 +0.24922000000000E+01 +0.36386000000000E+01 +0.47864000000000E+01 +0.59304000000000E+01 +0.70603000000000E+01 +-.76385000000000E+01 +-.65127000000000E+01 +-.54001000000000E+01 +-.43079000000000E+01 +-.32410000000000E+01 +-.21951000000000E+01 +-.11500000000000E+01 +-.77499000000000E-01 +0.10323000000000E+01 +0.21668000000000E+01 +0.33119000000000E+01 +0.44597000000000E+01 +0.56057000000000E+01 +0.67416000000000E+01 +-.79215000000000E+01 +-.67920000000000E+01 +-.56760000000000E+01 +-.45778000000000E+01 +-.35045000000000E+01 +-.24545000000000E+01 +-.14117000000000E+01 +-.34790000000000E+00 +0.75331000000000E+00 +0.18833000000000E+01 +0.30267000000000E+01 +0.41744000000000E+01 +0.53215000000000E+01 +0.64619000000000E+01 +-.81868000000000E+01 +-.70548000000000E+01 +-.59352000000000E+01 +-.48320000000000E+01 +-.37525000000000E+01 +-.26978000000000E+01 +-.16555000000000E+01 +-.59888000000000E+00 +0.49370000000000E+00 +0.16185000000000E+01 +0.27599000000000E+01 +0.39072000000000E+01 +0.50551000000000E+01 +0.61984000000000E+01 +-.84602000000000E+01 +-.73278000000000E+01 +-.62050000000000E+01 +-.50970000000000E+01 +-.40114000000000E+01 +-.29510000000000E+01 +-.19077000000000E+01 +-.85719000000000E+00 +0.22611000000000E+00 +0.13446000000000E+01 +0.24833000000000E+01 +0.36298000000000E+01 +0.47780000000000E+01 +0.59235000000000E+01 +-.87444000000000E+01 +-.76071000000000E+01 +-.64811000000000E+01 +-.53685000000000E+01 +-.42766000000000E+01 +-.32101000000000E+01 +-.21642000000000E+01 +-.11182000000000E+01 +-.44237000000000E-01 +0.10667000000000E+01 +0.22019000000000E+01 +0.33473000000000E+01 +0.44955000000000E+01 +0.56425000000000E+01 +-.90359000000000E+01 +-.78849000000000E+01 +-.67566000000000E+01 +-.56421000000000E+01 +-.45444000000000E+01 +-.34716000000000E+01 +-.24219000000000E+01 +-.13785000000000E+01 +-.31334000000000E+00 +0.78920000000000E+00 +0.19200000000000E+01 +0.30637000000000E+01 +0.42118000000000E+01 +0.53596000000000E+01 +-.93123000000000E+01 +-.81631000000000E+01 +-.70349000000000E+01 +-.59147000000000E+01 +-.48116000000000E+01 +-.37325000000000E+01 +-.26779000000000E+01 +-.16354000000000E+01 +-.57796000000000E+00 +0.51552000000000E+00 +0.16409000000000E+01 +0.27826000000000E+01 +0.39301000000000E+01 +0.50785000000000E+01 +-.95796000000000E+01 +-.84355000000000E+01 +-.73068000000000E+01 +-.61829000000000E+01 +-.50751000000000E+01 +-.39901000000000E+01 +-.29299000000000E+01 +-.18865000000000E+01 +-.83530000000000E+00 +0.24894000000000E+00 +0.13681000000000E+01 +0.25071000000000E+01 +0.36539000000000E+01 +0.48025000000000E+01 +-.43676000000000E+01 +-.32296000000000E+01 +-.21115000000000E+01 +-.10286000000000E+01 +0.13840000000000E-01 +0.10180000000000E+01 +0.20089000000000E+01 +0.30468000000000E+01 +0.41346000000000E+01 +0.52047000000000E+01 +0.61730000000000E+01 +0.70017000000000E+01 +0.72812000000000E+01 +0.72831000000000E+01 +-.46469000000000E+01 +-.35084000000000E+01 +-.23903000000000E+01 +-.13092000000000E+01 +-.26765000000000E+00 +0.74828000000000E+00 +0.17655000000000E+01 +0.28251000000000E+01 +0.39227000000000E+01 +0.50049000000000E+01 +0.59993000000000E+01 +0.68407000000000E+01 +0.71438000000000E+01 +0.71464000000000E+01 +-.48846000000000E+01 +-.37454000000000E+01 +-.26260000000000E+01 +-.15433000000000E+01 +-.49875000000000E+00 +0.52930000000000E+00 +0.15688000000000E+01 +0.26469000000000E+01 +0.37544000000000E+01 +0.48485000000000E+01 +0.58668000000000E+01 +0.67235000000000E+01 +0.70603000000000E+01 +0.70654000000000E+01 +-.51415000000000E+01 +-.40006000000000E+01 +-.28778000000000E+01 +-.17897000000000E+01 +-.73935000000000E+00 +0.29677000000000E+00 +0.13487000000000E+01 +0.24373000000000E+01 +0.35521000000000E+01 +0.46572000000000E+01 +0.56981000000000E+01 +0.65750000000000E+01 +0.69579000000000E+01 +0.69702000000000E+01 +-.53975000000000E+01 +-.42548000000000E+01 +-.31272000000000E+01 +-.20307000000000E+01 +-.97083000000000E+00 +0.75184000000000E-01 +0.11387000000000E+01 +0.22365000000000E+01 +0.33569000000000E+01 +0.44696000000000E+01 +0.55261000000000E+01 +0.64232000000000E+01 +0.68617000000000E+01 +0.68888000000000E+01 +-.55923000000000E+01 +-.44480000000000E+01 +-.33165000000000E+01 +-.22120000000000E+01 +-.11416000000000E+01 +-.84482000000000E-01 +0.99057000000000E+00 +0.20969000000000E+01 +0.32224000000000E+01 +0.43413000000000E+01 +0.54110000000000E+01 +0.63315000000000E+01 +0.68346000000000E+01 +0.68887000000000E+01 +-.57866000000000E+01 +-.46409000000000E+01 +-.35055000000000E+01 +-.23932000000000E+01 +-.13123000000000E+01 +-.24556000000000E+00 +0.83783000000000E+00 +0.19500000000000E+01 +0.30793000000000E+01 +0.42031000000000E+01 +0.52842000000000E+01 +0.62305000000000E+01 +0.68042000000000E+01 +0.69021000000000E+01 +-.59592000000000E+01 +-.48123000000000E+01 +-.36738000000000E+01 +-.25547000000000E+01 +-.14642000000000E+01 +-.38855000000000E+00 +0.70183000000000E+00 +0.18187000000000E+01 +0.29509000000000E+01 +0.40789000000000E+01 +0.51702000000000E+01 +0.61433000000000E+01 +0.67905000000000E+01 +0.69515000000000E+01 +-.61250000000000E+01 +-.49772000000000E+01 +-.38361000000000E+01 +-.27112000000000E+01 +-.16122000000000E+01 +-.52878000000000E+00 +0.56696000000000E+00 +0.16871000000000E+01 +0.28216000000000E+01 +0.39531000000000E+01 +0.50537000000000E+01 +0.60538000000000E+01 +0.67742000000000E+01 +0.70172000000000E+01 +-.63287000000000E+01 +-.51802000000000E+01 +-.40366000000000E+01 +-.29064000000000E+01 +-.17992000000000E+01 +-.70923000000000E+00 +0.38949000000000E+00 +0.15110000000000E+01 +0.26467000000000E+01 +0.37811000000000E+01 +0.48904000000000E+01 +0.59160000000000E+01 +0.67064000000000E+01 +0.70468000000000E+01 +-.65090000000000E+01 +-.53599000000000E+01 +-.42147000000000E+01 +-.30804000000000E+01 +-.19663000000000E+01 +-.87030000000000E+00 +0.23121000000000E+00 +0.13537000000000E+01 +0.24904000000000E+01 +0.36273000000000E+01 +0.47444000000000E+01 +0.57936000000000E+01 +0.66484000000000E+01 +0.70952000000000E+01 +-.66833000000000E+01 +-.55337000000000E+01 +-.43873000000000E+01 +-.32498000000000E+01 +-.21299000000000E+01 +-.10285000000000E+01 +0.75277000000000E-01 +0.11982000000000E+01 +0.23355000000000E+01 +0.34745000000000E+01 +0.45983000000000E+01 +0.56682000000000E+01 +0.65808000000000E+01 +0.71360000000000E+01 +-.68947000000000E+01 +-.57446000000000E+01 +-.45972000000000E+01 +-.34567000000000E+01 +-.23315000000000E+01 +-.12248000000000E+01 +-.11972000000000E+00 +0.10024000000000E+01 +0.21395000000000E+01 +0.32800000000000E+01 +0.44094000000000E+01 +0.54969000000000E+01 +0.64595000000000E+01 +0.71188000000000E+01 +-.71426000000000E+01 +-.59922000000000E+01 +-.48437000000000E+01 +-.37007000000000E+01 +-.25705000000000E+01 +-.14585000000000E+01 +-.35234000000000E+00 +0.76799000000000E+00 +0.19040000000000E+01 +0.30453000000000E+01 +0.41793000000000E+01 +0.52814000000000E+01 +0.62860000000000E+01 +0.70404000000000E+01 +-.74136000000000E+01 +-.62629000000000E+01 +-.51138000000000E+01 +-.39687000000000E+01 +-.28340000000000E+01 +-.17164000000000E+01 +-.60880000000000E+00 +0.50922000000000E+00 +0.16434000000000E+01 +0.27849000000000E+01 +0.39224000000000E+01 +0.50361000000000E+01 +0.60751000000000E+01 +0.69130000000000E+01 +-.76725000000000E+01 +-.65217000000000E+01 +-.53721000000000E+01 +-.42255000000000E+01 +-.30873000000000E+01 +-.19646000000000E+01 +-.85472000000000E+00 +0.26131000000000E+00 +0.13933000000000E+01 +0.25347000000000E+01 +0.36747000000000E+01 +0.47976000000000E+01 +0.58640000000000E+01 +0.67723000000000E+01 +-.78937000000000E+01 +-.67428000000000E+01 +-.55927000000000E+01 +-.44452000000000E+01 +-.33044000000000E+01 +-.21776000000000E+01 +-.10650000000000E+01 +0.49815000000000E-01 +0.11798000000000E+01 +0.23207000000000E+01 +0.34625000000000E+01 +0.45924000000000E+01 +0.56803000000000E+01 +0.66465000000000E+01 +-.81431000000000E+01 +-.69922000000000E+01 +-.58419000000000E+01 +-.46935000000000E+01 +-.35505000000000E+01 +-.24195000000000E+01 +-.13037000000000E+01 +-.19003000000000E+00 +0.93733000000000E+00 +0.20770000000000E+01 +0.32200000000000E+01 +0.43551000000000E+01 +0.54595000000000E+01 +0.64716000000000E+01 +-.84138000000000E+01 +-.72628000000000E+01 +-.61122000000000E+01 +-.49630000000000E+01 +-.38182000000000E+01 +-.26833000000000E+01 +-.15638000000000E+01 +-.45057000000000E+00 +0.67371000000000E+00 +0.18116000000000E+01 +0.29549000000000E+01 +0.40937000000000E+01 +0.52106000000000E+01 +0.62585000000000E+01 +-.87002000000000E+01 +-.75491000000000E+01 +-.63983000000000E+01 +-.52487000000000E+01 +-.41022000000000E+01 +-.29639000000000E+01 +-.18401000000000E+01 +-.72641000000000E+00 +0.39464000000000E+00 +0.15301000000000E+01 +0.26731000000000E+01 +0.38145000000000E+01 +0.49404000000000E+01 +0.60157000000000E+01 +-.89431000000000E+01 +-.77920000000000E+01 +-.66411000000000E+01 +-.54911000000000E+01 +-.43436000000000E+01 +-.32029000000000E+01 +-.20754000000000E+01 +-.96033000000000E+00 +0.15837000000000E+00 +0.12914000000000E+01 +0.24338000000000E+01 +0.35770000000000E+01 +0.47096000000000E+01 +0.58054000000000E+01 +-.91726000000000E+01 +-.80215000000000E+01 +-.68706000000000E+01 +-.57203000000000E+01 +-.45720000000000E+01 +-.34294000000000E+01 +-.22985000000000E+01 +-.11815000000000E+01 +-.64548000000000E-01 +0.10659000000000E+01 +0.22073000000000E+01 +0.33516000000000E+01 +0.44890000000000E+01 +0.56001000000000E+01 +-.94316000000000E+01 +-.82803000000000E+01 +-.71293000000000E+01 +-.59788000000000E+01 +-.48298000000000E+01 +-.36854000000000E+01 +-.25511000000000E+01 +-.14313000000000E+01 +-.31573000000000E+00 +0.81161000000000E+00 +0.19515000000000E+01 +0.30961000000000E+01 +0.42368000000000E+01 +0.53590000000000E+01 +-.97100000000000E+01 +-.85588000000000E+01 +-.74077000000000E+01 +-.62570000000000E+01 +-.51074000000000E+01 +-.39614000000000E+01 +-.28239000000000E+01 +-.17007000000000E+01 +-.58554000000000E+00 +0.53842000000000E+00 +0.16760000000000E+01 +0.28204000000000E+01 +0.39634000000000E+01 +0.50935000000000E+01 +-.10002000000000E+02 +-.88503000000000E+01 +-.76993000000000E+01 +-.65485000000000E+01 +-.53986000000000E+01 +-.42512000000000E+01 +-.31108000000000E+01 +-.19837000000000E+01 +-.86787000000000E+00 +0.25279000000000E+00 +0.13875000000000E+01 +0.25310000000000E+01 +0.36754000000000E+01 +0.48113000000000E+01 +-.10296000000000E+02 +-.91450000000000E+01 +-.79940000000000E+01 +-.68430000000000E+01 +-.56927000000000E+01 +-.45444000000000E+01 +-.34017000000000E+01 +-.22706000000000E+01 +-.11529000000000E+01 +-.34925000000000E-01 +0.10964000000000E+01 +0.22385000000000E+01 +0.33836000000000E+01 +0.45234000000000E+01 +-.10595000000000E+02 +-.94443000000000E+01 +-.82930000000000E+01 +-.71421000000000E+01 +-.59915000000000E+01 +-.48424000000000E+01 +-.36977000000000E+01 +-.25629000000000E+01 +-.14423000000000E+01 +-.32613000000000E+00 +0.80153000000000E+00 +0.19417000000000E+01 +0.30868000000000E+01 +0.42294000000000E+01 +-.10896000000000E+02 +-.97451000000000E+01 +-.85937000000000E+01 +-.74427000000000E+01 +-.62920000000000E+01 +-.51425000000000E+01 +-.39961000000000E+01 +-.28580000000000E+01 +-.17338000000000E+01 +-.61816000000000E+00 +0.50578000000000E+00 +0.16433000000000E+01 +0.27880000000000E+01 +0.39323000000000E+01 +-.11196000000000E+02 +-.10045000000000E+02 +-.88938000000000E+01 +-.77427000000000E+01 +-.65918000000000E+01 +-.54418000000000E+01 +-.42942000000000E+01 +-.31533000000000E+01 +-.20252000000000E+01 +-.90884000000000E+00 +0.21173000000000E+00 +0.13462000000000E+01 +0.24898000000000E+01 +0.36351000000000E+01 +-.11493000000000E+02 +-.10342000000000E+02 +-.91907000000000E+01 +-.80396000000000E+01 +-.68885000000000E+01 +-.57382000000000E+01 +-.45897000000000E+01 +-.34465000000000E+01 +-.23146000000000E+01 +-.11963000000000E+01 +-.78371000000000E-01 +0.10526000000000E+01 +0.21947000000000E+01 +0.33404000000000E+01 +-.11737000000000E+02 +-.10585000000000E+02 +-.94338000000000E+01 +-.82827000000000E+01 +-.71318000000000E+01 +-.59813000000000E+01 +-.48323000000000E+01 +-.36874000000000E+01 +-.25526000000000E+01 +-.14319000000000E+01 +-.31542000000000E+00 +0.81259000000000E+00 +0.19530000000000E+01 +0.30987000000000E+01 +-.11955000000000E+02 +-.10803000000000E+02 +-.96519000000000E+01 +-.85007000000000E+01 +-.73496000000000E+01 +-.61990000000000E+01 +-.50494000000000E+01 +-.39035000000000E+01 +-.27662000000000E+01 +-.16430000000000E+01 +-.52713000000000E+00 +0.59816000000000E+00 +0.17368000000000E+01 +0.28823000000000E+01 +-.63754000000000E+01 +-.52275000000000E+01 +-.40850000000000E+01 +-.29572000000000E+01 +-.18657000000000E+01 +-.83522000000000E+00 +0.15807000000000E+00 +0.11901000000000E+01 +0.22739000000000E+01 +0.33428000000000E+01 +0.43119000000000E+01 +0.51577000000000E+01 +0.59410000000000E+01 +0.61145000000000E+01 +-.65956000000000E+01 +-.54470000000000E+01 +-.43027000000000E+01 +-.31710000000000E+01 +-.20698000000000E+01 +-.10199000000000E+01 +-.10732000000000E-02 +0.10477000000000E+01 +0.21374000000000E+01 +0.32166000000000E+01 +0.42120000000000E+01 +0.50820000000000E+01 +0.58688000000000E+01 +0.60488000000000E+01 +-.68080000000000E+01 +-.56588000000000E+01 +-.45135000000000E+01 +-.33792000000000E+01 +-.22719000000000E+01 +-.12104000000000E+01 +-.17844000000000E+00 +0.87669000000000E+00 +0.19683000000000E+01 +0.30563000000000E+01 +0.40769000000000E+01 +0.49760000000000E+01 +0.57673000000000E+01 +0.59584000000000E+01 +-.70631000000000E+01 +-.59138000000000E+01 +-.47678000000000E+01 +-.36321000000000E+01 +-.25219000000000E+01 +-.14561000000000E+01 +-.42285000000000E+00 +0.62794000000000E+00 +0.17164000000000E+01 +0.28116000000000E+01 +0.38572000000000E+01 +0.47903000000000E+01 +0.55894000000000E+01 +0.57979000000000E+01 +-.73335000000000E+01 +-.61838000000000E+01 +-.50372000000000E+01 +-.38998000000000E+01 +-.27856000000000E+01 +-.17137000000000E+01 +-.67697000000000E+00 +0.37069000000000E+00 +0.14555000000000E+01 +0.25549000000000E+01 +0.36190000000000E+01 +0.45831000000000E+01 +0.53916000000000E+01 +0.56252000000000E+01 +-.75664000000000E+01 +-.64165000000000E+01 +-.52693000000000E+01 +-.41301000000000E+01 +-.30117000000000E+01 +-.19327000000000E+01 +-.88968000000000E+00 +0.15909000000000E+00 +0.12436000000000E+01 +0.23478000000000E+01 +0.34280000000000E+01 +0.44213000000000E+01 +0.52430000000000E+01 +0.55120000000000E+01 +-.77898000000000E+01 +-.66396000000000E+01 +-.54918000000000E+01 +-.43508000000000E+01 +-.32278000000000E+01 +-.21403000000000E+01 +-.10883000000000E+01 +-.35124000000000E-01 +0.10509000000000E+01 +0.21595000000000E+01 +0.32527000000000E+01 +0.42711000000000E+01 +0.51108000000000E+01 +0.54265000000000E+01 +-.79990000000000E+01 +-.68488000000000E+01 +-.57002000000000E+01 +-.45574000000000E+01 +-.34298000000000E+01 +-.23329000000000E+01 +-.12702000000000E+01 +-.21054000000000E+00 +0.87811000000000E+00 +0.19903000000000E+01 +0.30934000000000E+01 +0.41322000000000E+01 +0.49949000000000E+01 +0.53688000000000E+01 +-.81516000000000E+01 +-.70012000000000E+01 +-.58522000000000E+01 +-.47079000000000E+01 +-.35762000000000E+01 +-.24709000000000E+01 +-.13973000000000E+01 +-.32959000000000E+00 +0.76326000000000E+00 +0.18791000000000E+01 +0.29899000000000E+01 +0.40454000000000E+01 +0.49351000000000E+01 +0.53774000000000E+01 +-.83145000000000E+01 +-.71639000000000E+01 +-.60145000000000E+01 +-.48688000000000E+01 +-.37333000000000E+01 +-.26201000000000E+01 +-.15359000000000E+01 +-.46066000000000E+00 +0.63541000000000E+00 +0.17537000000000E+01 +0.28699000000000E+01 +0.39395000000000E+01 +0.48588000000000E+01 +0.53770000000000E+01 +-.84546000000000E+01 +-.73038000000000E+01 +-.61539000000000E+01 +-.50071000000000E+01 +-.38685000000000E+01 +-.27487000000000E+01 +-.16551000000000E+01 +-.57271000000000E+00 +0.52655000000000E+00 +0.16469000000000E+01 +0.27676000000000E+01 +0.38493000000000E+01 +0.47997000000000E+01 +0.53971000000000E+01 +-.85959000000000E+01 +-.74451000000000E+01 +-.62949000000000E+01 +-.51471000000000E+01 +-.40060000000000E+01 +-.28804000000000E+01 +-.17785000000000E+01 +-.68979000000000E+00 +0.41202000000000E+00 +0.15338000000000E+01 +0.26581000000000E+01 +0.37507000000000E+01 +0.47318000000000E+01 +0.54086000000000E+01 +-.87891000000000E+01 +-.76382000000000E+01 +-.64878000000000E+01 +-.53391000000000E+01 +-.41957000000000E+01 +-.30648000000000E+01 +-.19549000000000E+01 +-.86029000000000E+00 +0.24263000000000E+00 +0.13645000000000E+01 +0.24914000000000E+01 +0.35936000000000E+01 +0.46036000000000E+01 +0.53567000000000E+01 +-.89690000000000E+01 +-.78179000000000E+01 +-.66672000000000E+01 +-.55181000000000E+01 +-.43729000000000E+01 +-.32379000000000E+01 +-.21212000000000E+01 +-.10213000000000E+01 +0.82893000000000E-01 +0.12047000000000E+01 +0.23337000000000E+01 +0.34445000000000E+01 +0.44808000000000E+01 +0.53046000000000E+01 +-.91445000000000E+01 +-.79935000000000E+01 +-.68428000000000E+01 +-.56931000000000E+01 +-.45465000000000E+01 +-.34083000000000E+01 +-.22860000000000E+01 +-.11810000000000E+01 +-.75628000000000E-01 +0.10459000000000E+01 +0.21766000000000E+01 +0.32946000000000E+01 +0.43541000000000E+01 +0.52411000000000E+01 +-.93567000000000E+01 +-.82056000000000E+01 +-.70548000000000E+01 +-.59047000000000E+01 +-.47571000000000E+01 +-.36160000000000E+01 +-.24885000000000E+01 +-.13784000000000E+01 +-.27211000000000E+00 +0.84821000000000E+00 +0.19796000000000E+01 +0.31035000000000E+01 +0.41826000000000E+01 +0.51245000000000E+01 +-.95967000000000E+01 +-.84456000000000E+01 +-.72947000000000E+01 +-.61443000000000E+01 +-.49957000000000E+01 +-.38522000000000E+01 +-.27201000000000E+01 +-.16048000000000E+01 +-.49740000000000E+00 +0.62111000000000E+00 +0.17523000000000E+01 +0.28807000000000E+01 +0.39759000000000E+01 +0.49640000000000E+01 +-.98584000000000E+01 +-.87070000000000E+01 +-.75562000000000E+01 +-.64055000000000E+01 +-.52562000000000E+01 +-.41108000000000E+01 +-.29746000000000E+01 +-.18541000000000E+01 +-.74490000000000E+00 +0.37151000000000E+00 +0.15016000000000E+01 +0.26331000000000E+01 +0.37410000000000E+01 +0.47670000000000E+01 +-.10108000000000E+02 +-.89565000000000E+01 +-.78055000000000E+01 +-.66547000000000E+01 +-.55050000000000E+01 +-.43582000000000E+01 +-.32187000000000E+01 +-.20934000000000E+01 +-.98186000000000E+00 +0.13288000000000E+00 +0.12614000000000E+01 +0.23950000000000E+01 +0.35128000000000E+01 +0.45690000000000E+01 +-.10319000000000E+02 +-.91677000000000E+01 +-.80164000000000E+01 +-.68656000000000E+01 +-.57156000000000E+01 +-.45677000000000E+01 +-.34261000000000E+01 +-.22971000000000E+01 +-.11827000000000E+01 +-.68909000000000E-01 +0.10581000000000E+01 +0.21930000000000E+01 +0.33182000000000E+01 +0.43982000000000E+01 +-.10562000000000E+02 +-.94109000000000E+01 +-.82598000000000E+01 +-.71088000000000E+01 +-.59584000000000E+01 +-.48098000000000E+01 +-.36661000000000E+01 +-.25333000000000E+01 +-.14157000000000E+01 +-.30253000000000E+00 +0.82227000000000E+00 +0.19572000000000E+01 +0.30878000000000E+01 +0.41859000000000E+01 +-.10828000000000E+02 +-.96768000000000E+01 +-.85256000000000E+01 +-.73745000000000E+01 +-.62240000000000E+01 +-.50747000000000E+01 +-.39293000000000E+01 +-.27930000000000E+01 +-.16715000000000E+01 +-.55843000000000E+00 +0.56364000000000E+00 +0.16977000000000E+01 +0.28318000000000E+01 +0.39435000000000E+01 +-.11110000000000E+02 +-.99592000000000E+01 +-.88079000000000E+01 +-.76569000000000E+01 +-.65061000000000E+01 +-.53563000000000E+01 +-.42095000000000E+01 +-.30699000000000E+01 +-.19444000000000E+01 +-.83029000000000E+00 +0.28897000000000E+00 +0.14212000000000E+01 +0.25573000000000E+01 +0.36789000000000E+01 +-.11350000000000E+02 +-.10198000000000E+02 +-.90471000000000E+01 +-.78960000000000E+01 +-.67451000000000E+01 +-.55950000000000E+01 +-.44471000000000E+01 +-.33054000000000E+01 +-.21763000000000E+01 +-.10605000000000E+01 +0.56761000000000E-01 +0.11870000000000E+01 +0.23243000000000E+01 +0.34529000000000E+01 +-.11574000000000E+02 +-.10423000000000E+02 +-.92717000000000E+01 +-.81206000000000E+01 +-.69696000000000E+01 +-.58193000000000E+01 +-.46708000000000E+01 +-.35273000000000E+01 +-.23950000000000E+01 +-.12771000000000E+01 +-.16113000000000E+00 +0.96704000000000E+00 +0.21045000000000E+01 +0.32382000000000E+01 +-.11822000000000E+02 +-.10671000000000E+02 +-.95193000000000E+01 +-.83682000000000E+01 +-.72172000000000E+01 +-.60665000000000E+01 +-.49175000000000E+01 +-.37724000000000E+01 +-.26370000000000E+01 +-.15162000000000E+01 +-.40114000000000E+00 +0.72433000000000E+00 +0.18611000000000E+01 +0.29980000000000E+01 +-.12087000000000E+02 +-.10935000000000E+02 +-.97839000000000E+01 +-.86328000000000E+01 +-.74818000000000E+01 +-.63311000000000E+01 +-.51814000000000E+01 +-.40349000000000E+01 +-.28967000000000E+01 +-.17724000000000E+01 +-.65742000000000E+00 +0.46511000000000E+00 +0.16003000000000E+01 +0.27390000000000E+01 +-.12362000000000E+02 +-.11210000000000E+02 +-.10059000000000E+02 +-.89077000000000E+01 +-.77567000000000E+01 +-.66058000000000E+01 +-.54558000000000E+01 +-.43082000000000E+01 +-.31674000000000E+01 +-.20394000000000E+01 +-.92343000000000E+00 +0.19627000000000E+00 +0.13291000000000E+01 +0.24685000000000E+01 +-.12642000000000E+02 +-.11491000000000E+02 +-.10339000000000E+02 +-.91882000000000E+01 +-.80369000000000E+01 +-.68861000000000E+01 +-.57357000000000E+01 +-.45873000000000E+01 +-.34442000000000E+01 +-.23125000000000E+01 +-.11945000000000E+01 +-.77164000000000E-01 +0.10528000000000E+01 +0.21919000000000E+01 +-.12924000000000E+02 +-.11772000000000E+02 +-.10621000000000E+02 +-.94700000000000E+01 +-.83188000000000E+01 +-.71677000000000E+01 +-.60172000000000E+01 +-.48680000000000E+01 +-.37231000000000E+01 +-.25880000000000E+01 +-.14672000000000E+01 +-.35129000000000E+00 +0.77545000000000E+00 +0.19135000000000E+01 +-.13204000000000E+02 +-.12052000000000E+02 +-.10901000000000E+02 +-.97498000000000E+01 +-.85986000000000E+01 +-.74475000000000E+01 +-.62968000000000E+01 +-.51471000000000E+01 +-.40007000000000E+01 +-.28625000000000E+01 +-.17384000000000E+01 +-.62288000000000E+00 +0.50058000000000E+00 +0.16367000000000E+01 +-.13479000000000E+02 +-.12327000000000E+02 +-.11176000000000E+02 +-.10025000000000E+02 +-.88733000000000E+01 +-.77223000000000E+01 +-.65714000000000E+01 +-.54214000000000E+01 +-.42738000000000E+01 +-.31331000000000E+01 +-.20053000000000E+01 +-.88913000000000E+00 +0.23137000000000E+00 +0.13651000000000E+01 +-.85859000000000E+01 +-.74379000000000E+01 +-.62943000000000E+01 +-.51638000000000E+01 +-.40660000000000E+01 +-.30269000000000E+01 +-.20269000000000E+01 +-.99219000000000E+00 +0.91763000000000E-01 +0.11606000000000E+01 +0.21302000000000E+01 +0.29765000000000E+01 +0.37640000000000E+01 +0.45248000000000E+01 +-.87322000000000E+01 +-.75833000000000E+01 +-.64375000000000E+01 +-.53013000000000E+01 +-.41892000000000E+01 +-.31201000000000E+01 +-.20793000000000E+01 +-.10155000000000E+01 +0.79191000000000E-01 +0.11588000000000E+01 +0.21544000000000E+01 +0.30245000000000E+01 +0.38198000000000E+01 +0.45771000000000E+01 +-.88862000000000E+01 +-.77366000000000E+01 +-.65892000000000E+01 +-.54491000000000E+01 +-.43270000000000E+01 +-.32370000000000E+01 +-.21687000000000E+01 +-.10863000000000E+01 +0.15131000000000E-01 +0.11039000000000E+01 +0.21239000000000E+01 +0.30229000000000E+01 +0.38301000000000E+01 +0.45835000000000E+01 +-.90801000000000E+01 +-.79299000000000E+01 +-.67817000000000E+01 +-.56394000000000E+01 +-.45115000000000E+01 +-.34097000000000E+01 +-.23266000000000E+01 +-.12356000000000E+01 +-.13261000000000E+00 +0.96234000000000E+00 +0.20059000000000E+01 +0.29388000000000E+01 +0.37645000000000E+01 +0.45143000000000E+01 +-.92866000000000E+01 +-.81362000000000E+01 +-.69873000000000E+01 +-.58429000000000E+01 +-.47097000000000E+01 +-.35972000000000E+01 +-.25009000000000E+01 +-.14035000000000E+01 +-.30267000000000E+00 +0.79202000000000E+00 +0.18505000000000E+01 +0.28141000000000E+01 +0.36625000000000E+01 +0.44084000000000E+01 +-.94966000000000E+01 +-.83459000000000E+01 +-.71964000000000E+01 +-.60504000000000E+01 +-.49133000000000E+01 +-.37928000000000E+01 +-.26871000000000E+01 +-.15862000000000E+01 +-.48971000000000E+00 +0.60164000000000E+00 +0.16708000000000E+01 +0.26639000000000E+01 +0.35400000000000E+01 +0.42837000000000E+01 +-.96890000000000E+01 +-.85383000000000E+01 +-.73884000000000E+01 +-.62413000000000E+01 +-.51011000000000E+01 +-.39742000000000E+01 +-.28610000000000E+01 +-.17575000000000E+01 +-.66492000000000E+00 +0.42288000000000E+00 +0.15003000000000E+01 +0.25203000000000E+01 +0.34278000000000E+01 +0.41722000000000E+01 +-.98706000000000E+01 +-.87197000000000E+01 +-.75696000000000E+01 +-.64215000000000E+01 +-.52789000000000E+01 +-.41470000000000E+01 +-.30278000000000E+01 +-.19214000000000E+01 +-.83051000000000E+00 +0.25567000000000E+00 +0.13402000000000E+01 +0.23839000000000E+01 +0.33237000000000E+01 +0.40739000000000E+01 +-.10029000000000E+02 +-.88777000000000E+01 +-.77272000000000E+01 +-.65784000000000E+01 +-.54337000000000E+01 +-.42979000000000E+01 +-.31735000000000E+01 +-.20635000000000E+01 +-.97160000000000E+00 +0.11549000000000E+00 +0.12068000000000E+01 +0.22703000000000E+01 +0.32404000000000E+01 +0.40028000000000E+01 +-.10179000000000E+02 +-.90281000000000E+01 +-.78774000000000E+01 +-.67281000000000E+01 +-.55820000000000E+01 +-.44430000000000E+01 +-.33141000000000E+01 +-.21998000000000E+01 +-.11045000000000E+01 +-.14780000000000E-01 +0.10822000000000E+01 +0.21614000000000E+01 +0.31578000000000E+01 +0.39400000000000E+01 +-.10318000000000E+02 +-.91670000000000E+01 +-.80161000000000E+01 +-.68665000000000E+01 +-.57192000000000E+01 +-.45775000000000E+01 +-.34447000000000E+01 +-.23257000000000E+01 +-.12258000000000E+01 +-.13246000000000E+00 +0.96939000000000E+00 +0.20601000000000E+01 +0.30787000000000E+01 +0.38879000000000E+01 +-.10427000000000E+02 +-.92759000000000E+01 +-.81250000000000E+01 +-.69749000000000E+01 +-.58267000000000E+01 +-.46830000000000E+01 +-.35467000000000E+01 +-.24233000000000E+01 +-.13186000000000E+01 +-.22109000000000E+00 +0.88507000000000E+00 +0.19847000000000E+01 +0.30219000000000E+01 +0.38639000000000E+01 +-.10564000000000E+02 +-.94133000000000E+01 +-.82622000000000E+01 +-.71118000000000E+01 +-.59630000000000E+01 +-.48175000000000E+01 +-.36783000000000E+01 +-.25505000000000E+01 +-.14404000000000E+01 +-.33891000000000E+00 +0.77025000000000E+00 +0.18762000000000E+01 +0.29295000000000E+01 +0.38079000000000E+01 +-.10676000000000E+02 +-.95251000000000E+01 +-.83740000000000E+01 +-.72234000000000E+01 +-.60740000000000E+01 +-.49272000000000E+01 +-.37856000000000E+01 +-.26542000000000E+01 +-.15393000000000E+01 +-.43389000000000E+00 +0.67815000000000E+00 +0.17895000000000E+01 +0.28572000000000E+01 +0.37733000000000E+01 +-.10838000000000E+02 +-.96865000000000E+01 +-.85354000000000E+01 +-.73846000000000E+01 +-.62347000000000E+01 +-.50869000000000E+01 +-.39432000000000E+01 +-.28080000000000E+01 +-.16882000000000E+01 +-.57916000000000E+00 +0.53461000000000E+00 +0.16499000000000E+01 +0.27304000000000E+01 +0.36833000000000E+01 +-.11039000000000E+02 +-.98872000000000E+01 +-.87361000000000E+01 +-.75852000000000E+01 +-.64349000000000E+01 +-.52863000000000E+01 +-.41409000000000E+01 +-.30024000000000E+01 +-.18775000000000E+01 +-.76491000000000E+00 +0.34992000000000E+00 +0.14680000000000E+01 +0.25598000000000E+01 +0.35471000000000E+01 +-.11185000000000E+02 +-.10034000000000E+02 +-.88826000000000E+01 +-.77316000000000E+01 +-.65811000000000E+01 +-.54318000000000E+01 +-.42850000000000E+01 +-.31443000000000E+01 +-.20158000000000E+01 +-.89987000000000E+00 +0.21655000000000E+00 +0.13375000000000E+01 +0.24394000000000E+01 +0.34577000000000E+01 +-.11359000000000E+02 +-.10208000000000E+02 +-.90566000000000E+01 +-.79056000000000E+01 +-.67549000000000E+01 +-.56051000000000E+01 +-.44574000000000E+01 +-.33146000000000E+01 +-.21826000000000E+01 +-.10635000000000E+01 +0.54111000000000E-01 +0.11770000000000E+01 +0.22874000000000E+01 +0.33326000000000E+01 +-.11571000000000E+02 +-.10420000000000E+02 +-.92688000000000E+01 +-.81174000000000E+01 +-.69668000000000E+01 +-.58167000000000E+01 +-.46681000000000E+01 +-.35235000000000E+01 +-.23881000000000E+01 +-.12655000000000E+01 +-.14706000000000E+00 +0.97684000000000E+00 +0.20937000000000E+01 +0.31616000000000E+01 +-.11812000000000E+02 +-.10660000000000E+02 +-.95088000000000E+01 +-.83577000000000E+01 +-.72068000000000E+01 +-.60564000000000E+01 +-.49072000000000E+01 +-.37610000000000E+01 +-.26226000000000E+01 +-.14965000000000E+01 +-.37701000000000E+00 +0.74706000000000E+00 +0.18689000000000E+01 +0.29549000000000E+01 +-.12073000000000E+02 +-.10922000000000E+02 +-.97705000000000E+01 +-.86191000000000E+01 +-.74683000000000E+01 +-.63176000000000E+01 +-.51678000000000E+01 +-.40205000000000E+01 +-.28793000000000E+01 +-.17496000000000E+01 +-.62871000000000E+00 +0.49498000000000E+00 +0.16200000000000E+01 +0.27203000000000E+01 +-.12294000000000E+02 +-.11143000000000E+02 +-.99917000000000E+01 +-.88403000000000E+01 +-.76893000000000E+01 +-.65386000000000E+01 +-.53884000000000E+01 +-.42402000000000E+01 +-.30971000000000E+01 +-.19644000000000E+01 +-.84174000000000E+00 +0.28184000000000E+00 +0.14091000000000E+01 +0.25204000000000E+01 +-.12510000000000E+02 +-.11359000000000E+02 +-.10208000000000E+02 +-.90562000000000E+01 +-.79052000000000E+01 +-.67543000000000E+01 +-.56039000000000E+01 +-.44550000000000E+01 +-.33104000000000E+01 +-.21749000000000E+01 +-.10503000000000E+01 +0.73132000000000E-01 +0.12016000000000E+01 +0.23212000000000E+01 +-.12756000000000E+02 +-.11605000000000E+02 +-.10453000000000E+02 +-.93020000000000E+01 +-.81509000000000E+01 +-.70000000000000E+01 +-.58494000000000E+01 +-.47000000000000E+01 +-.35539000000000E+01 +-.24158000000000E+01 +-.12888000000000E+01 +-.16551000000000E+00 +0.96312000000000E+00 +0.20884000000000E+01 +-.13021000000000E+02 +-.11869000000000E+02 +-.10718000000000E+02 +-.95669000000000E+01 +-.84158000000000E+01 +-.72648000000000E+01 +-.61139000000000E+01 +-.49641000000000E+01 +-.38168000000000E+01 +-.26762000000000E+01 +-.15465000000000E+01 +-.42302000000000E+00 +0.70496000000000E+00 +0.18337000000000E+01 +-.13296000000000E+02 +-.12145000000000E+02 +-.10993000000000E+02 +-.98418000000000E+01 +-.86907000000000E+01 +-.75396000000000E+01 +-.63887000000000E+01 +-.52384000000000E+01 +-.40902000000000E+01 +-.29474000000000E+01 +-.18148000000000E+01 +-.69054000000000E+00 +0.43638000000000E+00 +0.15670000000000E+01 +-.13499000000000E+02 +-.12348000000000E+02 +-.11197000000000E+02 +-.10045000000000E+02 +-.88938000000000E+01 +-.77428000000000E+01 +-.65918000000000E+01 +-.54414000000000E+01 +-.42926000000000E+01 +-.31484000000000E+01 +-.20135000000000E+01 +-.88815000000000E+00 +0.23822000000000E+00 +0.13701000000000E+01 +-.13718000000000E+02 +-.12566000000000E+02 +-.11415000000000E+02 +-.10264000000000E+02 +-.91125000000000E+01 +-.79613000000000E+01 +-.68103000000000E+01 +-.56597000000000E+01 +-.45104000000000E+01 +-.33650000000000E+01 +-.22278000000000E+01 +-.11010000000000E+01 +0.24762000000000E-01 +0.11568000000000E+01 +-.13958000000000E+02 +-.12806000000000E+02 +-.11655000000000E+02 +-.10504000000000E+02 +-.93525000000000E+01 +-.82012000000000E+01 +-.70503000000000E+01 +-.58994000000000E+01 +-.47498000000000E+01 +-.36032000000000E+01 +-.24639000000000E+01 +-.13350000000000E+01 +-.20980000000000E+00 +0.92159000000000E+00 +-.14210000000000E+02 +-.13058000000000E+02 +-.11907000000000E+02 +-.10756000000000E+02 +-.96045000000000E+01 +-.84534000000000E+01 +-.73022000000000E+01 +-.61514000000000E+01 +-.50013000000000E+01 +-.38538000000000E+01 +-.27123000000000E+01 +-.15812000000000E+01 +-.45611000000000E+00 +0.67409000000000E+00 +-.14467000000000E+02 +-.13316000000000E+02 +-.12165000000000E+02 +-.11013000000000E+02 +-.98621000000000E+01 +-.87109000000000E+01 +-.75598000000000E+01 +-.64088000000000E+01 +-.52585000000000E+01 +-.41101000000000E+01 +-.29669000000000E+01 +-.18332000000000E+01 +-.70761000000000E+00 +0.42113000000000E+00 +-.14725000000000E+02 +-.13574000000000E+02 +-.12423000000000E+02 +-.11271000000000E+02 +-.10120000000000E+02 +-.89687000000000E+01 +-.78176000000000E+01 +-.66665000000000E+01 +-.55160000000000E+01 +-.43669000000000E+01 +-.32222000000000E+01 +-.20860000000000E+01 +-.95932000000000E+00 +0.16807000000000E+00 +-.10359000000000E+02 +-.92112000000000E+01 +-.80676000000000E+01 +-.69369000000000E+01 +-.58383000000000E+01 +-.47969000000000E+01 +-.37930000000000E+01 +-.27532000000000E+01 +-.16648000000000E+01 +-.59343000000000E+00 +0.37721000000000E+00 +0.12238000000000E+01 +0.20113000000000E+01 +0.27836000000000E+01 +-.10600000000000E+02 +-.94507000000000E+01 +-.83052000000000E+01 +-.71699000000000E+01 +-.60602000000000E+01 +-.49956000000000E+01 +-.39605000000000E+01 +-.28986000000000E+01 +-.18014000000000E+01 +-.71957000000000E+00 +0.27684000000000E+00 +0.11473000000000E+01 +0.19426000000000E+01 +0.27164000000000E+01 +-.10687000000000E+02 +-.95371000000000E+01 +-.83899000000000E+01 +-.72499000000000E+01 +-.61281000000000E+01 +-.50381000000000E+01 +-.39683000000000E+01 +-.28801000000000E+01 +-.17705000000000E+01 +-.67690000000000E+00 +0.34438000000000E+00 +0.12434000000000E+01 +0.20505000000000E+01 +0.28269000000000E+01 +-.10815000000000E+02 +-.96648000000000E+01 +-.85166000000000E+01 +-.73739000000000E+01 +-.62452000000000E+01 +-.51411000000000E+01 +-.40521000000000E+01 +-.29495000000000E+01 +-.18316000000000E+01 +-.72705000000000E+00 +0.31927000000000E+00 +0.12525000000000E+01 +0.20780000000000E+01 +0.28588000000000E+01 +-.10989000000000E+02 +-.98389000000000E+01 +-.86899000000000E+01 +-.75452000000000E+01 +-.64111000000000E+01 +-.52958000000000E+01 +-.41919000000000E+01 +-.30782000000000E+01 +-.19546000000000E+01 +-.84315000000000E+00 +0.22109000000000E+00 +0.11858000000000E+01 +0.20342000000000E+01 +0.28216000000000E+01 +-.11145000000000E+02 +-.99939000000000E+01 +-.88442000000000E+01 +-.76979000000000E+01 +-.65594000000000E+01 +-.54352000000000E+01 +-.43196000000000E+01 +-.31971000000000E+01 +-.20688000000000E+01 +-.95219000000000E+00 +0.12666000000000E+00 +0.11215000000000E+01 +0.19982000000000E+01 +0.27958000000000E+01 +-.11283000000000E+02 +-.10133000000000E+02 +-.89827000000000E+01 +-.78350000000000E+01 +-.66934000000000E+01 +-.55621000000000E+01 +-.44376000000000E+01 +-.33087000000000E+01 +-.21768000000000E+01 +-.10560000000000E+01 +0.34715000000000E-01 +0.10574000000000E+01 +0.19668000000000E+01 +0.27792000000000E+01 +-.11422000000000E+02 +-.10271000000000E+02 +-.91211000000000E+01 +-.79724000000000E+01 +-.68284000000000E+01 +-.56923000000000E+01 +-.45613000000000E+01 +-.34274000000000E+01 +-.22928000000000E+01 +-.11686000000000E+01 +-.68327000000000E-01 +0.97881000000000E+00 +0.19230000000000E+01 +0.27552000000000E+01 +-.11524000000000E+02 +-.10374000000000E+02 +-.92229000000000E+01 +-.80735000000000E+01 +-.69276000000000E+01 +-.57876000000000E+01 +-.46514000000000E+01 +-.35136000000000E+01 +-.23767000000000E+01 +-.12497000000000E+01 +-.14168000000000E+00 +0.92621000000000E+00 +0.19049000000000E+01 +0.27607000000000E+01 +-.11617000000000E+02 +-.10466000000000E+02 +-.93157000000000E+01 +-.81658000000000E+01 +-.70184000000000E+01 +-.58755000000000E+01 +-.47355000000000E+01 +-.35948000000000E+01 +-.24560000000000E+01 +-.13265000000000E+01 +-.21231000000000E+00 +0.87238000000000E+00 +0.18827000000000E+01 +0.27641000000000E+01 +-.11702000000000E+02 +-.10551000000000E+02 +-.93997000000000E+01 +-.82493000000000E+01 +-.71011000000000E+01 +-.59558000000000E+01 +-.48130000000000E+01 +-.36701000000000E+01 +-.25297000000000E+01 +-.13981000000000E+01 +-.27896000000000E+00 +0.81873000000000E+00 +0.18558000000000E+01 +0.27631000000000E+01 +-.11786000000000E+02 +-.10635000000000E+02 +-.94839000000000E+01 +-.83335000000000E+01 +-.71843000000000E+01 +-.60376000000000E+01 +-.48927000000000E+01 +-.37480000000000E+01 +-.26062000000000E+01 +-.14726000000000E+01 +-.34952000000000E+00 +0.75780000000000E+00 +0.18161000000000E+01 +0.27484000000000E+01 +-.11868000000000E+02 +-.10717000000000E+02 +-.95659000000000E+01 +-.84150000000000E+01 +-.72655000000000E+01 +-.61176000000000E+01 +-.49709000000000E+01 +-.38250000000000E+01 +-.26818000000000E+01 +-.15463000000000E+01 +-.42010000000000E+00 +0.69421000000000E+00 +0.17687000000000E+01 +0.27253000000000E+01 +-.11958000000000E+02 +-.10806000000000E+02 +-.96550000000000E+01 +-.85042000000000E+01 +-.73541000000000E+01 +-.62053000000000E+01 +-.50576000000000E+01 +-.39106000000000E+01 +-.27663000000000E+01 +-.16289000000000E+01 +-.50003000000000E+00 +0.61937000000000E+00 +0.17061000000000E+01 +0.26863000000000E+01 +-.12088000000000E+02 +-.10937000000000E+02 +-.97854000000000E+01 +-.86345000000000E+01 +-.74841000000000E+01 +-.63347000000000E+01 +-.51862000000000E+01 +-.40381000000000E+01 +-.28926000000000E+01 +-.17534000000000E+01 +-.62209000000000E+00 +0.50104000000000E+00 +0.15973000000000E+01 +0.26002000000000E+01 +-.12180000000000E+02 +-.11029000000000E+02 +-.98779000000000E+01 +-.87271000000000E+01 +-.75763000000000E+01 +-.64264000000000E+01 +-.52771000000000E+01 +-.41284000000000E+01 +-.29820000000000E+01 +-.18412000000000E+01 +-.70787000000000E+00 +0.41850000000000E+00 +0.15229000000000E+01 +0.25477000000000E+01 +-.12332000000000E+02 +-.11180000000000E+02 +-.10029000000000E+02 +-.88779000000000E+01 +-.77273000000000E+01 +-.65769000000000E+01 +-.54271000000000E+01 +-.42780000000000E+01 +-.31306000000000E+01 +-.19882000000000E+01 +-.85278000000000E+00 +0.27617000000000E+00 +0.13875000000000E+01 +0.24326000000000E+01 +-.12522000000000E+02 +-.11371000000000E+02 +-.10220000000000E+02 +-.90686000000000E+01 +-.79178000000000E+01 +-.67672000000000E+01 +-.56171000000000E+01 +-.44674000000000E+01 +-.33192000000000E+01 +-.21752000000000E+01 +-.10378000000000E+01 +0.93302000000000E-01 +0.12105000000000E+01 +0.22742000000000E+01 +-.12651000000000E+02 +-.11500000000000E+02 +-.10349000000000E+02 +-.91975000000000E+01 +-.80464000000000E+01 +-.68958000000000E+01 +-.57452000000000E+01 +-.45952000000000E+01 +-.34465000000000E+01 +-.23014000000000E+01 +-.11624000000000E+01 +-.29050000000000E-01 +0.10935000000000E+01 +0.21738000000000E+01 +-.12824000000000E+02 +-.11673000000000E+02 +-.10522000000000E+02 +-.93706000000000E+01 +-.82195000000000E+01 +-.70687000000000E+01 +-.59181000000000E+01 +-.47677000000000E+01 +-.36185000000000E+01 +-.24723000000000E+01 +-.13317000000000E+01 +-.19657000000000E+00 +0.93033000000000E+00 +0.20248000000000E+01 +-.13036000000000E+02 +-.11885000000000E+02 +-.10734000000000E+02 +-.95823000000000E+01 +-.84312000000000E+01 +-.72802000000000E+01 +-.61294000000000E+01 +-.49788000000000E+01 +-.38291000000000E+01 +-.26819000000000E+01 +-.15398000000000E+01 +-.40302000000000E+00 +0.72733000000000E+00 +0.18336000000000E+01 +-.13276000000000E+02 +-.12125000000000E+02 +-.10973000000000E+02 +-.98220000000000E+01 +-.86709000000000E+01 +-.75198000000000E+01 +-.63689000000000E+01 +-.52181000000000E+01 +-.40680000000000E+01 +-.29200000000000E+01 +-.17764000000000E+01 +-.63808000000000E+00 +0.49493000000000E+00 +0.16104000000000E+01 +-.13537000000000E+02 +-.12385000000000E+02 +-.11234000000000E+02 +-.10083000000000E+02 +-.89316000000000E+01 +-.77805000000000E+01 +-.66294000000000E+01 +-.54785000000000E+01 +-.43281000000000E+01 +-.31794000000000E+01 +-.20344000000000E+01 +-.89455000000000E+00 +0.24051000000000E+00 +0.13632000000000E+01 +-.13745000000000E+02 +-.12593000000000E+02 +-.11442000000000E+02 +-.10291000000000E+02 +-.91394000000000E+01 +-.79883000000000E+01 +-.68372000000000E+01 +-.56862000000000E+01 +-.45356000000000E+01 +-.33864000000000E+01 +-.22403000000000E+01 +-.10992000000000E+01 +0.37641000000000E-01 +0.11659000000000E+01 +-.13958000000000E+02 +-.12807000000000E+02 +-.11656000000000E+02 +-.10504000000000E+02 +-.93530000000000E+01 +-.82017000000000E+01 +-.70507000000000E+01 +-.58995000000000E+01 +-.47489000000000E+01 +-.35992000000000E+01 +-.24522000000000E+01 +-.13098000000000E+01 +-.17163000000000E+00 +0.96065000000000E+00 +-.14197000000000E+02 +-.13046000000000E+02 +-.11894000000000E+02 +-.10743000000000E+02 +-.95918000000000E+01 +-.84404000000000E+01 +-.72894000000000E+01 +-.61383000000000E+01 +-.49874000000000E+01 +-.38375000000000E+01 +-.26896000000000E+01 +-.15460000000000E+01 +-.40664000000000E+00 +0.72847000000000E+00 +-.14454000000000E+02 +-.13302000000000E+02 +-.12151000000000E+02 +-.11000000000000E+02 +-.98484000000000E+01 +-.86973000000000E+01 +-.75460000000000E+01 +-.63949000000000E+01 +-.52439000000000E+01 +-.40936000000000E+01 +-.29451000000000E+01 +-.18003000000000E+01 +-.65982000000000E+00 +0.47722000000000E+00 +-.14721000000000E+02 +-.13570000000000E+02 +-.12419000000000E+02 +-.11268000000000E+02 +-.10116000000000E+02 +-.89651000000000E+01 +-.78140000000000E+01 +-.66627000000000E+01 +-.55117000000000E+01 +-.43612000000000E+01 +-.32120000000000E+01 +-.20661000000000E+01 +-.92456000000000E+00 +0.21381000000000E+00 +-.14905000000000E+02 +-.13754000000000E+02 +-.12603000000000E+02 +-.11451000000000E+02 +-.10300000000000E+02 +-.91489000000000E+01 +-.79977000000000E+01 +-.68464000000000E+01 +-.56954000000000E+01 +-.45447000000000E+01 +-.33952000000000E+01 +-.22485000000000E+01 +-.11061000000000E+01 +0.33411000000000E-01 +-.15115000000000E+02 +-.13964000000000E+02 +-.12813000000000E+02 +-.11661000000000E+02 +-.10510000000000E+02 +-.93589000000000E+01 +-.82075000000000E+01 +-.70564000000000E+01 +-.59053000000000E+01 +-.47545000000000E+01 +-.36047000000000E+01 +-.24573000000000E+01 +-.13139000000000E+01 +-.17360000000000E+00 +-.15343000000000E+02 +-.14192000000000E+02 +-.13040000000000E+02 +-.11889000000000E+02 +-.10738000000000E+02 +-.95864000000000E+01 +-.84353000000000E+01 +-.72841000000000E+01 +-.61329000000000E+01 +-.49819000000000E+01 +-.38319000000000E+01 +-.26838000000000E+01 +-.15395000000000E+01 +-.39848000000000E+00 +-.15579000000000E+02 +-.14427000000000E+02 +-.13276000000000E+02 +-.12125000000000E+02 +-.10974000000000E+02 +-.98225000000000E+01 +-.86711000000000E+01 +-.75199000000000E+01 +-.63688000000000E+01 +-.52178000000000E+01 +-.40674000000000E+01 +-.29188000000000E+01 +-.17735000000000E+01 +-.63184000000000E+00 +-.11290000000000E+02 +-.10142000000000E+02 +-.89978000000000E+01 +-.78658000000000E+01 +-.67644000000000E+01 +-.57167000000000E+01 +-.47031000000000E+01 +-.36550000000000E+01 +-.25621000000000E+01 +-.14887000000000E+01 +-.51730000000000E+00 +0.32940000000000E+00 +0.11169000000000E+01 +0.18893000000000E+01 +-.11520000000000E+02 +-.10371000000000E+02 +-.92253000000000E+01 +-.80891000000000E+01 +-.69767000000000E+01 +-.59065000000000E+01 +-.48632000000000E+01 +-.37942000000000E+01 +-.26929000000000E+01 +-.16088000000000E+01 +-.61131000000000E+00 +0.25947000000000E+00 +0.10547000000000E+01 +0.18286000000000E+01 +-.11737000000000E+02 +-.10588000000000E+02 +-.94407000000000E+01 +-.83010000000000E+01 +-.71804000000000E+01 +-.60929000000000E+01 +-.50262000000000E+01 +-.39401000000000E+01 +-.28301000000000E+01 +-.17347000000000E+01 +-.71187000000000E+00 +0.18771000000000E+00 +0.99487000000000E+00 +0.17711000000000E+01 +-.11849000000000E+02 +-.10699000000000E+02 +-.95505000000000E+01 +-.84080000000000E+01 +-.72799000000000E+01 +-.61768000000000E+01 +-.50891000000000E+01 +-.39868000000000E+01 +-.28672000000000E+01 +-.17597000000000E+01 +-.71146000000000E+00 +0.22206000000000E+00 +0.10474000000000E+01 +0.18281000000000E+01 +-.11968000000000E+02 +-.10817000000000E+02 +-.96685000000000E+01 +-.85237000000000E+01 +-.73894000000000E+01 +-.62737000000000E+01 +-.51691000000000E+01 +-.40538000000000E+01 +-.29269000000000E+01 +-.18108000000000E+01 +-.74295000000000E+00 +0.22272000000000E+00 +0.10711000000000E+01 +0.18583000000000E+01 +-.12115000000000E+02 +-.10965000000000E+02 +-.98149000000000E+01 +-.86685000000000E+01 +-.75302000000000E+01 +-.64056000000000E+01 +-.52896000000000E+01 +-.41655000000000E+01 +-.30333000000000E+01 +-.19101000000000E+01 +-.82591000000000E+00 +0.17068000000000E+00 +0.10474000000000E+01 +0.18450000000000E+01 +-.12242000000000E+02 +-.11091000000000E+02 +-.99412000000000E+01 +-.87935000000000E+01 +-.76517000000000E+01 +-.65204000000000E+01 +-.53951000000000E+01 +-.42643000000000E+01 +-.31277000000000E+01 +-.19990000000000E+01 +-.90144000000000E+00 +0.12337000000000E+00 +0.10327000000000E+01 +0.18458000000000E+01 +-.12351000000000E+02 +-.11200000000000E+02 +-.10050000000000E+02 +-.89009000000000E+01 +-.77567000000000E+01 +-.66201000000000E+01 +-.54882000000000E+01 +-.43519000000000E+01 +-.32122000000000E+01 +-.20790000000000E+01 +-.97084000000000E+00 +0.78825000000000E-01 +0.10229000000000E+01 +0.18577000000000E+01 +-.12458000000000E+02 +-.11307000000000E+02 +-.10156000000000E+02 +-.90073000000000E+01 +-.78613000000000E+01 +-.67209000000000E+01 +-.55840000000000E+01 +-.44441000000000E+01 +-.33018000000000E+01 +-.21652000000000E+01 +-.10485000000000E+01 +0.22096000000000E-01 +0.10009000000000E+01 +0.18631000000000E+01 +-.12537000000000E+02 +-.11386000000000E+02 +-.10235000000000E+02 +-.90854000000000E+01 +-.79380000000000E+01 +-.67947000000000E+01 +-.56539000000000E+01 +-.45111000000000E+01 +-.33669000000000E+01 +-.22278000000000E+01 +-.11045000000000E+01 +-.16798000000000E-01 +0.99449000000000E+00 +0.18881000000000E+01 +-.12610000000000E+02 +-.11458000000000E+02 +-.10307000000000E+02 +-.91572000000000E+01 +-.80088000000000E+01 +-.68633000000000E+01 +-.57197000000000E+01 +-.45748000000000E+01 +-.34292000000000E+01 +-.22880000000000E+01 +-.11597000000000E+01 +-.58628000000000E-01 +0.98097000000000E+00 +0.19073000000000E+01 +-.12670000000000E+02 +-.11519000000000E+02 +-.10368000000000E+02 +-.92175000000000E+01 +-.80684000000000E+01 +-.69213000000000E+01 +-.57756000000000E+01 +-.46290000000000E+01 +-.34824000000000E+01 +-.23397000000000E+01 +-.12076000000000E+01 +-.96302000000000E-01 +0.96648000000000E+00 +0.19238000000000E+01 +-.12738000000000E+02 +-.11587000000000E+02 +-.10436000000000E+02 +-.92852000000000E+01 +-.81355000000000E+01 +-.69873000000000E+01 +-.58401000000000E+01 +-.46925000000000E+01 +-.35449000000000E+01 +-.24009000000000E+01 +-.12659000000000E+01 +-.14715000000000E+00 +0.93344000000000E+00 +0.19182000000000E+01 +-.12829000000000E+02 +-.11678000000000E+02 +-.10527000000000E+02 +-.93760000000000E+01 +-.82258000000000E+01 +-.70770000000000E+01 +-.59288000000000E+01 +-.47804000000000E+01 +-.36321000000000E+01 +-.24871000000000E+01 +-.13497000000000E+01 +-.22548000000000E+00 +0.86821000000000E+00 +0.18763000000000E+01 +-.12904000000000E+02 +-.11753000000000E+02 +-.10602000000000E+02 +-.94507000000000E+01 +-.83000000000000E+01 +-.71506000000000E+01 +-.60016000000000E+01 +-.48524000000000E+01 +-.37037000000000E+01 +-.25577000000000E+01 +-.14185000000000E+01 +-.29027000000000E+00 +0.81308000000000E+00 +0.18411000000000E+01 +-.13017000000000E+02 +-.11866000000000E+02 +-.10715000000000E+02 +-.95637000000000E+01 +-.84131000000000E+01 +-.72632000000000E+01 +-.61135000000000E+01 +-.49639000000000E+01 +-.38146000000000E+01 +-.26678000000000E+01 +-.15269000000000E+01 +-.39562000000000E+00 +0.71498000000000E+00 +0.17605000000000E+01 +-.13108000000000E+02 +-.11957000000000E+02 +-.10806000000000E+02 +-.96548000000000E+01 +-.85039000000000E+01 +-.73536000000000E+01 +-.62036000000000E+01 +-.50535000000000E+01 +-.39039000000000E+01 +-.27565000000000E+01 +-.16141000000000E+01 +-.48027000000000E+00 +0.63631000000000E+00 +0.16977000000000E+01 +-.13243000000000E+02 +-.12092000000000E+02 +-.10940000000000E+02 +-.97893000000000E+01 +-.86382000000000E+01 +-.74877000000000E+01 +-.63373000000000E+01 +-.51870000000000E+01 +-.40370000000000E+01 +-.28889000000000E+01 +-.17452000000000E+01 +-.60913000000000E+00 +0.51245000000000E+00 +0.15882000000000E+01 +-.13423000000000E+02 +-.12272000000000E+02 +-.11121000000000E+02 +-.99692000000000E+01 +-.88184000000000E+01 +-.76675000000000E+01 +-.65168000000000E+01 +-.53663000000000E+01 +-.42161000000000E+01 +-.30673000000000E+01 +-.19224000000000E+01 +-.78421000000000E+00 +0.34168000000000E+00 +0.14303000000000E+01 +-.13557000000000E+02 +-.12406000000000E+02 +-.11254000000000E+02 +-.10103000000000E+02 +-.89521000000000E+01 +-.78011000000000E+01 +-.66504000000000E+01 +-.54996000000000E+01 +-.43491000000000E+01 +-.32000000000000E+01 +-.20540000000000E+01 +-.91406000000000E+00 +0.21574000000000E+00 +0.13159000000000E+01 +-.13719000000000E+02 +-.12568000000000E+02 +-.11417000000000E+02 +-.10265000000000E+02 +-.91143000000000E+01 +-.79633000000000E+01 +-.68123000000000E+01 +-.56614000000000E+01 +-.45107000000000E+01 +-.33611000000000E+01 +-.22143000000000E+01 +-.10727000000000E+01 +0.60430000000000E-01 +0.11704000000000E+01 +-.13923000000000E+02 +-.12771000000000E+02 +-.11620000000000E+02 +-.10469000000000E+02 +-.93176000000000E+01 +-.81665000000000E+01 +-.70155000000000E+01 +-.58645000000000E+01 +-.47136000000000E+01 +-.35638000000000E+01 +-.24161000000000E+01 +-.12729000000000E+01 +-.13700000000000E+00 +0.98117000000000E+00 +-.14156000000000E+02 +-.13005000000000E+02 +-.11853000000000E+02 +-.10702000000000E+02 +-.95508000000000E+01 +-.83997000000000E+01 +-.72485000000000E+01 +-.60975000000000E+01 +-.49465000000000E+01 +-.37963000000000E+01 +-.26479000000000E+01 +-.15034000000000E+01 +-.36509000000000E+00 +0.75963000000000E+00 +-.14411000000000E+02 +-.13260000000000E+02 +-.12108000000000E+02 +-.10957000000000E+02 +-.98059000000000E+01 +-.86548000000000E+01 +-.75037000000000E+01 +-.63525000000000E+01 +-.52015000000000E+01 +-.40510000000000E+01 +-.29020000000000E+01 +-.17562000000000E+01 +-.61592000000000E+00 +0.51392000000000E+00 +-.14624000000000E+02 +-.13473000000000E+02 +-.12322000000000E+02 +-.11170000000000E+02 +-.10019000000000E+02 +-.88679000000000E+01 +-.77169000000000E+01 +-.65657000000000E+01 +-.54147000000000E+01 +-.42639000000000E+01 +-.31145000000000E+01 +-.19677000000000E+01 +-.82571000000000E+00 +0.30817000000000E+00 +-.14826000000000E+02 +-.13674000000000E+02 +-.12523000000000E+02 +-.11372000000000E+02 +-.10221000000000E+02 +-.90693000000000E+01 +-.79182000000000E+01 +-.67670000000000E+01 +-.56158000000000E+01 +-.44651000000000E+01 +-.33152000000000E+01 +-.21676000000000E+01 +-.10242000000000E+01 +0.11277000000000E+00 +-.15056000000000E+02 +-.13905000000000E+02 +-.12753000000000E+02 +-.11602000000000E+02 +-.10451000000000E+02 +-.92993000000000E+01 +-.81482000000000E+01 +-.69971000000000E+01 +-.58458000000000E+01 +-.46949000000000E+01 +-.35448000000000E+01 +-.23965000000000E+01 +-.12519000000000E+01 +-.11250000000000E+00 +-.15304000000000E+02 +-.14153000000000E+02 +-.13002000000000E+02 +-.11850000000000E+02 +-.10699000000000E+02 +-.95479000000000E+01 +-.83965000000000E+01 +-.72454000000000E+01 +-.60942000000000E+01 +-.49432000000000E+01 +-.37928000000000E+01 +-.26439000000000E+01 +-.14982000000000E+01 +-.35699000000000E+00 +-.15564000000000E+02 +-.14413000000000E+02 +-.13261000000000E+02 +-.12110000000000E+02 +-.10959000000000E+02 +-.98074000000000E+01 +-.86562000000000E+01 +-.75050000000000E+01 +-.63538000000000E+01 +-.52028000000000E+01 +-.40521000000000E+01 +-.29027000000000E+01 +-.17560000000000E+01 +-.61333000000000E+00 +-.15752000000000E+02 +-.14601000000000E+02 +-.13450000000000E+02 +-.12299000000000E+02 +-.11147000000000E+02 +-.99958000000000E+01 +-.88447000000000E+01 +-.76935000000000E+01 +-.65422000000000E+01 +-.53911000000000E+01 +-.42404000000000E+01 +-.30906000000000E+01 +-.19432000000000E+01 +-.79938000000000E+00 +-.15949000000000E+02 +-.14797000000000E+02 +-.13646000000000E+02 +-.12495000000000E+02 +-.11344000000000E+02 +-.10192000000000E+02 +-.90410000000000E+01 +-.78896000000000E+01 +-.67384000000000E+01 +-.55873000000000E+01 +-.44364000000000E+01 +-.32864000000000E+01 +-.21384000000000E+01 +-.99359000000000E+00 +-.16163000000000E+02 +-.15011000000000E+02 +-.13860000000000E+02 +-.12709000000000E+02 +-.11557000000000E+02 +-.10406000000000E+02 +-.92549000000000E+01 +-.81035000000000E+01 +-.69524000000000E+01 +-.58013000000000E+01 +-.46503000000000E+01 +-.35000000000000E+01 +-.23514000000000E+01 +-.12058000000000E+01 +-.12008000000000E+02 +-.10859000000000E+02 +-.97151000000000E+01 +-.85823000000000E+01 +-.74785000000000E+01 +-.64257000000000E+01 +-.54043000000000E+01 +-.43497000000000E+01 +-.32535000000000E+01 +-.21788000000000E+01 +-.12069000000000E+01 +-.35999000000000E+00 +0.42760000000000E+00 +0.12000000000000E+01 +-.12231000000000E+02 +-.11082000000000E+02 +-.99355000000000E+01 +-.87983000000000E+01 +-.76841000000000E+01 +-.66094000000000E+01 +-.55594000000000E+01 +-.44851000000000E+01 +-.33811000000000E+01 +-.22956000000000E+01 +-.12974000000000E+01 +-.42632000000000E+00 +0.36904000000000E+00 +0.11429000000000E+01 +-.12440000000000E+02 +-.11291000000000E+02 +-.10144000000000E+02 +-.90032000000000E+01 +-.78806000000000E+01 +-.67892000000000E+01 +-.57170000000000E+01 +-.46265000000000E+01 +-.35141000000000E+01 +-.24172000000000E+01 +-.13935000000000E+01 +-.49335000000000E+00 +0.31396000000000E+00 +0.10903000000000E+01 +-.12667000000000E+02 +-.11517000000000E+02 +-.10369000000000E+02 +-.92268000000000E+01 +-.80994000000000E+01 +-.69973000000000E+01 +-.59113000000000E+01 +-.48098000000000E+01 +-.36904000000000E+01 +-.25822000000000E+01 +-.15328000000000E+01 +-.59875000000000E+00 +0.22667000000000E+00 +0.10072000000000E+01 +-.12775000000000E+02 +-.11625000000000E+02 +-.10476000000000E+02 +-.93313000000000E+01 +-.81973000000000E+01 +-.70823000000000E+01 +-.59785000000000E+01 +-.48638000000000E+01 +-.37366000000000E+01 +-.26190000000000E+01 +-.15493000000000E+01 +-.58260000000000E+00 +0.26584000000000E+00 +0.10529000000000E+01 +-.12879000000000E+02 +-.11728000000000E+02 +-.10579000000000E+02 +-.94321000000000E+01 +-.82937000000000E+01 +-.71689000000000E+01 +-.60524000000000E+01 +-.49279000000000E+01 +-.37946000000000E+01 +-.26694000000000E+01 +-.15826000000000E+01 +-.58453000000000E+00 +0.29227000000000E+00 +0.10896000000000E+01 +-.13011000000000E+02 +-.11861000000000E+02 +-.10710000000000E+02 +-.95630000000000E+01 +-.84211000000000E+01 +-.72899000000000E+01 +-.61647000000000E+01 +-.50333000000000E+01 +-.38959000000000E+01 +-.27647000000000E+01 +-.16640000000000E+01 +-.63737000000000E+00 +0.27180000000000E+00 +0.10844000000000E+01 +-.13118000000000E+02 +-.11967000000000E+02 +-.10816000000000E+02 +-.96677000000000E+01 +-.85234000000000E+01 +-.73868000000000E+01 +-.62548000000000E+01 +-.51183000000000E+01 +-.39774000000000E+01 +-.28416000000000E+01 +-.17298000000000E+01 +-.67842000000000E+00 +0.26517000000000E+00 +0.10991000000000E+01 +-.13209000000000E+02 +-.12058000000000E+02 +-.10908000000000E+02 +-.97583000000000E+01 +-.86123000000000E+01 +-.74718000000000E+01 +-.63345000000000E+01 +-.51941000000000E+01 +-.40507000000000E+01 +-.29114000000000E+01 +-.17910000000000E+01 +-.71878000000000E+00 +0.25916000000000E+00 +0.11206000000000E+01 +-.13304000000000E+02 +-.12153000000000E+02 +-.11002000000000E+02 +-.98523000000000E+01 +-.87048000000000E+01 +-.75614000000000E+01 +-.64205000000000E+01 +-.52772000000000E+01 +-.41320000000000E+01 +-.29902000000000E+01 +-.18631000000000E+01 +-.77383000000000E+00 +0.23629000000000E+00 +0.11302000000000E+01 +-.13370000000000E+02 +-.12219000000000E+02 +-.11068000000000E+02 +-.99177000000000E+01 +-.87693000000000E+01 +-.76238000000000E+01 +-.64800000000000E+01 +-.53346000000000E+01 +-.41879000000000E+01 +-.30441000000000E+01 +-.19121000000000E+01 +-.80939000000000E+00 +0.22924000000000E+00 +0.11583000000000E+01 +-.13433000000000E+02 +-.12281000000000E+02 +-.11130000000000E+02 +-.99797000000000E+01 +-.88306000000000E+01 +-.76835000000000E+01 +-.65377000000000E+01 +-.53907000000000E+01 +-.42429000000000E+01 +-.30978000000000E+01 +-.19620000000000E+01 +-.84897000000000E+00 +0.21350000000000E+00 +0.11771000000000E+01 +-.13487000000000E+02 +-.12335000000000E+02 +-.11184000000000E+02 +-.10034000000000E+02 +-.88838000000000E+01 +-.77356000000000E+01 +-.65883000000000E+01 +-.54402000000000E+01 +-.42916000000000E+01 +-.31453000000000E+01 +-.20067000000000E+01 +-.88602000000000E+00 +0.19535000000000E+00 +0.11901000000000E+01 +-.13565000000000E+02 +-.12414000000000E+02 +-.11263000000000E+02 +-.10112000000000E+02 +-.89617000000000E+01 +-.78127000000000E+01 +-.66644000000000E+01 +-.55156000000000E+01 +-.43665000000000E+01 +-.32193000000000E+01 +-.20785000000000E+01 +-.95206000000000E+00 +0.14349000000000E+00 +0.11643000000000E+01 +-.13654000000000E+02 +-.12503000000000E+02 +-.11352000000000E+02 +-.10201000000000E+02 +-.90500000000000E+01 +-.79006000000000E+01 +-.67515000000000E+01 +-.56021000000000E+01 +-.44525000000000E+01 +-.33046000000000E+01 +-.21621000000000E+01 +-.10314000000000E+01 +0.74423000000000E-01 +0.11161000000000E+01 +-.13720000000000E+02 +-.12569000000000E+02 +-.11418000000000E+02 +-.10267000000000E+02 +-.91162000000000E+01 +-.79662000000000E+01 +-.68164000000000E+01 +-.56665000000000E+01 +-.45166000000000E+01 +-.33682000000000E+01 +-.22244000000000E+01 +-.10906000000000E+01 +0.22800000000000E-01 +0.10812000000000E+01 +-.13828000000000E+02 +-.12677000000000E+02 +-.11525000000000E+02 +-.10374000000000E+02 +-.92234000000000E+01 +-.80730000000000E+01 +-.69230000000000E+01 +-.57727000000000E+01 +-.46226000000000E+01 +-.34736000000000E+01 +-.23287000000000E+01 +-.11923000000000E+01 +-.73227000000000E-01 +0.99899000000000E+00 +-.13915000000000E+02 +-.12764000000000E+02 +-.11613000000000E+02 +-.10461000000000E+02 +-.93103000000000E+01 +-.81597000000000E+01 +-.70093000000000E+01 +-.58588000000000E+01 +-.47084000000000E+01 +-.35591000000000E+01 +-.24132000000000E+01 +-.12748000000000E+01 +-.15108000000000E+00 +0.93312000000000E+00 +-.14046000000000E+02 +-.12895000000000E+02 +-.11744000000000E+02 +-.10593000000000E+02 +-.94414000000000E+01 +-.82908000000000E+01 +-.71401000000000E+01 +-.59894000000000E+01 +-.48387000000000E+01 +-.36891000000000E+01 +-.25424000000000E+01 +-.14020000000000E+01 +-.27436000000000E+00 +0.82037000000000E+00 +-.14223000000000E+02 +-.13072000000000E+02 +-.11921000000000E+02 +-.10769000000000E+02 +-.96182000000000E+01 +-.84673000000000E+01 +-.73165000000000E+01 +-.61656000000000E+01 +-.50149000000000E+01 +-.38649000000000E+01 +-.27173000000000E+01 +-.15752000000000E+01 +-.44404000000000E+00 +0.66002000000000E+00 +-.14353000000000E+02 +-.13202000000000E+02 +-.12051000000000E+02 +-.10899000000000E+02 +-.97483000000000E+01 +-.85972000000000E+01 +-.74462000000000E+01 +-.62953000000000E+01 +-.51444000000000E+01 +-.39942000000000E+01 +-.28459000000000E+01 +-.17024000000000E+01 +-.56810000000000E+00 +0.54430000000000E+00 +-.14513000000000E+02 +-.13362000000000E+02 +-.12211000000000E+02 +-.11060000000000E+02 +-.99082000000000E+01 +-.87571000000000E+01 +-.76062000000000E+01 +-.64552000000000E+01 +-.53042000000000E+01 +-.41538000000000E+01 +-.30049000000000E+01 +-.18601000000000E+01 +-.72307000000000E+00 +0.39647000000000E+00 +-.14715000000000E+02 +-.13564000000000E+02 +-.12412000000000E+02 +-.11261000000000E+02 +-.10110000000000E+02 +-.89587000000000E+01 +-.78076000000000E+01 +-.66565000000000E+01 +-.55055000000000E+01 +-.43549000000000E+01 +-.32055000000000E+01 +-.20594000000000E+01 +-.92001000000000E+00 +0.20546000000000E+00 +-.14946000000000E+02 +-.13795000000000E+02 +-.12643000000000E+02 +-.11492000000000E+02 +-.10341000000000E+02 +-.91897000000000E+01 +-.80383000000000E+01 +-.68873000000000E+01 +-.57362000000000E+01 +-.45854000000000E+01 +-.34357000000000E+01 +-.22886000000000E+01 +-.11471000000000E+01 +-.16755000000000E-01 +-.15194000000000E+02 +-.14043000000000E+02 +-.12892000000000E+02 +-.11740000000000E+02 +-.10589000000000E+02 +-.94377000000000E+01 +-.82866000000000E+01 +-.71355000000000E+01 +-.59844000000000E+01 +-.48335000000000E+01 +-.36833000000000E+01 +-.25353000000000E+01 +-.13919000000000E+01 +-.25772000000000E+00 +-.15402000000000E+02 +-.14250000000000E+02 +-.13099000000000E+02 +-.11948000000000E+02 +-.10797000000000E+02 +-.96453000000000E+01 +-.84941000000000E+01 +-.73430000000000E+01 +-.61918000000000E+01 +-.50408000000000E+01 +-.38904000000000E+01 +-.27418000000000E+01 +-.15970000000000E+01 +-.45955000000000E+00 +-.15599000000000E+02 +-.14448000000000E+02 +-.13296000000000E+02 +-.12145000000000E+02 +-.10994000000000E+02 +-.98425000000000E+01 +-.86914000000000E+01 +-.75402000000000E+01 +-.63890000000000E+01 +-.52379000000000E+01 +-.40873000000000E+01 +-.29382000000000E+01 +-.17921000000000E+01 +-.65225000000000E+00 +-.15824000000000E+02 +-.14673000000000E+02 +-.13522000000000E+02 +-.12370000000000E+02 +-.11219000000000E+02 +-.10068000000000E+02 +-.89165000000000E+01 +-.77654000000000E+01 +-.66141000000000E+01 +-.54630000000000E+01 +-.43123000000000E+01 +-.31627000000000E+01 +-.20156000000000E+01 +-.87372000000000E+00 +-.16067000000000E+02 +-.14916000000000E+02 +-.13764000000000E+02 +-.12613000000000E+02 +-.11462000000000E+02 +-.10311000000000E+02 +-.91592000000000E+01 +-.80078000000000E+01 +-.68567000000000E+01 +-.57056000000000E+01 +-.45547000000000E+01 +-.34047000000000E+01 +-.22568000000000E+01 +-.11133000000000E+01 +-.16319000000000E+02 +-.15168000000000E+02 +-.14017000000000E+02 +-.12866000000000E+02 +-.11714000000000E+02 +-.10563000000000E+02 +-.94119000000000E+01 +-.82605000000000E+01 +-.71094000000000E+01 +-.59581000000000E+01 +-.48073000000000E+01 +-.36569000000000E+01 +-.25083000000000E+01 +-.13633000000000E+01 +-.16499000000000E+02 +-.15347000000000E+02 +-.14196000000000E+02 +-.13045000000000E+02 +-.11894000000000E+02 +-.10742000000000E+02 +-.95911000000000E+01 +-.84397000000000E+01 +-.72886000000000E+01 +-.61373000000000E+01 +-.49863000000000E+01 +-.38358000000000E+01 +-.26867000000000E+01 +-.15407000000000E+01 +-.16685000000000E+02 +-.15534000000000E+02 +-.14383000000000E+02 +-.13231000000000E+02 +-.12080000000000E+02 +-.10929000000000E+02 +-.97776000000000E+01 +-.86265000000000E+01 +-.74752000000000E+01 +-.63240000000000E+01 +-.51729000000000E+01 +-.40222000000000E+01 +-.28727000000000E+01 +-.17259000000000E+01 +-.12692000000000E+02 +-.11543000000000E+02 +-.10398000000000E+02 +-.92649000000000E+01 +-.81592000000000E+01 +-.71019000000000E+01 +-.60741000000000E+01 +-.50142000000000E+01 +-.39153000000000E+01 +-.28396000000000E+01 +-.18673000000000E+01 +-.10203000000000E+01 +-.23261000000000E+00 +0.53973000000000E+00 +-.12909000000000E+02 +-.11760000000000E+02 +-.10613000000000E+02 +-.94756000000000E+01 +-.83594000000000E+01 +-.72810000000000E+01 +-.62256000000000E+01 +-.51467000000000E+01 +-.40405000000000E+01 +-.29542000000000E+01 +-.19556000000000E+01 +-.10842000000000E+01 +-.28872000000000E+00 +0.48515000000000E+00 +-.13113000000000E+02 +-.11963000000000E+02 +-.10815000000000E+02 +-.96746000000000E+01 +-.85505000000000E+01 +-.74558000000000E+01 +-.63790000000000E+01 +-.52848000000000E+01 +-.41707000000000E+01 +-.30730000000000E+01 +-.20485000000000E+01 +-.11480000000000E+01 +-.34048000000000E+00 +0.43588000000000E+00 +-.13334000000000E+02 +-.12184000000000E+02 +-.11035000000000E+02 +-.98926000000000E+01 +-.87634000000000E+01 +-.76588000000000E+01 +-.65687000000000E+01 +-.54642000000000E+01 +-.43433000000000E+01 +-.32342000000000E+01 +-.21840000000000E+01 +-.12492000000000E+01 +-.42333000000000E+00 +0.35737000000000E+00 +-.13560000000000E+02 +-.12409000000000E+02 +-.11260000000000E+02 +-.10116000000000E+02 +-.89824000000000E+01 +-.78685000000000E+01 +-.67664000000000E+01 +-.56526000000000E+01 +-.45256000000000E+01 +-.34077000000000E+01 +-.23371000000000E+01 +-.13694000000000E+01 +-.52039000000000E+00 +0.26679000000000E+00 +-.13634000000000E+02 +-.12484000000000E+02 +-.11334000000000E+02 +-.10188000000000E+02 +-.90493000000000E+01 +-.79249000000000E+01 +-.68088000000000E+01 +-.56844000000000E+01 +-.45511000000000E+01 +-.34251000000000E+01 +-.23367000000000E+01 +-.13369000000000E+01 +-.45921000000000E+00 +0.33827000000000E+00 +-.13728000000000E+02 +-.12577000000000E+02 +-.11427000000000E+02 +-.10279000000000E+02 +-.91370000000000E+01 +-.80054000000000E+01 +-.68799000000000E+01 +-.57483000000000E+01 +-.46102000000000E+01 +-.34780000000000E+01 +-.23751000000000E+01 +-.13460000000000E+01 +-.43546000000000E+00 +0.37741000000000E+00 +-.13846000000000E+02 +-.12696000000000E+02 +-.11545000000000E+02 +-.10396000000000E+02 +-.92522000000000E+01 +-.81157000000000E+01 +-.69838000000000E+01 +-.58472000000000E+01 +-.47058000000000E+01 +-.35688000000000E+01 +-.24542000000000E+01 +-.13996000000000E+01 +-.45417000000000E+00 +0.38010000000000E+00 +-.13925000000000E+02 +-.12774000000000E+02 +-.11624000000000E+02 +-.10474000000000E+02 +-.93281000000000E+01 +-.81875000000000E+01 +-.70503000000000E+01 +-.59097000000000E+01 +-.47656000000000E+01 +-.36251000000000E+01 +-.25016000000000E+01 +-.14255000000000E+01 +-.44547000000000E+00 +0.41636000000000E+00 +-.13997000000000E+02 +-.12846000000000E+02 +-.11695000000000E+02 +-.10545000000000E+02 +-.93975000000000E+01 +-.82542000000000E+01 +-.71129000000000E+01 +-.59695000000000E+01 +-.48235000000000E+01 +-.36802000000000E+01 +-.25499000000000E+01 +-.14565000000000E+01 +-.44402000000000E+00 +0.45048000000000E+00 +-.14077000000000E+02 +-.12926000000000E+02 +-.11775000000000E+02 +-.10625000000000E+02 +-.94763000000000E+01 +-.83308000000000E+01 +-.71869000000000E+01 +-.60414000000000E+01 +-.48940000000000E+01 +-.37488000000000E+01 +-.26133000000000E+01 +-.15062000000000E+01 +-.46500000000000E+00 +0.46510000000000E+00 +-.14124000000000E+02 +-.12972000000000E+02 +-.11821000000000E+02 +-.10671000000000E+02 +-.95212000000000E+01 +-.83743000000000E+01 +-.72283000000000E+01 +-.60812000000000E+01 +-.49329000000000E+01 +-.37861000000000E+01 +-.26469000000000E+01 +-.15292000000000E+01 +-.46392000000000E+00 +0.50206000000000E+00 +-.14172000000000E+02 +-.13021000000000E+02 +-.11869000000000E+02 +-.10719000000000E+02 +-.95686000000000E+01 +-.84204000000000E+01 +-.72731000000000E+01 +-.61248000000000E+01 +-.49757000000000E+01 +-.38279000000000E+01 +-.26859000000000E+01 +-.15604000000000E+01 +-.47568000000000E+00 +0.52359000000000E+00 +-.14238000000000E+02 +-.13087000000000E+02 +-.11936000000000E+02 +-.10785000000000E+02 +-.96345000000000E+01 +-.84854000000000E+01 +-.73370000000000E+01 +-.61880000000000E+01 +-.50383000000000E+01 +-.38898000000000E+01 +-.27457000000000E+01 +-.16145000000000E+01 +-.51485000000000E+00 +0.51292000000000E+00 +-.14312000000000E+02 +-.13161000000000E+02 +-.12010000000000E+02 +-.10858000000000E+02 +-.97080000000000E+01 +-.85583000000000E+01 +-.74092000000000E+01 +-.62595000000000E+01 +-.51095000000000E+01 +-.39604000000000E+01 +-.28148000000000E+01 +-.16794000000000E+01 +-.56883000000000E+00 +0.48175000000000E+00 +-.14385000000000E+02 +-.13233000000000E+02 +-.12082000000000E+02 +-.10931000000000E+02 +-.97805000000000E+01 +-.86304000000000E+01 +-.74807000000000E+01 +-.63306000000000E+01 +-.51803000000000E+01 +-.40308000000000E+01 +-.28842000000000E+01 +-.17457000000000E+01 +-.62726000000000E+00 +0.44086000000000E+00 +-.14448000000000E+02 +-.13297000000000E+02 +-.12146000000000E+02 +-.10995000000000E+02 +-.98437000000000E+01 +-.86934000000000E+01 +-.75433000000000E+01 +-.63929000000000E+01 +-.52424000000000E+01 +-.40925000000000E+01 +-.29451000000000E+01 +-.18045000000000E+01 +-.68042000000000E+00 +0.40125000000000E+00 +-.14555000000000E+02 +-.13404000000000E+02 +-.12252000000000E+02 +-.11101000000000E+02 +-.99502000000000E+01 +-.87996000000000E+01 +-.76492000000000E+01 +-.64985000000000E+01 +-.53478000000000E+01 +-.41976000000000E+01 +-.30496000000000E+01 +-.19073000000000E+01 +-.77882000000000E+00 +0.31361000000000E+00 +-.14635000000000E+02 +-.13484000000000E+02 +-.12333000000000E+02 +-.11182000000000E+02 +-.10031000000000E+02 +-.88796000000000E+01 +-.77290000000000E+01 +-.65782000000000E+01 +-.54274000000000E+01 +-.42771000000000E+01 +-.31285000000000E+01 +-.19848000000000E+01 +-.85289000000000E+00 +0.24869000000000E+00 +-.14771000000000E+02 +-.13619000000000E+02 +-.12468000000000E+02 +-.11317000000000E+02 +-.10166000000000E+02 +-.90146000000000E+01 +-.78638000000000E+01 +-.67128000000000E+01 +-.55619000000000E+01 +-.44114000000000E+01 +-.32623000000000E+01 +-.21174000000000E+01 +-.98239000000000E+00 +0.12716000000000E+00 +-.14948000000000E+02 +-.13797000000000E+02 +-.12646000000000E+02 +-.11494000000000E+02 +-.10343000000000E+02 +-.91921000000000E+01 +-.80413000000000E+01 +-.68903000000000E+01 +-.57393000000000E+01 +-.45885000000000E+01 +-.34391000000000E+01 +-.22930000000000E+01 +-.11553000000000E+01 +-.38677000000000E-01 +-.15069000000000E+02 +-.13917000000000E+02 +-.12766000000000E+02 +-.11615000000000E+02 +-.10463000000000E+02 +-.93123000000000E+01 +-.81614000000000E+01 +-.70103000000000E+01 +-.58591000000000E+01 +-.47084000000000E+01 +-.35586000000000E+01 +-.24116000000000E+01 +-.12715000000000E+01 +-.14867000000000E+00 +-.15232000000000E+02 +-.14081000000000E+02 +-.12930000000000E+02 +-.11779000000000E+02 +-.10627000000000E+02 +-.94761000000000E+01 +-.83250000000000E+01 +-.71738000000000E+01 +-.60227000000000E+01 +-.48718000000000E+01 +-.37217000000000E+01 +-.25739000000000E+01 +-.14318000000000E+01 +-.30355000000000E+00 +-.15434000000000E+02 +-.14283000000000E+02 +-.13132000000000E+02 +-.11980000000000E+02 +-.10829000000000E+02 +-.96780000000000E+01 +-.85269000000000E+01 +-.73757000000000E+01 +-.62246000000000E+01 +-.50736000000000E+01 +-.39232000000000E+01 +-.27747000000000E+01 +-.16307000000000E+01 +-.49801000000000E+00 +-.15662000000000E+02 +-.14510000000000E+02 +-.13359000000000E+02 +-.12208000000000E+02 +-.11057000000000E+02 +-.99053000000000E+01 +-.87542000000000E+01 +-.76029000000000E+01 +-.64518000000000E+01 +-.53007000000000E+01 +-.41501000000000E+01 +-.30009000000000E+01 +-.18555000000000E+01 +-.71901000000000E+00 +-.15909000000000E+02 +-.14757000000000E+02 +-.13606000000000E+02 +-.12455000000000E+02 +-.11303000000000E+02 +-.10152000000000E+02 +-.90010000000000E+01 +-.78499000000000E+01 +-.66986000000000E+01 +-.55475000000000E+01 +-.43967000000000E+01 +-.32471000000000E+01 +-.21003000000000E+01 +-.96078000000000E+00 +-.16103000000000E+02 +-.14951000000000E+02 +-.13800000000000E+02 +-.12649000000000E+02 +-.11498000000000E+02 +-.10346000000000E+02 +-.91951000000000E+01 +-.80439000000000E+01 +-.68927000000000E+01 +-.57416000000000E+01 +-.45907000000000E+01 +-.34407000000000E+01 +-.22929000000000E+01 +-.11509000000000E+01 +-.16299000000000E+02 +-.15148000000000E+02 +-.13997000000000E+02 +-.12846000000000E+02 +-.11694000000000E+02 +-.10543000000000E+02 +-.93918000000000E+01 +-.82405000000000E+01 +-.70894000000000E+01 +-.59382000000000E+01 +-.47872000000000E+01 +-.36370000000000E+01 +-.24885000000000E+01 +-.13445000000000E+01 +-.16522000000000E+02 +-.15371000000000E+02 +-.14219000000000E+02 +-.13068000000000E+02 +-.11917000000000E+02 +-.10766000000000E+02 +-.96143000000000E+01 +-.84629000000000E+01 +-.73118000000000E+01 +-.61606000000000E+01 +-.50095000000000E+01 +-.38590000000000E+01 +-.27099000000000E+01 +-.15644000000000E+01 +-.16760000000000E+02 +-.15609000000000E+02 +-.14457000000000E+02 +-.13306000000000E+02 +-.12155000000000E+02 +-.11003000000000E+02 +-.98521000000000E+01 +-.87009000000000E+01 +-.75497000000000E+01 +-.63984000000000E+01 +-.52473000000000E+01 +-.40966000000000E+01 +-.29470000000000E+01 +-.18002000000000E+01 +-.17006000000000E+02 +-.15854000000000E+02 +-.14703000000000E+02 +-.13552000000000E+02 +-.12401000000000E+02 +-.11249000000000E+02 +-.10098000000000E+02 +-.89468000000000E+01 +-.77957000000000E+01 +-.66444000000000E+01 +-.54932000000000E+01 +-.43423000000000E+01 +-.31923000000000E+01 +-.20446000000000E+01 +-.17167000000000E+02 +-.16015000000000E+02 +-.14864000000000E+02 +-.13713000000000E+02 +-.12561000000000E+02 +-.11410000000000E+02 +-.10259000000000E+02 +-.91074000000000E+01 +-.79562000000000E+01 +-.68049000000000E+01 +-.56537000000000E+01 +-.45028000000000E+01 +-.33525000000000E+01 +-.22041000000000E+01 +-.13263000000000E+02 +-.12115000000000E+02 +-.10969000000000E+02 +-.98350000000000E+01 +-.87271000000000E+01 +-.76649000000000E+01 +-.66300000000000E+01 +-.55642000000000E+01 +-.44625000000000E+01 +-.33860000000000E+01 +-.24134000000000E+01 +-.15662000000000E+01 +-.77843000000000E+00 +-.60257000000000E-02 +-.13474000000000E+02 +-.12324000000000E+02 +-.11178000000000E+02 +-.10040000000000E+02 +-.89214000000000E+01 +-.78387000000000E+01 +-.67773000000000E+01 +-.56938000000000E+01 +-.45853000000000E+01 +-.34982000000000E+01 +-.24992000000000E+01 +-.16276000000000E+01 +-.83202000000000E+00 +-.58078000000000E-01 +-.13672000000000E+02 +-.12522000000000E+02 +-.11374000000000E+02 +-.10232000000000E+02 +-.91067000000000E+01 +-.80085000000000E+01 +-.69268000000000E+01 +-.58287000000000E+01 +-.47126000000000E+01 +-.36143000000000E+01 +-.25895000000000E+01 +-.16887000000000E+01 +-.88091000000000E+00 +-.10444000000000E+00 +-.13887000000000E+02 +-.12737000000000E+02 +-.11588000000000E+02 +-.10445000000000E+02 +-.93145000000000E+01 +-.82068000000000E+01 +-.71125000000000E+01 +-.60048000000000E+01 +-.48822000000000E+01 +-.37725000000000E+01 +-.27218000000000E+01 +-.17866000000000E+01 +-.96042000000000E+00 +-.17954000000000E+00 +-.14108000000000E+02 +-.12957000000000E+02 +-.11808000000000E+02 +-.10663000000000E+02 +-.95286000000000E+01 +-.84119000000000E+01 +-.73060000000000E+01 +-.61896000000000E+01 +-.50613000000000E+01 +-.39427000000000E+01 +-.28716000000000E+01 +-.19033000000000E+01 +-.10537000000000E+01 +-.26630000000000E+00 +-.14319000000000E+02 +-.13168000000000E+02 +-.12019000000000E+02 +-.10872000000000E+02 +-.97344000000000E+01 +-.86106000000000E+01 +-.74957000000000E+01 +-.63721000000000E+01 +-.52390000000000E+01 +-.41129000000000E+01 +-.30241000000000E+01 +-.20235000000000E+01 +-.11452000000000E+01 +-.34748000000000E+00 +-.14385000000000E+02 +-.13234000000000E+02 +-.12084000000000E+02 +-.10937000000000E+02 +-.97947000000000E+01 +-.86633000000000E+01 +-.75380000000000E+01 +-.64065000000000E+01 +-.52684000000000E+01 +-.41360000000000E+01 +-.30323000000000E+01 +-.20023000000000E+01 +-.10911000000000E+01 +-.27835000000000E+00 +-.14471000000000E+02 +-.13320000000000E+02 +-.12170000000000E+02 +-.11021000000000E+02 +-.98770000000000E+01 +-.87400000000000E+01 +-.76077000000000E+01 +-.64707000000000E+01 +-.53292000000000E+01 +-.41919000000000E+01 +-.30767000000000E+01 +-.20211000000000E+01 +-.10755000000000E+01 +-.24213000000000E+00 +-.14590000000000E+02 +-.13438000000000E+02 +-.12288000000000E+02 +-.11138000000000E+02 +-.99924000000000E+01 +-.88518000000000E+01 +-.77147000000000E+01 +-.65741000000000E+01 +-.54301000000000E+01 +-.42892000000000E+01 +-.31652000000000E+01 +-.20886000000000E+01 +-.11093000000000E+01 +-.24981000000000E+00 +-.14670000000000E+02 +-.13519000000000E+02 +-.12368000000000E+02 +-.11219000000000E+02 +-.10071000000000E+02 +-.89275000000000E+01 +-.77864000000000E+01 +-.66428000000000E+01 +-.54968000000000E+01 +-.43534000000000E+01 +-.32228000000000E+01 +-.21296000000000E+01 +-.11195000000000E+01 +-.22921000000000E+00 +-.14751000000000E+02 +-.13600000000000E+02 +-.12449000000000E+02 +-.11299000000000E+02 +-.10150000000000E+02 +-.90049000000000E+01 +-.78608000000000E+01 +-.67152000000000E+01 +-.55679000000000E+01 +-.44225000000000E+01 +-.32871000000000E+01 +-.21810000000000E+01 +-.11437000000000E+01 +-.21966000000000E+00 +-.14845000000000E+02 +-.13694000000000E+02 +-.12543000000000E+02 +-.11393000000000E+02 +-.10243000000000E+02 +-.90962000000000E+01 +-.79502000000000E+01 +-.68031000000000E+01 +-.56547000000000E+01 +-.45079000000000E+01 +-.33690000000000E+01 +-.22529000000000E+01 +-.11927000000000E+01 +-.23402000000000E+00 +-.14906000000000E+02 +-.13754000000000E+02 +-.12603000000000E+02 +-.11453000000000E+02 +-.10303000000000E+02 +-.91543000000000E+01 +-.80068000000000E+01 +-.68586000000000E+01 +-.57096000000000E+01 +-.45619000000000E+01 +-.34203000000000E+01 +-.22968000000000E+01 +-.12178000000000E+01 +-.22609000000000E+00 +-.14990000000000E+02 +-.13839000000000E+02 +-.12688000000000E+02 +-.11537000000000E+02 +-.10386000000000E+02 +-.92375000000000E+01 +-.80891000000000E+01 +-.69401000000000E+01 +-.57904000000000E+01 +-.46420000000000E+01 +-.34984000000000E+01 +-.23691000000000E+01 +-.12752000000000E+01 +-.25396000000000E+00 +-.15068000000000E+02 +-.13917000000000E+02 +-.12766000000000E+02 +-.11615000000000E+02 +-.10464000000000E+02 +-.93147000000000E+01 +-.81655000000000E+01 +-.70159000000000E+01 +-.58658000000000E+01 +-.47168000000000E+01 +-.35717000000000E+01 +-.24382000000000E+01 +-.13328000000000E+01 +-.28705000000000E+00 +-.15145000000000E+02 +-.13994000000000E+02 +-.12842000000000E+02 +-.11691000000000E+02 +-.10541000000000E+02 +-.93904000000000E+01 +-.82407000000000E+01 +-.70907000000000E+01 +-.59404000000000E+01 +-.47910000000000E+01 +-.36448000000000E+01 +-.25079000000000E+01 +-.13940000000000E+01 +-.32898000000000E+00 +-.15220000000000E+02 +-.14069000000000E+02 +-.12918000000000E+02 +-.11767000000000E+02 +-.10616000000000E+02 +-.94656000000000E+01 +-.83152000000000E+01 +-.71650000000000E+01 +-.60145000000000E+01 +-.48646000000000E+01 +-.37176000000000E+01 +-.25784000000000E+01 +-.14580000000000E+01 +-.37836000000000E+00 +-.15284000000000E+02 +-.14133000000000E+02 +-.12981000000000E+02 +-.11830000000000E+02 +-.10679000000000E+02 +-.95286000000000E+01 +-.83779000000000E+01 +-.72274000000000E+01 +-.60768000000000E+01 +-.49266000000000E+01 +-.37790000000000E+01 +-.26379000000000E+01 +-.15127000000000E+01 +-.42195000000000E+00 +-.15390000000000E+02 +-.14238000000000E+02 +-.13087000000000E+02 +-.11936000000000E+02 +-.10785000000000E+02 +-.96340000000000E+01 +-.84832000000000E+01 +-.73325000000000E+01 +-.61816000000000E+01 +-.50314000000000E+01 +-.38831000000000E+01 +-.27404000000000E+01 +-.16112000000000E+01 +-.51161000000000E+00 +-.15470000000000E+02 +-.14319000000000E+02 +-.13168000000000E+02 +-.12017000000000E+02 +-.10865000000000E+02 +-.97146000000000E+01 +-.85637000000000E+01 +-.74128000000000E+01 +-.62620000000000E+01 +-.51115000000000E+01 +-.39628000000000E+01 +-.28187000000000E+01 +-.16864000000000E+01 +-.57933000000000E+00 +-.15603000000000E+02 +-.14452000000000E+02 +-.13300000000000E+02 +-.12149000000000E+02 +-.10998000000000E+02 +-.98467000000000E+01 +-.86958000000000E+01 +-.75448000000000E+01 +-.63938000000000E+01 +-.52433000000000E+01 +-.40940000000000E+01 +-.29488000000000E+01 +-.18135000000000E+01 +-.69989000000000E+00 +-.15778000000000E+02 +-.14626000000000E+02 +-.13475000000000E+02 +-.12324000000000E+02 +-.11173000000000E+02 +-.10022000000000E+02 +-.88706000000000E+01 +-.77196000000000E+01 +-.65685000000000E+01 +-.54177000000000E+01 +-.42681000000000E+01 +-.31217000000000E+01 +-.19836000000000E+01 +-.86414000000000E+00 +-.15896000000000E+02 +-.14745000000000E+02 +-.13594000000000E+02 +-.12443000000000E+02 +-.11292000000000E+02 +-.10140000000000E+02 +-.89890000000000E+01 +-.78380000000000E+01 +-.66869000000000E+01 +-.55361000000000E+01 +-.43861000000000E+01 +-.32389000000000E+01 +-.20986000000000E+01 +-.97400000000000E+00 +-.16053000000000E+02 +-.14902000000000E+02 +-.13751000000000E+02 +-.12600000000000E+02 +-.11448000000000E+02 +-.10297000000000E+02 +-.91460000000000E+01 +-.79950000000000E+01 +-.68437000000000E+01 +-.56929000000000E+01 +-.45426000000000E+01 +-.33947000000000E+01 +-.22524000000000E+01 +-.11232000000000E+01 +-.16249000000000E+02 +-.15098000000000E+02 +-.13947000000000E+02 +-.12795000000000E+02 +-.11644000000000E+02 +-.10493000000000E+02 +-.93416000000000E+01 +-.81904000000000E+01 +-.70392000000000E+01 +-.58882000000000E+01 +-.47377000000000E+01 +-.35890000000000E+01 +-.24450000000000E+01 +-.13118000000000E+01 +-.16472000000000E+02 +-.15321000000000E+02 +-.14169000000000E+02 +-.13018000000000E+02 +-.11867000000000E+02 +-.10716000000000E+02 +-.95642000000000E+01 +-.84131000000000E+01 +-.72620000000000E+01 +-.61108000000000E+01 +-.49602000000000E+01 +-.38109000000000E+01 +-.26653000000000E+01 +-.15287000000000E+01 +-.16714000000000E+02 +-.15563000000000E+02 +-.14411000000000E+02 +-.13260000000000E+02 +-.12109000000000E+02 +-.10958000000000E+02 +-.98062000000000E+01 +-.86550000000000E+01 +-.75038000000000E+01 +-.63527000000000E+01 +-.52019000000000E+01 +-.40521000000000E+01 +-.29053000000000E+01 +-.17657000000000E+01 +-.16904000000000E+02 +-.15752000000000E+02 +-.14601000000000E+02 +-.13450000000000E+02 +-.12299000000000E+02 +-.11147000000000E+02 +-.99961000000000E+01 +-.88447000000000E+01 +-.76936000000000E+01 +-.65425000000000E+01 +-.53915000000000E+01 +-.42415000000000E+01 +-.30937000000000E+01 +-.19518000000000E+01 +-.17093000000000E+02 +-.15942000000000E+02 +-.14791000000000E+02 +-.13640000000000E+02 +-.12488000000000E+02 +-.11337000000000E+02 +-.10186000000000E+02 +-.90344000000000E+01 +-.78833000000000E+01 +-.67322000000000E+01 +-.55812000000000E+01 +-.44308000000000E+01 +-.32823000000000E+01 +-.21385000000000E+01 +-.17308000000000E+02 +-.16157000000000E+02 +-.15006000000000E+02 +-.13854000000000E+02 +-.12703000000000E+02 +-.11552000000000E+02 +-.10400000000000E+02 +-.92490000000000E+01 +-.80979000000000E+01 +-.69467000000000E+01 +-.57957000000000E+01 +-.46450000000000E+01 +-.34960000000000E+01 +-.23507000000000E+01 +-.17537000000000E+02 +-.16386000000000E+02 +-.15234000000000E+02 +-.14083000000000E+02 +-.12932000000000E+02 +-.11781000000000E+02 +-.10629000000000E+02 +-.94780000000000E+01 +-.83267000000000E+01 +-.71757000000000E+01 +-.60245000000000E+01 +-.48738000000000E+01 +-.37242000000000E+01 +-.25776000000000E+01 +-.17772000000000E+02 +-.16621000000000E+02 +-.15470000000000E+02 +-.14319000000000E+02 +-.13167000000000E+02 +-.12016000000000E+02 +-.10865000000000E+02 +-.97136000000000E+01 +-.85625000000000E+01 +-.74113000000000E+01 +-.62601000000000E+01 +-.51093000000000E+01 +-.39593000000000E+01 +-.28117000000000E+01 +-.14180000000000E+02 +-.13031000000000E+02 +-.11886000000000E+02 +-.10750000000000E+02 +-.96382000000000E+01 +-.85686000000000E+01 +-.75226000000000E+01 +-.64480000000000E+01 +-.53422000000000E+01 +-.42642000000000E+01 +-.32912000000000E+01 +-.24438000000000E+01 +-.16560000000000E+01 +-.88351000000000E+00 +-.14380000000000E+02 +-.13231000000000E+02 +-.12083000000000E+02 +-.10944000000000E+02 +-.98228000000000E+01 +-.87334000000000E+01 +-.76630000000000E+01 +-.65723000000000E+01 +-.54603000000000E+01 +-.43721000000000E+01 +-.33726000000000E+01 +-.25009000000000E+01 +-.17051000000000E+01 +-.93103000000000E+00 +-.14567000000000E+02 +-.13417000000000E+02 +-.12269000000000E+02 +-.11127000000000E+02 +-.99983000000000E+01 +-.88945000000000E+01 +-.78052000000000E+01 +-.67012000000000E+01 +-.55824000000000E+01 +-.44830000000000E+01 +-.34578000000000E+01 +-.25567000000000E+01 +-.17487000000000E+01 +-.97205000000000E+00 +-.14773000000000E+02 +-.13623000000000E+02 +-.12474000000000E+02 +-.11330000000000E+02 +-.10197000000000E+02 +-.90842000000000E+01 +-.79836000000000E+01 +-.68711000000000E+01 +-.57462000000000E+01 +-.46355000000000E+01 +-.35844000000000E+01 +-.26488000000000E+01 +-.18223000000000E+01 +-.10410000000000E+01 +-.14984000000000E+02 +-.13833000000000E+02 +-.12684000000000E+02 +-.11538000000000E+02 +-.10402000000000E+02 +-.92810000000000E+01 +-.81697000000000E+01 +-.70491000000000E+01 +-.59188000000000E+01 +-.47994000000000E+01 +-.37278000000000E+01 +-.27590000000000E+01 +-.19089000000000E+01 +-.11209000000000E+01 +-.15185000000000E+02 +-.14034000000000E+02 +-.12885000000000E+02 +-.11738000000000E+02 +-.10598000000000E+02 +-.94709000000000E+01 +-.83511000000000E+01 +-.72241000000000E+01 +-.60894000000000E+01 +-.49626000000000E+01 +-.38732000000000E+01 +-.28719000000000E+01 +-.19926000000000E+01 +-.11940000000000E+01 +-.15378000000000E+02 +-.14227000000000E+02 +-.13077000000000E+02 +-.11929000000000E+02 +-.10787000000000E+02 +-.96550000000000E+01 +-.85286000000000E+01 +-.73966000000000E+01 +-.62582000000000E+01 +-.51254000000000E+01 +-.40211000000000E+01 +-.29899000000000E+01 +-.20772000000000E+01 +-.12631000000000E+01 +-.15545000000000E+02 +-.14394000000000E+02 +-.13244000000000E+02 +-.12095000000000E+02 +-.10951000000000E+02 +-.98147000000000E+01 +-.86829000000000E+01 +-.75464000000000E+01 +-.64050000000000E+01 +-.52675000000000E+01 +-.41515000000000E+01 +-.30941000000000E+01 +-.21460000000000E+01 +-.13104000000000E+01 +-.15580000000000E+02 +-.14429000000000E+02 +-.13279000000000E+02 +-.12129000000000E+02 +-.10983000000000E+02 +-.98420000000000E+01 +-.87046000000000E+01 +-.75637000000000E+01 +-.64194000000000E+01 +-.52782000000000E+01 +-.41530000000000E+01 +-.30739000000000E+01 +-.20911000000000E+01 +-.12286000000000E+01 +-.15665000000000E+02 +-.14514000000000E+02 +-.13364000000000E+02 +-.12214000000000E+02 +-.11066000000000E+02 +-.99224000000000E+01 +-.87810000000000E+01 +-.76373000000000E+01 +-.64912000000000E+01 +-.53472000000000E+01 +-.42152000000000E+01 +-.31188000000000E+01 +-.21041000000000E+01 +-.12104000000000E+01 +-.15776000000000E+02 +-.14625000000000E+02 +-.13474000000000E+02 +-.12323000000000E+02 +-.11175000000000E+02 +-.10029000000000E+02 +-.88853000000000E+01 +-.77397000000000E+01 +-.65922000000000E+01 +-.54463000000000E+01 +-.43093000000000E+01 +-.31997000000000E+01 +-.21575000000000E+01 +-.12309000000000E+01 +-.15850000000000E+02 +-.14699000000000E+02 +-.13548000000000E+02 +-.12397000000000E+02 +-.11248000000000E+02 +-.10101000000000E+02 +-.89548000000000E+01 +-.78075000000000E+01 +-.66589000000000E+01 +-.55117000000000E+01 +-.43712000000000E+01 +-.32520000000000E+01 +-.21879000000000E+01 +-.12294000000000E+01 +-.15950000000000E+02 +-.14799000000000E+02 +-.13648000000000E+02 +-.12497000000000E+02 +-.11347000000000E+02 +-.10198000000000E+02 +-.90510000000000E+01 +-.79027000000000E+01 +-.67534000000000E+01 +-.56052000000000E+01 +-.44624000000000E+01 +-.33364000000000E+01 +-.22554000000000E+01 +-.12684000000000E+01 +-.16092000000000E+02 +-.14941000000000E+02 +-.13790000000000E+02 +-.12639000000000E+02 +-.11489000000000E+02 +-.10340000000000E+02 +-.91914000000000E+01 +-.80422000000000E+01 +-.68926000000000E+01 +-.57438000000000E+01 +-.45992000000000E+01 +-.34683000000000E+01 +-.23745000000000E+01 +-.13622000000000E+01 +-.16226000000000E+02 +-.15075000000000E+02 +-.13924000000000E+02 +-.12773000000000E+02 +-.11622000000000E+02 +-.10473000000000E+02 +-.93235000000000E+01 +-.81738000000000E+01 +-.70238000000000E+01 +-.58745000000000E+01 +-.47288000000000E+01 +-.35942000000000E+01 +-.24906000000000E+01 +-.14568000000000E+01 +-.16349000000000E+02 +-.15198000000000E+02 +-.14047000000000E+02 +-.12896000000000E+02 +-.11745000000000E+02 +-.10595000000000E+02 +-.94448000000000E+01 +-.82947000000000E+01 +-.71444000000000E+01 +-.59948000000000E+01 +-.48481000000000E+01 +-.37109000000000E+01 +-.25995000000000E+01 +-.15474000000000E+01 +-.16457000000000E+02 +-.15305000000000E+02 +-.14154000000000E+02 +-.13003000000000E+02 +-.11852000000000E+02 +-.10702000000000E+02 +-.95515000000000E+01 +-.84011000000000E+01 +-.72506000000000E+01 +-.61007000000000E+01 +-.49534000000000E+01 +-.38139000000000E+01 +-.26964000000000E+01 +-.16288000000000E+01 +-.16563000000000E+02 +-.15412000000000E+02 +-.14261000000000E+02 +-.13110000000000E+02 +-.11959000000000E+02 +-.10808000000000E+02 +-.96575000000000E+01 +-.85068000000000E+01 +-.73562000000000E+01 +-.62061000000000E+01 +-.50581000000000E+01 +-.39168000000000E+01 +-.27940000000000E+01 +-.17137000000000E+01 +-.16647000000000E+02 +-.15496000000000E+02 +-.14345000000000E+02 +-.13194000000000E+02 +-.12043000000000E+02 +-.10892000000000E+02 +-.97410000000000E+01 +-.85903000000000E+01 +-.74395000000000E+01 +-.62892000000000E+01 +-.51406000000000E+01 +-.39979000000000E+01 +-.28710000000000E+01 +-.17805000000000E+01 +-.16736000000000E+02 +-.15585000000000E+02 +-.14434000000000E+02 +-.13282000000000E+02 +-.12131000000000E+02 +-.10980000000000E+02 +-.98293000000000E+01 +-.86785000000000E+01 +-.75277000000000E+01 +-.63772000000000E+01 +-.52283000000000E+01 +-.40842000000000E+01 +-.29537000000000E+01 +-.18548000000000E+01 +-.16849000000000E+02 +-.15698000000000E+02 +-.14546000000000E+02 +-.13395000000000E+02 +-.12244000000000E+02 +-.11093000000000E+02 +-.99417000000000E+01 +-.87905000000000E+01 +-.76396000000000E+01 +-.64890000000000E+01 +-.53397000000000E+01 +-.41945000000000E+01 +-.30607000000000E+01 +-.19542000000000E+01 +-.16938000000000E+02 +-.15788000000000E+02 +-.14636000000000E+02 +-.13485000000000E+02 +-.12334000000000E+02 +-.11183000000000E+02 +-.10031000000000E+02 +-.88804000000000E+01 +-.77294000000000E+01 +-.65787000000000E+01 +-.54291000000000E+01 +-.42828000000000E+01 +-.31465000000000E+01 +-.20337000000000E+01 +-.17082000000000E+02 +-.15931000000000E+02 +-.14780000000000E+02 +-.13628000000000E+02 +-.12477000000000E+02 +-.11326000000000E+02 +-.10175000000000E+02 +-.90237000000000E+01 +-.78726000000000E+01 +-.67217000000000E+01 +-.55718000000000E+01 +-.44247000000000E+01 +-.32856000000000E+01 +-.21667000000000E+01 +-.17243000000000E+02 +-.16092000000000E+02 +-.14941000000000E+02 +-.13790000000000E+02 +-.12638000000000E+02 +-.11487000000000E+02 +-.10336000000000E+02 +-.91848000000000E+01 +-.80337000000000E+01 +-.68827000000000E+01 +-.57325000000000E+01 +-.45846000000000E+01 +-.34432000000000E+01 +-.23188000000000E+01 +-.17355000000000E+02 +-.16204000000000E+02 +-.15053000000000E+02 +-.13901000000000E+02 +-.12750000000000E+02 +-.11599000000000E+02 +-.10448000000000E+02 +-.92964000000000E+01 +-.81453000000000E+01 +-.69944000000000E+01 +-.58440000000000E+01 +-.46954000000000E+01 +-.35524000000000E+01 +-.24238000000000E+01 +-.17517000000000E+02 +-.16366000000000E+02 +-.15215000000000E+02 +-.14063000000000E+02 +-.12912000000000E+02 +-.11761000000000E+02 +-.10610000000000E+02 +-.94585000000000E+01 +-.83074000000000E+01 +-.71562000000000E+01 +-.60057000000000E+01 +-.48566000000000E+01 +-.37120000000000E+01 +-.25792000000000E+01 +-.17713000000000E+02 +-.16562000000000E+02 +-.15411000000000E+02 +-.14260000000000E+02 +-.13108000000000E+02 +-.11957000000000E+02 +-.10806000000000E+02 +-.96545000000000E+01 +-.85034000000000E+01 +-.73523000000000E+01 +-.62015000000000E+01 +-.50520000000000E+01 +-.39060000000000E+01 +-.27695000000000E+01 +-.17933000000000E+02 +-.16782000000000E+02 +-.15631000000000E+02 +-.14479000000000E+02 +-.13328000000000E+02 +-.12177000000000E+02 +-.11025000000000E+02 +-.98743000000000E+01 +-.87229000000000E+01 +-.75719000000000E+01 +-.64210000000000E+01 +-.52710000000000E+01 +-.41238000000000E+01 +-.29843000000000E+01 +-.18168000000000E+02 +-.17017000000000E+02 +-.15866000000000E+02 +-.14715000000000E+02 +-.13563000000000E+02 +-.12412000000000E+02 +-.11261000000000E+02 +-.10110000000000E+02 +-.89585000000000E+01 +-.78073000000000E+01 +-.66562000000000E+01 +-.55060000000000E+01 +-.43578000000000E+01 +-.32158000000000E+01 +-.18326000000000E+02 +-.17174000000000E+02 +-.16023000000000E+02 +-.14872000000000E+02 +-.13721000000000E+02 +-.12570000000000E+02 +-.11418000000000E+02 +-.10267000000000E+02 +-.91157000000000E+01 +-.79646000000000E+01 +-.68135000000000E+01 +-.56631000000000E+01 +-.45143000000000E+01 +-.33705000000000E+01 +-.18420000000000E+02 +-.17358000000000E+02 +-.16207000000000E+02 +-.15055000000000E+02 +-.13904000000000E+02 +-.12753000000000E+02 +-.11602000000000E+02 +-.10450000000000E+02 +-.92991000000000E+01 +-.81479000000000E+01 +-.69968000000000E+01 +-.58462000000000E+01 +-.46969000000000E+01 +-.35516000000000E+01 +-.18420000000000E+02 +-.17561000000000E+02 +-.16409000000000E+02 +-.15258000000000E+02 +-.14107000000000E+02 +-.12956000000000E+02 +-.11804000000000E+02 +-.10653000000000E+02 +-.95017000000000E+01 +-.83506000000000E+01 +-.71995000000000E+01 +-.60487000000000E+01 +-.48990000000000E+01 +-.37525000000000E+01 +-.15936000000000E+02 +-.14786000000000E+02 +-.13640000000000E+02 +-.12501000000000E+02 +-.11383000000000E+02 +-.10298000000000E+02 +-.92307000000000E+01 +-.81396000000000E+01 +-.70264000000000E+01 +-.59459000000000E+01 +-.49723000000000E+01 +-.41249000000000E+01 +-.33370000000000E+01 +-.25645000000000E+01 +-.16122000000000E+02 +-.14972000000000E+02 +-.13824000000000E+02 +-.12682000000000E+02 +-.11554000000000E+02 +-.10453000000000E+02 +-.93647000000000E+01 +-.82607000000000E+01 +-.71427000000000E+01 +-.60524000000000E+01 +-.50524000000000E+01 +-.41804000000000E+01 +-.33846000000000E+01 +-.26105000000000E+01 +-.16295000000000E+02 +-.15145000000000E+02 +-.13996000000000E+02 +-.12851000000000E+02 +-.11718000000000E+02 +-.10604000000000E+02 +-.95000000000000E+01 +-.83853000000000E+01 +-.72616000000000E+01 +-.61604000000000E+01 +-.51348000000000E+01 +-.42334000000000E+01 +-.34254000000000E+01 +-.26486000000000E+01 +-.16488000000000E+02 +-.15337000000000E+02 +-.14188000000000E+02 +-.13042000000000E+02 +-.11905000000000E+02 +-.10783000000000E+02 +-.96707000000000E+01 +-.85491000000000E+01 +-.74202000000000E+01 +-.63080000000000E+01 +-.52565000000000E+01 +-.43207000000000E+01 +-.34940000000000E+01 +-.27126000000000E+01 +-.16685000000000E+02 +-.15534000000000E+02 +-.14384000000000E+02 +-.13237000000000E+02 +-.12097000000000E+02 +-.10969000000000E+02 +-.98469000000000E+01 +-.87187000000000E+01 +-.75851000000000E+01 +-.64645000000000E+01 +-.53923000000000E+01 +-.44232000000000E+01 +-.35729000000000E+01 +-.27845000000000E+01 +-.16869000000000E+02 +-.15718000000000E+02 +-.14568000000000E+02 +-.13420000000000E+02 +-.12277000000000E+02 +-.11144000000000E+02 +-.10015000000000E+02 +-.88821000000000E+01 +-.77445000000000E+01 +-.66166000000000E+01 +-.55267000000000E+01 +-.45250000000000E+01 +-.36453000000000E+01 +-.28462000000000E+01 +-.17042000000000E+02 +-.15891000000000E+02 +-.14740000000000E+02 +-.13592000000000E+02 +-.12447000000000E+02 +-.11310000000000E+02 +-.10176000000000E+02 +-.90386000000000E+01 +-.78978000000000E+01 +-.67642000000000E+01 +-.56595000000000E+01 +-.46278000000000E+01 +-.37145000000000E+01 +-.28993000000000E+01 +-.17204000000000E+02 +-.16053000000000E+02 +-.14903000000000E+02 +-.13753000000000E+02 +-.12607000000000E+02 +-.11467000000000E+02 +-.10329000000000E+02 +-.91887000000000E+01 +-.80452000000000E+01 +-.69071000000000E+01 +-.57906000000000E+01 +-.47327000000000E+01 +-.37834000000000E+01 +-.29462000000000E+01 +-.17358000000000E+02 +-.16207000000000E+02 +-.15056000000000E+02 +-.13906000000000E+02 +-.12759000000000E+02 +-.11616000000000E+02 +-.10476000000000E+02 +-.93328000000000E+01 +-.81875000000000E+01 +-.70459000000000E+01 +-.59203000000000E+01 +-.48402000000000E+01 +-.38555000000000E+01 +-.29901000000000E+01 +-.17506000000000E+02 +-.16354000000000E+02 +-.15204000000000E+02 +-.14054000000000E+02 +-.12906000000000E+02 +-.11761000000000E+02 +-.10618000000000E+02 +-.94731000000000E+01 +-.83264000000000E+01 +-.71821000000000E+01 +-.60496000000000E+01 +-.49518000000000E+01 +-.39340000000000E+01 +-.30355000000000E+01 +-.17651000000000E+02 +-.16500000000000E+02 +-.15349000000000E+02 +-.14198000000000E+02 +-.13050000000000E+02 +-.11904000000000E+02 +-.10759000000000E+02 +-.96125000000000E+01 +-.84646000000000E+01 +-.73185000000000E+01 +-.61808000000000E+01 +-.50691000000000E+01 +-.40220000000000E+01 +-.30876000000000E+01 +-.17797000000000E+02 +-.16646000000000E+02 +-.15495000000000E+02 +-.14345000000000E+02 +-.13195000000000E+02 +-.12048000000000E+02 +-.10902000000000E+02 +-.97544000000000E+01 +-.86057000000000E+01 +-.74580000000000E+01 +-.63165000000000E+01 +-.51942000000000E+01 +-.41228000000000E+01 +-.31520000000000E+01 +-.17806000000000E+02 +-.16654000000000E+02 +-.15503000000000E+02 +-.14353000000000E+02 +-.13202000000000E+02 +-.12054000000000E+02 +-.10906000000000E+02 +-.97576000000000E+01 +-.86082000000000E+01 +-.74595000000000E+01 +-.63152000000000E+01 +-.51849000000000E+01 +-.40939000000000E+01 +-.30892000000000E+01 +-.17888000000000E+02 +-.16737000000000E+02 +-.15586000000000E+02 +-.14435000000000E+02 +-.13285000000000E+02 +-.12135000000000E+02 +-.10987000000000E+02 +-.98374000000000E+01 +-.86873000000000E+01 +-.75380000000000E+01 +-.63917000000000E+01 +-.52559000000000E+01 +-.41495000000000E+01 +-.31148000000000E+01 +-.18016000000000E+02 +-.16865000000000E+02 +-.15714000000000E+02 +-.14563000000000E+02 +-.13412000000000E+02 +-.12262000000000E+02 +-.11113000000000E+02 +-.99631000000000E+01 +-.88130000000000E+01 +-.76631000000000E+01 +-.65155000000000E+01 +-.53754000000000E+01 +-.42578000000000E+01 +-.31981000000000E+01 +-.18124000000000E+02 +-.16972000000000E+02 +-.15821000000000E+02 +-.14670000000000E+02 +-.13519000000000E+02 +-.12369000000000E+02 +-.11219000000000E+02 +-.10069000000000E+02 +-.89182000000000E+01 +-.77679000000000E+01 +-.66194000000000E+01 +-.54766000000000E+01 +-.43508000000000E+01 +-.32717000000000E+01 +-.18265000000000E+02 +-.17113000000000E+02 +-.15962000000000E+02 +-.14811000000000E+02 +-.13660000000000E+02 +-.12510000000000E+02 +-.11359000000000E+02 +-.10209000000000E+02 +-.90581000000000E+01 +-.79077000000000E+01 +-.67585000000000E+01 +-.56138000000000E+01 +-.44824000000000E+01 +-.33890000000000E+01 +-.18420000000000E+02 +-.17311000000000E+02 +-.16160000000000E+02 +-.15009000000000E+02 +-.13857000000000E+02 +-.12707000000000E+02 +-.11556000000000E+02 +-.10406000000000E+02 +-.92546000000000E+01 +-.81040000000000E+01 +-.69543000000000E+01 +-.58083000000000E+01 +-.46733000000000E+01 +-.35698000000000E+01 +-.18420000000000E+02 +-.17557000000000E+02 +-.16406000000000E+02 +-.15255000000000E+02 +-.14104000000000E+02 +-.12953000000000E+02 +-.11802000000000E+02 +-.10651000000000E+02 +-.95002000000000E+01 +-.83496000000000E+01 +-.71997000000000E+01 +-.60529000000000E+01 +-.49153000000000E+01 +-.38049000000000E+01 +-.18420000000000E+02 +-.17835000000000E+02 +-.16684000000000E+02 +-.15533000000000E+02 +-.14382000000000E+02 +-.13231000000000E+02 +-.12080000000000E+02 +-.10929000000000E+02 +-.97778000000000E+01 +-.86270000000000E+01 +-.74769000000000E+01 +-.63296000000000E+01 +-.51903000000000E+01 +-.40751000000000E+01 +-.18420000000000E+02 +-.18136000000000E+02 +-.16984000000000E+02 +-.15833000000000E+02 +-.14682000000000E+02 +-.13531000000000E+02 +-.12380000000000E+02 +-.11229000000000E+02 +-.10078000000000E+02 +-.89268000000000E+01 +-.77766000000000E+01 +-.66287000000000E+01 +-.54882000000000E+01 +-.43690000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.17309000000000E+02 +-.16158000000000E+02 +-.15007000000000E+02 +-.13856000000000E+02 +-.12705000000000E+02 +-.11553000000000E+02 +-.10402000000000E+02 +-.92515000000000E+01 +-.81011000000000E+01 +-.69528000000000E+01 +-.58108000000000E+01 +-.46875000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.17602000000000E+02 +-.16451000000000E+02 +-.15300000000000E+02 +-.14149000000000E+02 +-.12998000000000E+02 +-.11846000000000E+02 +-.10695000000000E+02 +-.95442000000000E+01 +-.83936000000000E+01 +-.72449000000000E+01 +-.61014000000000E+01 +-.49740000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.17849000000000E+02 +-.16697000000000E+02 +-.15546000000000E+02 +-.14395000000000E+02 +-.13244000000000E+02 +-.12093000000000E+02 +-.10941000000000E+02 +-.97903000000000E+01 +-.86396000000000E+01 +-.74906000000000E+01 +-.63458000000000E+01 +-.52145000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18079000000000E+02 +-.16927000000000E+02 +-.15776000000000E+02 +-.14625000000000E+02 +-.13474000000000E+02 +-.12323000000000E+02 +-.11171000000000E+02 +-.10020000000000E+02 +-.88694000000000E+01 +-.77198000000000E+01 +-.65739000000000E+01 +-.54387000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18232000000000E+02 +-.17081000000000E+02 +-.15930000000000E+02 +-.14778000000000E+02 +-.13627000000000E+02 +-.12476000000000E+02 +-.11325000000000E+02 +-.10173000000000E+02 +-.90227000000000E+01 +-.78728000000000E+01 +-.67258000000000E+01 +-.55879000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18404000000000E+02 +-.17253000000000E+02 +-.16102000000000E+02 +-.14951000000000E+02 +-.13800000000000E+02 +-.12648000000000E+02 +-.11497000000000E+02 +-.10346000000000E+02 +-.91948000000000E+01 +-.80447000000000E+01 +-.68970000000000E+01 +-.57563000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17433000000000E+02 +-.16282000000000E+02 +-.15131000000000E+02 +-.13979000000000E+02 +-.12828000000000E+02 +-.11677000000000E+02 +-.10525000000000E+02 +-.93745000000000E+01 +-.82241000000000E+01 +-.70756000000000E+01 +-.59327000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17530000000000E+02 +-.16379000000000E+02 +-.15228000000000E+02 +-.14077000000000E+02 +-.12925000000000E+02 +-.11774000000000E+02 +-.10623000000000E+02 +-.94719000000000E+01 +-.83213000000000E+01 +-.71722000000000E+01 +-.60280000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17669000000000E+02 +-.16518000000000E+02 +-.15366000000000E+02 +-.14215000000000E+02 +-.13064000000000E+02 +-.11913000000000E+02 +-.10761000000000E+02 +-.96101000000000E+01 +-.84595000000000E+01 +-.73101000000000E+01 +-.61644000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17834000000000E+02 +-.16683000000000E+02 +-.15532000000000E+02 +-.14380000000000E+02 +-.13229000000000E+02 +-.12078000000000E+02 +-.10927000000000E+02 +-.97756000000000E+01 +-.86248000000000E+01 +-.74749000000000E+01 +-.63280000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18017000000000E+02 +-.16866000000000E+02 +-.15715000000000E+02 +-.14563000000000E+02 +-.13412000000000E+02 +-.12261000000000E+02 +-.11110000000000E+02 +-.99583000000000E+01 +-.88074000000000E+01 +-.76573000000000E+01 +-.65095000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.17675000000000E+02 +-.16534000000000E+02 +-.15410000000000E+02 +-.14312000000000E+02 +-.13228000000000E+02 +-.12124000000000E+02 +-.11004000000000E+02 +-.99219000000000E+01 +-.89480000000000E+01 +-.81003000000000E+01 +-.73125000000000E+01 +-.65400000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.17849000000000E+02 +-.16705000000000E+02 +-.15572000000000E+02 +-.14460000000000E+02 +-.13358000000000E+02 +-.12243000000000E+02 +-.11120000000000E+02 +-.10028000000000E+02 +-.90281000000000E+01 +-.81560000000000E+01 +-.73602000000000E+01 +-.65861000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18012000000000E+02 +-.16866000000000E+02 +-.15728000000000E+02 +-.14605000000000E+02 +-.13490000000000E+02 +-.12366000000000E+02 +-.11239000000000E+02 +-.10136000000000E+02 +-.91104000000000E+01 +-.82090000000000E+01 +-.74011000000000E+01 +-.66243000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18197000000000E+02 +-.17050000000000E+02 +-.15910000000000E+02 +-.14781000000000E+02 +-.13658000000000E+02 +-.12530000000000E+02 +-.11397000000000E+02 +-.10284000000000E+02 +-.92322000000000E+01 +-.82964000000000E+01 +-.74697000000000E+01 +-.66884000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18389000000000E+02 +-.17240000000000E+02 +-.16097000000000E+02 +-.14962000000000E+02 +-.13833000000000E+02 +-.12699000000000E+02 +-.11562000000000E+02 +-.10441000000000E+02 +-.93684000000000E+01 +-.83992000000000E+01 +-.75487000000000E+01 +-.67604000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17419000000000E+02 +-.16273000000000E+02 +-.15135000000000E+02 +-.14000000000000E+02 +-.12862000000000E+02 +-.11722000000000E+02 +-.10593000000000E+02 +-.95029000000000E+01 +-.85012000000000E+01 +-.76215000000000E+01 +-.68223000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17587000000000E+02 +-.16440000000000E+02 +-.15298000000000E+02 +-.14159000000000E+02 +-.13018000000000E+02 +-.11875000000000E+02 +-.10741000000000E+02 +-.96357000000000E+01 +-.86040000000000E+01 +-.76907000000000E+01 +-.68755000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17745000000000E+02 +-.16597000000000E+02 +-.15453000000000E+02 +-.14311000000000E+02 +-.13167000000000E+02 +-.12022000000000E+02 +-.10884000000000E+02 +-.97668000000000E+01 +-.87087000000000E+01 +-.77596000000000E+01 +-.69224000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17895000000000E+02 +-.16746000000000E+02 +-.15600000000000E+02 +-.14456000000000E+02 +-.13310000000000E+02 +-.12163000000000E+02 +-.11021000000000E+02 +-.98955000000000E+01 +-.88154000000000E+01 +-.78307000000000E+01 +-.69652000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18036000000000E+02 +-.16887000000000E+02 +-.15740000000000E+02 +-.14594000000000E+02 +-.13447000000000E+02 +-.12299000000000E+02 +-.11154000000000E+02 +-.10021000000000E+02 +-.89236000000000E+01 +-.79056000000000E+01 +-.70070000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18170000000000E+02 +-.17021000000000E+02 +-.15873000000000E+02 +-.14725000000000E+02 +-.13577000000000E+02 +-.12429000000000E+02 +-.11282000000000E+02 +-.10144000000000E+02 +-.90325000000000E+01 +-.79854000000000E+01 +-.70505000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18299000000000E+02 +-.17148000000000E+02 +-.16000000000000E+02 +-.14852000000000E+02 +-.13703000000000E+02 +-.12553000000000E+02 +-.11406000000000E+02 +-.10264000000000E+02 +-.91416000000000E+01 +-.80698000000000E+01 +-.70986000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17272000000000E+02 +-.16123000000000E+02 +-.14974000000000E+02 +-.13824000000000E+02 +-.12675000000000E+02 +-.11526000000000E+02 +-.10381000000000E+02 +-.92507000000000E+01 +-.81592000000000E+01 +-.71532000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17416000000000E+02 +-.16266000000000E+02 +-.15117000000000E+02 +-.13967000000000E+02 +-.12817000000000E+02 +-.11667000000000E+02 +-.10521000000000E+02 +-.93848000000000E+01 +-.82776000000000E+01 +-.72404000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17565000000000E+02 +-.16415000000000E+02 +-.15265000000000E+02 +-.14115000000000E+02 +-.12965000000000E+02 +-.11815000000000E+02 +-.10667000000000E+02 +-.95264000000000E+01 +-.84072000000000E+01 +-.73436000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17708000000000E+02 +-.16558000000000E+02 +-.15408000000000E+02 +-.14258000000000E+02 +-.13107000000000E+02 +-.11956000000000E+02 +-.10808000000000E+02 +-.96641000000000E+01 +-.85361000000000E+01 +-.74507000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17844000000000E+02 +-.16693000000000E+02 +-.15543000000000E+02 +-.14393000000000E+02 +-.13242000000000E+02 +-.12091000000000E+02 +-.10942000000000E+02 +-.97959000000000E+01 +-.86614000000000E+01 +-.75590000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17829000000000E+02 +-.16678000000000E+02 +-.15527000000000E+02 +-.14376000000000E+02 +-.13225000000000E+02 +-.12074000000000E+02 +-.10925000000000E+02 +-.97771000000000E+01 +-.86377000000000E+01 +-.75223000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17869000000000E+02 +-.16718000000000E+02 +-.15567000000000E+02 +-.14416000000000E+02 +-.13265000000000E+02 +-.12114000000000E+02 +-.10964000000000E+02 +-.98154000000000E+01 +-.86726000000000E+01 +-.75474000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17951000000000E+02 +-.16800000000000E+02 +-.15649000000000E+02 +-.14498000000000E+02 +-.13347000000000E+02 +-.12196000000000E+02 +-.11045000000000E+02 +-.98958000000000E+01 +-.87505000000000E+01 +-.76180000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18035000000000E+02 +-.16883000000000E+02 +-.15732000000000E+02 +-.14581000000000E+02 +-.13430000000000E+02 +-.12279000000000E+02 +-.11128000000000E+02 +-.99783000000000E+01 +-.88313000000000E+01 +-.76936000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18121000000000E+02 +-.16969000000000E+02 +-.15818000000000E+02 +-.14667000000000E+02 +-.13516000000000E+02 +-.12365000000000E+02 +-.11214000000000E+02 +-.10063000000000E+02 +-.89153000000000E+01 +-.77736000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18254000000000E+02 +-.17103000000000E+02 +-.15952000000000E+02 +-.14800000000000E+02 +-.13649000000000E+02 +-.12498000000000E+02 +-.11347000000000E+02 +-.10196000000000E+02 +-.90471000000000E+01 +-.79030000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17284000000000E+02 +-.16132000000000E+02 +-.14981000000000E+02 +-.13830000000000E+02 +-.12679000000000E+02 +-.11528000000000E+02 +-.10377000000000E+02 +-.92271000000000E+01 +-.80808000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17456000000000E+02 +-.16305000000000E+02 +-.15154000000000E+02 +-.14002000000000E+02 +-.12851000000000E+02 +-.11700000000000E+02 +-.10549000000000E+02 +-.93989000000000E+01 +-.82512000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17616000000000E+02 +-.16464000000000E+02 +-.15313000000000E+02 +-.14162000000000E+02 +-.13011000000000E+02 +-.11860000000000E+02 +-.10709000000000E+02 +-.95581000000000E+01 +-.84097000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17782000000000E+02 +-.16630000000000E+02 +-.15479000000000E+02 +-.14328000000000E+02 +-.13177000000000E+02 +-.12026000000000E+02 +-.10875000000000E+02 +-.97239000000000E+01 +-.85745000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17914000000000E+02 +-.16763000000000E+02 +-.15612000000000E+02 +-.14460000000000E+02 +-.13309000000000E+02 +-.12158000000000E+02 +-.11007000000000E+02 +-.98562000000000E+01 +-.87063000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18021000000000E+02 +-.16870000000000E+02 +-.15718000000000E+02 +-.14567000000000E+02 +-.13416000000000E+02 +-.12264000000000E+02 +-.11113000000000E+02 +-.99624000000000E+01 +-.88123000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18136000000000E+02 +-.16984000000000E+02 +-.15833000000000E+02 +-.14682000000000E+02 +-.13531000000000E+02 +-.12379000000000E+02 +-.11228000000000E+02 +-.10077000000000E+02 +-.89270000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18200000000000E+02 +-.17049000000000E+02 +-.15898000000000E+02 +-.14747000000000E+02 +-.13595000000000E+02 +-.12444000000000E+02 +-.11293000000000E+02 +-.10142000000000E+02 +-.89912000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18300000000000E+02 +-.17149000000000E+02 +-.15998000000000E+02 +-.14846000000000E+02 +-.13695000000000E+02 +-.12544000000000E+02 +-.11393000000000E+02 +-.10241000000000E+02 +-.90908000000000E+01 +-.16605000000000E+01 +-.88622000000000E+00 +-.13190000000000E+00 +0.63718000000000E+00 +0.14739000000000E+01 +0.23741000000000E+01 +0.33187000000000E+01 +0.43324000000000E+01 +0.53945000000000E+01 +0.64025000000000E+01 +0.71998000000000E+01 +0.76918000000000E+01 +0.78240000000000E+01 +0.78276000000000E+01 +-.22471000000000E+01 +-.14846000000000E+01 +-.77081000000000E+00 +-.56736000000000E-01 +0.72917000000000E+00 +0.15987000000000E+01 +0.25371000000000E+01 +0.35554000000000E+01 +0.46300000000000E+01 +0.56864000000000E+01 +0.66180000000000E+01 +0.73160000000000E+01 +0.75752000000000E+01 +0.75891000000000E+01 +-.28325000000000E+01 +-.20588000000000E+01 +-.13499000000000E+01 +-.65022000000000E+00 +0.11374000000000E+00 +0.95769000000000E+00 +0.18757000000000E+01 +0.28799000000000E+01 +0.39501000000000E+01 +0.50244000000000E+01 +0.60200000000000E+01 +0.68375000000000E+01 +0.72521000000000E+01 +0.72952000000000E+01 +-.34197000000000E+01 +-.26208000000000E+01 +-.18982000000000E+01 +-.11970000000000E+01 +-.44852000000000E+00 +0.35979000000000E+00 +0.12304000000000E+01 +0.21895000000000E+01 +0.32312000000000E+01 +0.43037000000000E+01 +0.53325000000000E+01 +0.62231000000000E+01 +0.67988000000000E+01 +0.69053000000000E+01 +-.40109000000000E+01 +-.31798000000000E+01 +-.24327000000000E+01 +-.17205000000000E+01 +-.98109000000000E+00 +-.20680000000000E+00 +0.60927000000000E+00 +0.15061000000000E+01 +0.24965000000000E+01 +0.35447000000000E+01 +0.45828000000000E+01 +0.55195000000000E+01 +0.62246000000000E+01 +0.64414000000000E+01 +-.45764000000000E+01 +-.37145000000000E+01 +-.29406000000000E+01 +-.22117000000000E+01 +-.14741000000000E+01 +-.72646000000000E+00 +0.39620000000000E-01 +0.86960000000000E+00 +0.17902000000000E+01 +0.27884000000000E+01 +0.38134000000000E+01 +0.47781000000000E+01 +0.55730000000000E+01 +0.59503000000000E+01 +-.51508000000000E+01 +-.42622000000000E+01 +-.34646000000000E+01 +-.27208000000000E+01 +-.19814000000000E+01 +-.12501000000000E+01 +-.52165000000000E+00 +0.24723000000000E+00 +0.10893000000000E+01 +0.20142000000000E+01 +0.29976000000000E+01 +0.39669000000000E+01 +0.48185000000000E+01 +0.53661000000000E+01 +-.57742000000000E+01 +-.48549000000000E+01 +-.40256000000000E+01 +-.32586000000000E+01 +-.25096000000000E+01 +-.17843000000000E+01 +-.10814000000000E+01 +-.36281000000000E+00 +0.40382000000000E+00 +0.12432000000000E+01 +0.21592000000000E+01 +0.31062000000000E+01 +0.39885000000000E+01 +0.46702000000000E+01 +-.64559000000000E+01 +-.55039000000000E+01 +-.46378000000000E+01 +-.38396000000000E+01 +-.30710000000000E+01 +-.23370000000000E+01 +-.16416000000000E+01 +-.95540000000000E+00 +-.24756000000000E+00 +0.51651000000000E+00 +0.13613000000000E+01 +0.22685000000000E+01 +0.31591000000000E+01 +0.39224000000000E+01 +-.72107000000000E+01 +-.62284000000000E+01 +-.53262000000000E+01 +-.44951000000000E+01 +-.37009000000000E+01 +-.29454000000000E+01 +-.22390000000000E+01 +-.15603000000000E+01 +-.87939000000000E+00 +-.15852000000000E+00 +0.63466000000000E+00 +0.15009000000000E+01 +0.23846000000000E+01 +0.31893000000000E+01 +-.80034000000000E+01 +-.69915000000000E+01 +-.60509000000000E+01 +-.51810000000000E+01 +-.43552000000000E+01 +-.35713000000000E+01 +-.28419000000000E+01 +-.21508000000000E+01 +-.14691000000000E+01 +-.76024000000000E+00 +0.58420000000000E-02 +0.83893000000000E+00 +0.17078000000000E+01 +0.25329000000000E+01 +-.88042000000000E+01 +-.77650000000000E+01 +-.67874000000000E+01 +-.58768000000000E+01 +-.50156000000000E+01 +-.41979000000000E+01 +-.34351000000000E+01 +-.27141000000000E+01 +-.20093000000000E+01 +-.12899000000000E+01 +-.53098000000000E+00 +0.28088000000000E+00 +0.11342000000000E+01 +0.19696000000000E+01 +-.95952000000000E+01 +-.85337000000000E+01 +-.75244000000000E+01 +-.65771000000000E+01 +-.56810000000000E+01 +-.48270000000000E+01 +-.40231000000000E+01 +-.32593000000000E+01 +-.25148000000000E+01 +-.17666000000000E+01 +-.99713000000000E+00 +-.19272000000000E+00 +0.64906000000000E+00 +0.14887000000000E+01 +-.10339000000000E+02 +-.92585000000000E+01 +-.82212000000000E+01 +-.72388000000000E+01 +-.63062000000000E+01 +-.54124000000000E+01 +-.45632000000000E+01 +-.37548000000000E+01 +-.29706000000000E+01 +-.21938000000000E+01 +-.14113000000000E+01 +-.61037000000000E+00 +0.21816000000000E+00 +0.10510000000000E+01 +-.11025000000000E+02 +-.99294000000000E+01 +-.88689000000000E+01 +-.78553000000000E+01 +-.68888000000000E+01 +-.59587000000000E+01 +-.50687000000000E+01 +-.42200000000000E+01 +-.33986000000000E+01 +-.25897000000000E+01 +-.17865000000000E+01 +-.98219000000000E+00 +-.16651000000000E+00 +0.65048000000000E+00 +-.11632000000000E+02 +-.10526000000000E+02 +-.94490000000000E+01 +-.84128000000000E+01 +-.74210000000000E+01 +-.64629000000000E+01 +-.55385000000000E+01 +-.46517000000000E+01 +-.37925000000000E+01 +-.29503000000000E+01 +-.21254000000000E+01 +-.13162000000000E+01 +-.51347000000000E+00 +0.28193000000000E+00 +-.12166000000000E+02 +-.11051000000000E+02 +-.99617000000000E+01 +-.89077000000000E+01 +-.78947000000000E+01 +-.69147000000000E+01 +-.59636000000000E+01 +-.50454000000000E+01 +-.41545000000000E+01 +-.32858000000000E+01 +-.24419000000000E+01 +-.16261000000000E+01 +-.83307000000000E+00 +-.57822000000000E-01 +-.12671000000000E+02 +-.11550000000000E+02 +-.10449000000000E+02 +-.93792000000000E+01 +-.83464000000000E+01 +-.73464000000000E+01 +-.63722000000000E+01 +-.54264000000000E+01 +-.45073000000000E+01 +-.36132000000000E+01 +-.27485000000000E+01 +-.19216000000000E+01 +-.11331000000000E+01 +-.37550000000000E+00 +-.13150000000000E+02 +-.12023000000000E+02 +-.10912000000000E+02 +-.98276000000000E+01 +-.87764000000000E+01 +-.77571000000000E+01 +-.67617000000000E+01 +-.57919000000000E+01 +-.48484000000000E+01 +-.39318000000000E+01 +-.30496000000000E+01 +-.22130000000000E+01 +-.14275000000000E+01 +-.68761000000000E+00 +-.13623000000000E+02 +-.12491000000000E+02 +-.11373000000000E+02 +-.10275000000000E+02 +-.92070000000000E+01 +-.81692000000000E+01 +-.71553000000000E+01 +-.61655000000000E+01 +-.52030000000000E+01 +-.42679000000000E+01 +-.33692000000000E+01 +-.25231000000000E+01 +-.17401000000000E+01 +-.10210000000000E+01 +-.14122000000000E+02 +-.12986000000000E+02 +-.11861000000000E+02 +-.10753000000000E+02 +-.96707000000000E+01 +-.86174000000000E+01 +-.75895000000000E+01 +-.65852000000000E+01 +-.56071000000000E+01 +-.46552000000000E+01 +-.37404000000000E+01 +-.28854000000000E+01 +-.21088000000000E+01 +-.14155000000000E+01 +-.14670000000000E+02 +-.13531000000000E+02 +-.12400000000000E+02 +-.11284000000000E+02 +-.10189000000000E+02 +-.91208000000000E+01 +-.80798000000000E+01 +-.70631000000000E+01 +-.60717000000000E+01 +-.51056000000000E+01 +-.41763000000000E+01 +-.33099000000000E+01 +-.25342000000000E+01 +-.18617000000000E+01 +-.15284000000000E+02 +-.14143000000000E+02 +-.13008000000000E+02 +-.11884000000000E+02 +-.10779000000000E+02 +-.96978000000000E+01 +-.86436000000000E+01 +-.76143000000000E+01 +-.66097000000000E+01 +-.56306000000000E+01 +-.46871000000000E+01 +-.38055000000000E+01 +-.30214000000000E+01 +-.23573000000000E+01 +-.15945000000000E+02 +-.14802000000000E+02 +-.13664000000000E+02 +-.12535000000000E+02 +-.11420000000000E+02 +-.10327000000000E+02 +-.92603000000000E+01 +-.82187000000000E+01 +-.72029000000000E+01 +-.62134000000000E+01 +-.52582000000000E+01 +-.43619000000000E+01 +-.35625000000000E+01 +-.28900000000000E+01 +-.16638000000000E+02 +-.15493000000000E+02 +-.14352000000000E+02 +-.13219000000000E+02 +-.12097000000000E+02 +-.10994000000000E+02 +-.99143000000000E+01 +-.88599000000000E+01 +-.78323000000000E+01 +-.68323000000000E+01 +-.58650000000000E+01 +-.49523000000000E+01 +-.41317000000000E+01 +-.34378000000000E+01 +-.17333000000000E+02 +-.16187000000000E+02 +-.15045000000000E+02 +-.13909000000000E+02 +-.12783000000000E+02 +-.11673000000000E+02 +-.10584000000000E+02 +-.95190000000000E+01 +-.84797000000000E+01 +-.74681000000000E+01 +-.64879000000000E+01 +-.55573000000000E+01 +-.47136000000000E+01 +-.39927000000000E+01 +-.17993000000000E+02 +-.16846000000000E+02 +-.15702000000000E+02 +-.14564000000000E+02 +-.13434000000000E+02 +-.12318000000000E+02 +-.11222000000000E+02 +-.10148000000000E+02 +-.90974000000000E+01 +-.80740000000000E+01 +-.70819000000000E+01 +-.61360000000000E+01 +-.52699000000000E+01 +-.45214000000000E+01 +-.18420000000000E+02 +-.17447000000000E+02 +-.16302000000000E+02 +-.15162000000000E+02 +-.14029000000000E+02 +-.12908000000000E+02 +-.11805000000000E+02 +-.10722000000000E+02 +-.96614000000000E+01 +-.86257000000000E+01 +-.76212000000000E+01 +-.66589000000000E+01 +-.57683000000000E+01 +-.49890000000000E+01 +-.18420000000000E+02 +-.17967000000000E+02 +-.16821000000000E+02 +-.15679000000000E+02 +-.14543000000000E+02 +-.13418000000000E+02 +-.12308000000000E+02 +-.11218000000000E+02 +-.10147000000000E+02 +-.90991000000000E+01 +-.80813000000000E+01 +-.71039000000000E+01 +-.61914000000000E+01 +-.53804000000000E+01 +-.18420000000000E+02 +-.18409000000000E+02 +-.17262000000000E+02 +-.16119000000000E+02 +-.14980000000000E+02 +-.13851000000000E+02 +-.12735000000000E+02 +-.11637000000000E+02 +-.10557000000000E+02 +-.94980000000000E+01 +-.84666000000000E+01 +-.74735000000000E+01 +-.65399000000000E+01 +-.56995000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.17634000000000E+02 +-.16489000000000E+02 +-.15349000000000E+02 +-.14216000000000E+02 +-.13095000000000E+02 +-.11990000000000E+02 +-.10903000000000E+02 +-.98359000000000E+01 +-.87937000000000E+01 +-.77859000000000E+01 +-.68329000000000E+01 +-.59667000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.17955000000000E+02 +-.16809000000000E+02 +-.15667000000000E+02 +-.14531000000000E+02 +-.13405000000000E+02 +-.12294000000000E+02 +-.11201000000000E+02 +-.10127000000000E+02 +-.90762000000000E+01 +-.80552000000000E+01 +-.70837000000000E+01 +-.61937000000000E+01 +0.82329000000000E+01 +0.87041000000000E+01 +0.92195000000000E+01 +0.96541000000000E+01 +0.10005000000000E+02 +0.10270000000000E+02 +0.10765000000000E+02 +0.10758000000000E+02 +0.10689000000000E+02 +0.11055000000000E+02 +0.11007000000000E+02 +0.10821000000000E+02 +0.11082000000000E+02 +0.11279000000000E+02 +0.66826000000000E+01 +0.78170000000000E+01 +0.87141000000000E+01 +0.93245000000000E+01 +0.96741000000000E+01 +0.10337000000000E+02 +0.10487000000000E+02 +0.10640000000000E+02 +0.10575000000000E+02 +0.10909000000000E+02 +0.10795000000000E+02 +0.10344000000000E+02 +0.10548000000000E+02 +0.10746000000000E+02 +0.52358000000000E+01 +0.64879000000000E+01 +0.76406000000000E+01 +0.92642000000000E+01 +0.99587000000000E+01 +0.10314000000000E+02 +0.10490000000000E+02 +0.10485000000000E+02 +0.10427000000000E+02 +0.10668000000000E+02 +0.10581000000000E+02 +0.99734000000000E+01 +0.10046000000000E+02 +0.10246000000000E+02 +0.41168000000000E+01 +0.54841000000000E+01 +0.72866000000000E+01 +0.85403000000000E+01 +0.94717000000000E+01 +0.99280000000000E+01 +0.10093000000000E+02 +0.10177000000000E+02 +0.10213000000000E+02 +0.10277000000000E+02 +0.10262000000000E+02 +0.97024000000000E+01 +0.95959000000000E+01 +0.97954000000000E+01 +0.34390000000000E+01 +0.47344000000000E+01 +0.65468000000000E+01 +0.78414000000000E+01 +0.88923000000000E+01 +0.94104000000000E+01 +0.95964000000000E+01 +0.96790000000000E+01 +0.97837000000000E+01 +0.98403000000000E+01 +0.98982000000000E+01 +0.95034000000000E+01 +0.92571000000000E+01 +0.94526000000000E+01 +0.29150000000000E+01 +0.39286000000000E+01 +0.50415000000000E+01 +0.72131000000000E+01 +0.82644000000000E+01 +0.88784000000000E+01 +0.91309000000000E+01 +0.92493000000000E+01 +0.93564000000000E+01 +0.94680000000000E+01 +0.95923000000000E+01 +0.93628000000000E+01 +0.90767000000000E+01 +0.92544000000000E+01 +0.24839000000000E+01 +0.33400000000000E+01 +0.41403000000000E+01 +0.53425000000000E+01 +0.75771000000000E+01 +0.83193000000000E+01 +0.86956000000000E+01 +0.89033000000000E+01 +0.90627000000000E+01 +0.91880000000000E+01 +0.93850000000000E+01 +0.92937000000000E+01 +0.90417000000000E+01 +0.92046000000000E+01 +0.19572000000000E+01 +0.29386000000000E+01 +0.38452000000000E+01 +0.49943000000000E+01 +0.67124000000000E+01 +0.76711000000000E+01 +0.82266000000000E+01 +0.85457000000000E+01 +0.87827000000000E+01 +0.89695000000000E+01 +0.92559000000000E+01 +0.93074000000000E+01 +0.91279000000000E+01 +0.92725000000000E+01 +0.12265000000000E+01 +0.22694000000000E+01 +0.33314000000000E+01 +0.43131000000000E+01 +0.54657000000000E+01 +0.69475000000000E+01 +0.76732000000000E+01 +0.81641000000000E+01 +0.85166000000000E+01 +0.87893000000000E+01 +0.91641000000000E+01 +0.93562000000000E+01 +0.92661000000000E+01 +0.93894000000000E+01 +0.48929000000000E+00 +0.15291000000000E+01 +0.26371000000000E+01 +0.37098000000000E+01 +0.49253000000000E+01 +0.60244000000000E+01 +0.70674000000000E+01 +0.77462000000000E+01 +0.82410000000000E+01 +0.86082000000000E+01 +0.90825000000000E+01 +0.94092000000000E+01 +0.94390000000000E+01 +0.95295000000000E+01 +-.21815000000000E+00 +0.86110000000000E+00 +0.20236000000000E+01 +0.30576000000000E+01 +0.42595000000000E+01 +0.53944000000000E+01 +0.64181000000000E+01 +0.72561000000000E+01 +0.79083000000000E+01 +0.84136000000000E+01 +0.88228000000000E+01 +0.94456000000000E+01 +0.96118000000000E+01 +0.96885000000000E+01 +-.93744000000000E+00 +0.11635000000000E+00 +0.12655000000000E+01 +0.25287000000000E+01 +0.36440000000000E+01 +0.48113000000000E+01 +0.58527000000000E+01 +0.67843000000000E+01 +0.75806000000000E+01 +0.82158000000000E+01 +0.87451000000000E+01 +0.94871000000000E+01 +0.97954000000000E+01 +0.98958000000000E+01 +-.12915000000000E+01 +-.33388000000000E+00 +0.72850000000000E+00 +0.19128000000000E+01 +0.31865000000000E+01 +0.43945000000000E+01 +0.54258000000000E+01 +0.63911000000000E+01 +0.72672000000000E+01 +0.80330000000000E+01 +0.86836000000000E+01 +0.95193000000000E+01 +0.99578000000000E+01 +0.10113000000000E+02 +-.17696000000000E+01 +-.69203000000000E+00 +0.32519000000000E+00 +0.14988000000000E+01 +0.27243000000000E+01 +0.39648000000000E+01 +0.51134000000000E+01 +0.60874000000000E+01 +0.70023000000000E+01 +0.78518000000000E+01 +0.85996000000000E+01 +0.95032000000000E+01 +0.10051000000000E+02 +0.10284000000000E+02 +-.20520000000000E+01 +-.10742000000000E+01 +0.43238000000000E-02 +0.11821000000000E+01 +0.24022000000000E+01 +0.35925000000000E+01 +0.48101000000000E+01 +0.58445000000000E+01 +0.67800000000000E+01 +0.76686000000000E+01 +0.85203000000000E+01 +0.94404000000000E+01 +0.10080000000000E+02 +0.10406000000000E+02 +-.23376000000000E+01 +-.13503000000000E+01 +-.31283000000000E+00 +0.86122000000000E+00 +0.19884000000000E+01 +0.32462000000000E+01 +0.44425000000000E+01 +0.55457000000000E+01 +0.65563000000000E+01 +0.74910000000000E+01 +0.83826000000000E+01 +0.92761000000000E+01 +0.10053000000000E+02 +0.10479000000000E+02 +-.26317000000000E+01 +-.16302000000000E+01 +-.59505000000000E+00 +0.54951000000000E+00 +0.16748000000000E+01 +0.28992000000000E+01 +0.40830000000000E+01 +0.52076000000000E+01 +0.62806000000000E+01 +0.72832000000000E+01 +0.82234000000000E+01 +0.91511000000000E+01 +0.99912000000000E+01 +0.10508000000000E+02 +-.29283000000000E+01 +-.19129000000000E+01 +-.87799000000000E+00 +0.24328000000000E+00 +0.13659000000000E+01 +0.25641000000000E+01 +0.37352000000000E+01 +0.48699000000000E+01 +0.59768000000000E+01 +0.70336000000000E+01 +0.80339000000000E+01 +0.89988000000000E+01 +0.98799000000000E+01 +0.10491000000000E+02 +-.32261000000000E+01 +-.22000000000000E+01 +-.11644000000000E+01 +-.61447000000000E-01 +0.10569000000000E+01 +0.22354000000000E+01 +0.33978000000000E+01 +0.45366000000000E+01 +0.56593000000000E+01 +0.67511000000000E+01 +0.78015000000000E+01 +0.88103000000000E+01 +0.97339000000000E+01 +0.10427000000000E+02 +-.35264000000000E+01 +-.24925000000000E+01 +-.14563000000000E+01 +-.36823000000000E+00 +0.74425000000000E+00 +0.19083000000000E+01 +0.30643000000000E+01 +0.42056000000000E+01 +0.53369000000000E+01 +0.64490000000000E+01 +0.75341000000000E+01 +0.85842000000000E+01 +0.95540000000000E+01 +0.10323000000000E+02 +-.38292000000000E+01 +-.27889000000000E+01 +-.17523000000000E+01 +-.67674000000000E+00 +0.42847000000000E+00 +0.15809000000000E+01 +0.27322000000000E+01 +0.38749000000000E+01 +0.50117000000000E+01 +0.61362000000000E+01 +0.72433000000000E+01 +0.83254000000000E+01 +0.93396000000000E+01 +0.10180000000000E+02 +-.40967000000000E+01 +-.30510000000000E+01 +-.20134000000000E+01 +-.94731000000000E+00 +0.15088000000000E+00 +0.12933000000000E+01 +0.24406000000000E+01 +0.35844000000000E+01 +0.47250000000000E+01 +0.58585000000000E+01 +0.69771000000000E+01 +0.80840000000000E+01 +0.91375000000000E+01 +0.10048000000000E+02 +-.43389000000000E+01 +-.32881000000000E+01 +-.22493000000000E+01 +-.11905000000000E+01 +-.99228000000000E-01 +0.10345000000000E+01 +0.21785000000000E+01 +0.33229000000000E+01 +0.44663000000000E+01 +0.56055000000000E+01 +0.67347000000000E+01 +0.78568000000000E+01 +0.89426000000000E+01 +0.99058000000000E+01 +-.45991000000000E+01 +-.35424000000000E+01 +-.25020000000000E+01 +-.14496000000000E+01 +-.36652000000000E+00 +0.75870000000000E+00 +0.18994000000000E+01 +0.30439000000000E+01 +0.41888000000000E+01 +0.53314000000000E+01 +0.64674000000000E+01 +0.75986000000000E+01 +0.87039000000000E+01 +0.97151000000000E+01 +-.48751000000000E+01 +-.38119000000000E+01 +-.27686000000000E+01 +-.17215000000000E+01 +-.64731000000000E+00 +0.46891000000000E+00 +0.16057000000000E+01 +0.27497000000000E+01 +0.38956000000000E+01 +0.50404000000000E+01 +0.61808000000000E+01 +0.73184000000000E+01 +0.84375000000000E+01 +0.94866000000000E+01 +-.51637000000000E+01 +-.40934000000000E+01 +-.30458000000000E+01 +-.20021000000000E+01 +-.93697000000000E+00 +0.16940000000000E+00 +0.13015000000000E+01 +0.24442000000000E+01 +0.35906000000000E+01 +0.47368000000000E+01 +0.58801000000000E+01 +0.70220000000000E+01 +0.81511000000000E+01 +0.92285000000000E+01 +-.54623000000000E+01 +-.43846000000000E+01 +-.33316000000000E+01 +-.22891000000000E+01 +-.12323000000000E+01 +-.13660000000000E+00 +0.98953000000000E+00 +0.21304000000000E+01 +0.32766000000000E+01 +0.44237000000000E+01 +0.55691000000000E+01 +0.67139000000000E+01 +0.78500000000000E+01 +0.89480000000000E+01 +-.57681000000000E+01 +-.46832000000000E+01 +-.36237000000000E+01 +-.25803000000000E+01 +-.15303000000000E+01 +-.44576000000000E+00 +0.67308000000000E+00 +0.18111000000000E+01 +0.29567000000000E+01 +0.41042000000000E+01 +0.52511000000000E+01 +0.63979000000000E+01 +0.75388000000000E+01 +0.86521000000000E+01 +-.60802000000000E+01 +-.49883000000000E+01 +-.39215000000000E+01 +-.28752000000000E+01 +-.18301000000000E+01 +-.75656000000000E+00 +0.35358000000000E+00 +0.14877000000000E+01 +0.26321000000000E+01 +0.37798000000000E+01 +0.49275000000000E+01 +0.60757000000000E+01 +0.72198000000000E+01 +0.83440000000000E+01 +-.63979000000000E+01 +-.52992000000000E+01 +-.42250000000000E+01 +-.31740000000000E+01 +-.21314000000000E+01 +-.10681000000000E+01 +0.32085000000000E-01 +0.11610000000000E+01 +0.23036000000000E+01 +0.34510000000000E+01 +0.45992000000000E+01 +0.57483000000000E+01 +0.68948000000000E+01 +0.80269000000000E+01 +-.67198000000000E+01 +-.56151000000000E+01 +-.45334000000000E+01 +-.34764000000000E+01 +-.24340000000000E+01 +-.13793000000000E+01 +-.29005000000000E+00 +0.83221000000000E+00 +0.19722000000000E+01 +0.31190000000000E+01 +0.42675000000000E+01 +0.54171000000000E+01 +0.65651000000000E+01 +0.77026000000000E+01 +-.70039000000000E+01 +-.58937000000000E+01 +-.48058000000000E+01 +-.37430000000000E+01 +-.26987000000000E+01 +-.16500000000000E+01 +-.57047000000000E+00 +0.54482000000000E+00 +0.16818000000000E+01 +0.28276000000000E+01 +0.39763000000000E+01 +0.51261000000000E+01 +0.62750000000000E+01 +0.74166000000000E+01 +0.80183000000000E+01 +0.80398000000000E+01 +0.80603000000000E+01 +0.80999000000000E+01 +0.81133000000000E+01 +0.81255000000000E+01 +0.81306000000000E+01 +0.81465000000000E+01 +0.81455000000000E+01 +0.81377000000000E+01 +0.84958000000000E+01 +0.87151000000000E+01 +0.93865000000000E+01 +0.97244000000000E+01 +0.79341000000000E+01 +0.79696000000000E+01 +0.80005000000000E+01 +0.80312000000000E+01 +0.80901000000000E+01 +0.81062000000000E+01 +0.81323000000000E+01 +0.81382000000000E+01 +0.81682000000000E+01 +0.81360000000000E+01 +0.86460000000000E+01 +0.86868000000000E+01 +0.93545000000000E+01 +0.96882000000000E+01 +0.77899000000000E+01 +0.78591000000000E+01 +0.79146000000000E+01 +0.79590000000000E+01 +0.80154000000000E+01 +0.80842000000000E+01 +0.81062000000000E+01 +0.81541000000000E+01 +0.81572000000000E+01 +0.81516000000000E+01 +0.88228000000000E+01 +0.86636000000000E+01 +0.93083000000000E+01 +0.96365000000000E+01 +0.75210000000000E+01 +0.76653000000000E+01 +0.77751000000000E+01 +0.78571000000000E+01 +0.79208000000000E+01 +0.80125000000000E+01 +0.80889000000000E+01 +0.81770000000000E+01 +0.81899000000000E+01 +0.81853000000000E+01 +0.89824000000000E+01 +0.86594000000000E+01 +0.92405000000000E+01 +0.95605000000000E+01 +0.69821000000000E+01 +0.73030000000000E+01 +0.75298000000000E+01 +0.76906000000000E+01 +0.78082000000000E+01 +0.78966000000000E+01 +0.80330000000000E+01 +0.81106000000000E+01 +0.82295000000000E+01 +0.82334000000000E+01 +0.90881000000000E+01 +0.86809000000000E+01 +0.91421000000000E+01 +0.94509000000000E+01 +0.58337000000000E+01 +0.65105000000000E+01 +0.70692000000000E+01 +0.74016000000000E+01 +0.76254000000000E+01 +0.77843000000000E+01 +0.79012000000000E+01 +0.80818000000000E+01 +0.81526000000000E+01 +0.82852000000000E+01 +0.91145000000000E+01 +0.87195000000000E+01 +0.90002000000000E+01 +0.93003000000000E+01 +0.41765000000000E+01 +0.52355000000000E+01 +0.61530000000000E+01 +0.68909000000000E+01 +0.73159000000000E+01 +0.76016000000000E+01 +0.78007000000000E+01 +0.80588000000000E+01 +0.81494000000000E+01 +0.83210000000000E+01 +0.90591000000000E+01 +0.87471000000000E+01 +0.88518000000000E+01 +0.91162000000000E+01 +0.26322000000000E+01 +0.38174000000000E+01 +0.48248000000000E+01 +0.58298000000000E+01 +0.68096000000000E+01 +0.74567000000000E+01 +0.77794000000000E+01 +0.78579000000000E+01 +0.81321000000000E+01 +0.82158000000000E+01 +0.89509000000000E+01 +0.87349000000000E+01 +0.87227000000000E+01 +0.89385000000000E+01 +0.12853000000000E+01 +0.25042000000000E+01 +0.35876000000000E+01 +0.47450000000000E+01 +0.57908000000000E+01 +0.66770000000000E+01 +0.77861000000000E+01 +0.81672000000000E+01 +0.83762000000000E+01 +0.81938000000000E+01 +0.88237000000000E+01 +0.86870000000000E+01 +0.86250000000000E+01 +0.87896000000000E+01 +0.30902000000000E+00 +0.14916000000000E+01 +0.25807000000000E+01 +0.36612000000000E+01 +0.48328000000000E+01 +0.58984000000000E+01 +0.72751000000000E+01 +0.78839000000000E+01 +0.82305000000000E+01 +0.85842000000000E+01 +0.86929000000000E+01 +0.86208000000000E+01 +0.85579000000000E+01 +0.86833000000000E+01 +-.22738000000000E+00 +0.78183000000000E+00 +0.17647000000000E+01 +0.28109000000000E+01 +0.40131000000000E+01 +0.50291000000000E+01 +0.62175000000000E+01 +0.73666000000000E+01 +0.79147000000000E+01 +0.83779000000000E+01 +0.85486000000000E+01 +0.85454000000000E+01 +0.85161000000000E+01 +0.86194000000000E+01 +-.74518000000000E+00 +0.31135000000000E+00 +0.12581000000000E+01 +0.21984000000000E+01 +0.31801000000000E+01 +0.43153000000000E+01 +0.54209000000000E+01 +0.66742000000000E+01 +0.74388000000000E+01 +0.80254000000000E+01 +0.83689000000000E+01 +0.84524000000000E+01 +0.84807000000000E+01 +0.85874000000000E+01 +-.15631000000000E+01 +-.41999000000000E+00 +0.65567000000000E+00 +0.16840000000000E+01 +0.26658000000000E+01 +0.37197000000000E+01 +0.47844000000000E+01 +0.58170000000000E+01 +0.68596000000000E+01 +0.76454000000000E+01 +0.81257000000000E+01 +0.83301000000000E+01 +0.84395000000000E+01 +0.85747000000000E+01 +-.22975000000000E+01 +-.11931000000000E+01 +-.90471000000000E-01 +0.10095000000000E+01 +0.20900000000000E+01 +0.31799000000000E+01 +0.42262000000000E+01 +0.52445000000000E+01 +0.62661000000000E+01 +0.71526000000000E+01 +0.78162000000000E+01 +0.81685000000000E+01 +0.83855000000000E+01 +0.85762000000000E+01 +-.29675000000000E+01 +-.18760000000000E+01 +-.78297000000000E+00 +0.32513000000000E+00 +0.14406000000000E+01 +0.25815000000000E+01 +0.36777000000000E+01 +0.47189000000000E+01 +0.57091000000000E+01 +0.66748000000000E+01 +0.74449000000000E+01 +0.79647000000000E+01 +0.83083000000000E+01 +0.85759000000000E+01 +-.35662000000000E+01 +-.24804000000000E+01 +-.13927000000000E+01 +-.29095000000000E+00 +0.82950000000000E+00 +0.19820000000000E+01 +0.31107000000000E+01 +0.41989000000000E+01 +0.52334000000000E+01 +0.62241000000000E+01 +0.70718000000000E+01 +0.77277000000000E+01 +0.81965000000000E+01 +0.85540000000000E+01 +-.41104000000000E+01 +-.30146000000000E+01 +-.19295000000000E+01 +-.83447000000000E+00 +0.28400000000000E+00 +0.14347000000000E+01 +0.25728000000000E+01 +0.36879000000000E+01 +0.47675000000000E+01 +0.58013000000000E+01 +0.67118000000000E+01 +0.74681000000000E+01 +0.80605000000000E+01 +0.85107000000000E+01 +-.46102000000000E+01 +-.34977000000000E+01 +-.24066000000000E+01 +-.13158000000000E+01 +-.20223000000000E+00 +0.94296000000000E+00 +0.20828000000000E+01 +0.32093000000000E+01 +0.43160000000000E+01 +0.53909000000000E+01 +0.63628000000000E+01 +0.72041000000000E+01 +0.79028000000000E+01 +0.84531000000000E+01 +-.50737000000000E+01 +-.39462000000000E+01 +-.28428000000000E+01 +-.17511000000000E+01 +-.64281000000000E+00 +0.49548000000000E+00 +0.16342000000000E+01 +0.27662000000000E+01 +0.38874000000000E+01 +0.49893000000000E+01 +0.60148000000000E+01 +0.69314000000000E+01 +0.77208000000000E+01 +0.83618000000000E+01 +-.55052000000000E+01 +-.43678000000000E+01 +-.32510000000000E+01 +-.21530000000000E+01 +-.10481000000000E+01 +0.82834000000000E-01 +0.12192000000000E+01 +0.23537000000000E+01 +0.34832000000000E+01 +0.46019000000000E+01 +0.56654000000000E+01 +0.66453000000000E+01 +0.75148000000000E+01 +0.82397000000000E+01 +-.59116000000000E+01 +-.47686000000000E+01 +-.36408000000000E+01 +-.25330000000000E+01 +-.14284000000000E+01 +-.30439000000000E+00 +0.82854000000000E+00 +0.19641000000000E+01 +0.30984000000000E+01 +0.42266000000000E+01 +0.53164000000000E+01 +0.63447000000000E+01 +0.72830000000000E+01 +0.80867000000000E+01 +-.62881000000000E+01 +-.51420000000000E+01 +-.40066000000000E+01 +-.28887000000000E+01 +-.17809000000000E+01 +-.66234000000000E+00 +0.46660000000000E+00 +0.16020000000000E+01 +0.27394000000000E+01 +0.38736000000000E+01 +0.49813000000000E+01 +0.60450000000000E+01 +0.70398000000000E+01 +0.79175000000000E+01 +-.66249000000000E+01 +-.54771000000000E+01 +-.43367000000000E+01 +-.32104000000000E+01 +-.20973000000000E+01 +-.98186000000000E+00 +0.14315000000000E+00 +0.12777000000000E+01 +0.24169000000000E+01 +0.35552000000000E+01 +0.46757000000000E+01 +0.57653000000000E+01 +0.68040000000000E+01 +0.77465000000000E+01 +-.69564000000000E+01 +-.58075000000000E+01 +-.46639000000000E+01 +-.35312000000000E+01 +-.24122000000000E+01 +-.12977000000000E+01 +-.17656000000000E+00 +0.95621000000000E+00 +0.20962000000000E+01 +0.32370000000000E+01 +0.43661000000000E+01 +0.54733000000000E+01 +0.65436000000000E+01 +0.75385000000000E+01 +-.72867000000000E+01 +-.61372000000000E+01 +-.49915000000000E+01 +-.38540000000000E+01 +-.27290000000000E+01 +-.16135000000000E+01 +-.49574000000000E+00 +0.63445000000000E+00 +0.17742000000000E+01 +0.29166000000000E+01 +0.40514000000000E+01 +0.51708000000000E+01 +0.62638000000000E+01 +0.72996000000000E+01 +-.76178000000000E+01 +-.64678000000000E+01 +-.53206000000000E+01 +-.41794000000000E+01 +-.30491000000000E+01 +-.19310000000000E+01 +-.81566000000000E+00 +0.31129000000000E+00 +0.14500000000000E+01 +0.25930000000000E+01 +0.37318000000000E+01 +0.48597000000000E+01 +0.59690000000000E+01 +0.70356000000000E+01 +-.78948000000000E+01 +-.67444000000000E+01 +-.55962000000000E+01 +-.44526000000000E+01 +-.33183000000000E+01 +-.21970000000000E+01 +-.10826000000000E+01 +0.41553000000000E-01 +0.11789000000000E+01 +0.23224000000000E+01 +0.34641000000000E+01 +0.45988000000000E+01 +0.57200000000000E+01 +0.68104000000000E+01 +-.81470000000000E+01 +-.69963000000000E+01 +-.58474000000000E+01 +-.47021000000000E+01 +-.35646000000000E+01 +-.24402000000000E+01 +-.13257000000000E+01 +-.20399000000000E+00 +0.93170000000000E+00 +0.20751000000000E+01 +0.32189000000000E+01 +0.43583000000000E+01 +0.54883000000000E+01 +0.65961000000000E+01 +-.84219000000000E+01 +-.72711000000000E+01 +-.61216000000000E+01 +-.49749000000000E+01 +-.38346000000000E+01 +-.27065000000000E+01 +-.15910000000000E+01 +-.47195000000000E+00 +0.66127000000000E+00 +0.18040000000000E+01 +0.29489000000000E+01 +0.40913000000000E+01 +0.52273000000000E+01 +0.63475000000000E+01 +-.87134000000000E+01 +-.75625000000000E+01 +-.64125000000000E+01 +-.52646000000000E+01 +-.41218000000000E+01 +-.29901000000000E+01 +-.18724000000000E+01 +-.75562000000000E+00 +0.37449000000000E+00 +0.15159000000000E+01 +0.26611000000000E+01 +0.38056000000000E+01 +0.49458000000000E+01 +0.60747000000000E+01 +-.90168000000000E+01 +-.78658000000000E+01 +-.67156000000000E+01 +-.55669000000000E+01 +-.44221000000000E+01 +-.32866000000000E+01 +-.21658000000000E+01 +-.10505000000000E+01 +0.76046000000000E-01 +0.12154000000000E+01 +0.23605000000000E+01 +0.35062000000000E+01 +0.46493000000000E+01 +0.57844000000000E+01 +-.93232000000000E+01 +-.81721000000000E+01 +-.70216000000000E+01 +-.58723000000000E+01 +-.47260000000000E+01 +-.35872000000000E+01 +-.24626000000000E+01 +-.13475000000000E+01 +-.22455000000000E+00 +0.91222000000000E+00 +0.20566000000000E+01 +0.32030000000000E+01 +0.43481000000000E+01 +0.54877000000000E+01 +0.79482000000000E+01 +0.79525000000000E+01 +0.79563000000000E+01 +0.79594000000000E+01 +0.79619000000000E+01 +0.79639000000000E+01 +0.79652000000000E+01 +0.79661000000000E+01 +0.79661000000000E+01 +0.79669000000000E+01 +0.79934000000000E+01 +0.80659000000000E+01 +0.80530000000000E+01 +0.83943000000000E+01 +0.79248000000000E+01 +0.79307000000000E+01 +0.79359000000000E+01 +0.79406000000000E+01 +0.79445000000000E+01 +0.79476000000000E+01 +0.79500000000000E+01 +0.79514000000000E+01 +0.79519000000000E+01 +0.79528000000000E+01 +0.79791000000000E+01 +0.80518000000000E+01 +0.80435000000000E+01 +0.83757000000000E+01 +0.78873000000000E+01 +0.78967000000000E+01 +0.79048000000000E+01 +0.79116000000000E+01 +0.79175000000000E+01 +0.79226000000000E+01 +0.79266000000000E+01 +0.79294000000000E+01 +0.79307000000000E+01 +0.79316000000000E+01 +0.79579000000000E+01 +0.80305000000000E+01 +0.80322000000000E+01 +0.83501000000000E+01 +0.78284000000000E+01 +0.78441000000000E+01 +0.78574000000000E+01 +0.78684000000000E+01 +0.78774000000000E+01 +0.78853000000000E+01 +0.78918000000000E+01 +0.78969000000000E+01 +0.78997000000000E+01 +0.79015000000000E+01 +0.79265000000000E+01 +0.80007000000000E+01 +0.80183000000000E+01 +0.83206000000000E+01 +0.77362000000000E+01 +0.77638000000000E+01 +0.77859000000000E+01 +0.78038000000000E+01 +0.78186000000000E+01 +0.78307000000000E+01 +0.78411000000000E+01 +0.78495000000000E+01 +0.78550000000000E+01 +0.78586000000000E+01 +0.78827000000000E+01 +0.79564000000000E+01 +0.79971000000000E+01 +0.82842000000000E+01 +0.74858000000000E+01 +0.75984000000000E+01 +0.76633000000000E+01 +0.77032000000000E+01 +0.77305000000000E+01 +0.77510000000000E+01 +0.77676000000000E+01 +0.77810000000000E+01 +0.77908000000000E+01 +0.77975000000000E+01 +0.78217000000000E+01 +0.78928000000000E+01 +0.79484000000000E+01 +0.82239000000000E+01 +0.66869000000000E+01 +0.70735000000000E+01 +0.73270000000000E+01 +0.74839000000000E+01 +0.75743000000000E+01 +0.76252000000000E+01 +0.76584000000000E+01 +0.76820000000000E+01 +0.76980000000000E+01 +0.77102000000000E+01 +0.77368000000000E+01 +0.78008000000000E+01 +0.78788000000000E+01 +0.81240000000000E+01 +0.49966000000000E+01 +0.58453000000000E+01 +0.64835000000000E+01 +0.69196000000000E+01 +0.72026000000000E+01 +0.73785000000000E+01 +0.74791000000000E+01 +0.75334000000000E+01 +0.75675000000000E+01 +0.75874000000000E+01 +0.76198000000000E+01 +0.76765000000000E+01 +0.77809000000000E+01 +0.80061000000000E+01 +0.28907000000000E+01 +0.39785000000000E+01 +0.49795000000000E+01 +0.58162000000000E+01 +0.64360000000000E+01 +0.68538000000000E+01 +0.71344000000000E+01 +0.72943000000000E+01 +0.73835000000000E+01 +0.74132000000000E+01 +0.74647000000000E+01 +0.75210000000000E+01 +0.76481000000000E+01 +0.78693000000000E+01 +0.10058000000000E+01 +0.21239000000000E+01 +0.32303000000000E+01 +0.42859000000000E+01 +0.52266000000000E+01 +0.59767000000000E+01 +0.65083000000000E+01 +0.68572000000000E+01 +0.70699000000000E+01 +0.71938000000000E+01 +0.72703000000000E+01 +0.73478000000000E+01 +0.74845000000000E+01 +0.77195000000000E+01 +-.49332000000000E+00 +0.57329000000000E+00 +0.16689000000000E+01 +0.27694000000000E+01 +0.38383000000000E+01 +0.48197000000000E+01 +0.56361000000000E+01 +0.62395000000000E+01 +0.66473000000000E+01 +0.68998000000000E+01 +0.70493000000000E+01 +0.71737000000000E+01 +0.73231000000000E+01 +0.75630000000000E+01 +-.16026000000000E+01 +-.58992000000000E+00 +0.44341000000000E+00 +0.15050000000000E+01 +0.25822000000000E+01 +0.36406000000000E+01 +0.46261000000000E+01 +0.54623000000000E+01 +0.60969000000000E+01 +0.65300000000000E+01 +0.68014000000000E+01 +0.69760000000000E+01 +0.71888000000000E+01 +0.74218000000000E+01 +-.26819000000000E+01 +-.16235000000000E+01 +-.49953000000000E+00 +0.54378000000000E+00 +0.15916000000000E+01 +0.26391000000000E+01 +0.36685000000000E+01 +0.46321000000000E+01 +0.54564000000000E+01 +0.60872000000000E+01 +0.65157000000000E+01 +0.67957000000000E+01 +0.70872000000000E+01 +0.73162000000000E+01 +-.35814000000000E+01 +-.24932000000000E+01 +-.14317000000000E+01 +-.36981000000000E+00 +0.79626000000000E+00 +0.18525000000000E+01 +0.28840000000000E+01 +0.40680000000000E+01 +0.50258000000000E+01 +0.58307000000000E+01 +0.61885000000000E+01 +0.66014000000000E+01 +0.70044000000000E+01 +0.72494000000000E+01 +-.43629000000000E+01 +-.32516000000000E+01 +-.21703000000000E+01 +-.11042000000000E+01 +-.26590000000000E-01 +0.10587000000000E+01 +0.22327000000000E+01 +0.32553000000000E+01 +0.44678000000000E+01 +0.54259000000000E+01 +0.61580000000000E+01 +0.63813000000000E+01 +0.68629000000000E+01 +0.72053000000000E+01 +-.50420000000000E+01 +-.39162000000000E+01 +-.28141000000000E+01 +-.17369000000000E+01 +-.66109000000000E+00 +0.42952000000000E+00 +0.15203000000000E+01 +0.27030000000000E+01 +0.38752000000000E+01 +0.49653000000000E+01 +0.58529000000000E+01 +0.66803000000000E+01 +0.67419000000000E+01 +0.71759000000000E+01 +-.56349000000000E+01 +-.45007000000000E+01 +-.33826000000000E+01 +-.22895000000000E+01 +-.12106000000000E+01 +-.12247000000000E+00 +0.97583000000000E+00 +0.20660000000000E+01 +0.32496000000000E+01 +0.44470000000000E+01 +0.54794000000000E+01 +0.64604000000000E+01 +0.71619000000000E+01 +0.71432000000000E+01 +-.61604000000000E+01 +-.50217000000000E+01 +-.38928000000000E+01 +-.27841000000000E+01 +-.16967000000000E+01 +-.61008000000000E+00 +0.48867000000000E+00 +0.15903000000000E+01 +0.26780000000000E+01 +0.38480000000000E+01 +0.50428000000000E+01 +0.61021000000000E+01 +0.70298000000000E+01 +0.73243000000000E+01 +-.66353000000000E+01 +-.54937000000000E+01 +-.43578000000000E+01 +-.32368000000000E+01 +-.21379000000000E+01 +-.10497000000000E+01 +0.47656000000000E-01 +0.11543000000000E+01 +0.22578000000000E+01 +0.34620000000000E+01 +0.45935000000000E+01 +0.57186000000000E+01 +0.67703000000000E+01 +0.72634000000000E+01 +-.70619000000000E+01 +-.59182000000000E+01 +-.47780000000000E+01 +-.36479000000000E+01 +-.25378000000000E+01 +-.14446000000000E+01 +-.34818000000000E+00 +0.76044000000000E+00 +0.18733000000000E+01 +0.29723000000000E+01 +0.41525000000000E+01 +0.54241000000000E+01 +0.65383000000000E+01 +0.71630000000000E+01 +-.74495000000000E+01 +-.63042000000000E+01 +-.51610000000000E+01 +-.40247000000000E+01 +-.29049000000000E+01 +-.18047000000000E+01 +-.70796000000000E+00 +0.40118000000000E+00 +0.15195000000000E+01 +0.26320000000000E+01 +0.38384000000000E+01 +0.51104000000000E+01 +0.62698000000000E+01 +0.70116000000000E+01 +-.78165000000000E+01 +-.66702000000000E+01 +-.55249000000000E+01 +-.43842000000000E+01 +-.32565000000000E+01 +-.21486000000000E+01 +-.10501000000000E+01 +0.58460000000000E-01 +0.11795000000000E+01 +0.23005000000000E+01 +0.34025000000000E+01 +0.47214000000000E+01 +0.59575000000000E+01 +0.67830000000000E+01 +-.81716000000000E+01 +-.70244000000000E+01 +-.58777000000000E+01 +-.47339000000000E+01 +-.36000000000000E+01 +-.24844000000000E+01 +-.13828000000000E+01 +-.27528000000000E+00 +0.84651000000000E+00 +0.19727000000000E+01 +0.30878000000000E+01 +0.44011000000000E+01 +0.55935000000000E+01 +0.65360000000000E+01 +-.85171000000000E+01 +-.73689000000000E+01 +-.62209000000000E+01 +-.50752000000000E+01 +-.39366000000000E+01 +-.28139000000000E+01 +-.17079000000000E+01 +-.60117000000000E+00 +0.51987000000000E+00 +0.16490000000000E+01 +0.27732000000000E+01 +0.40121000000000E+01 +0.52620000000000E+01 +0.62551000000000E+01 +-.88435000000000E+01 +-.76947000000000E+01 +-.65459000000000E+01 +-.53986000000000E+01 +-.42567000000000E+01 +-.31279000000000E+01 +-.20167000000000E+01 +-.90990000000000E+00 +0.20962000000000E+00 +0.13401000000000E+01 +0.24698000000000E+01 +0.36924000000000E+01 +0.48823000000000E+01 +0.59666000000000E+01 +-.91414000000000E+01 +-.79918000000000E+01 +-.68425000000000E+01 +-.56941000000000E+01 +-.45498000000000E+01 +-.34163000000000E+01 +-.22996000000000E+01 +-.11917000000000E+01 +-.73820000000000E-01 +0.10568000000000E+01 +0.21904000000000E+01 +0.33967000000000E+01 +0.45792000000000E+01 +0.56886000000000E+01 +-.94465000000000E+01 +-.82966000000000E+01 +-.71469000000000E+01 +-.59977000000000E+01 +-.48516000000000E+01 +-.37140000000000E+01 +-.25919000000000E+01 +-.14820000000000E+01 +-.36616000000000E+00 +0.76338000000000E+00 +0.18990000000000E+01 +0.30923000000000E+01 +0.42681000000000E+01 +0.53929000000000E+01 +-.97595000000000E+01 +-.86094000000000E+01 +-.74594000000000E+01 +-.63096000000000E+01 +-.51621000000000E+01 +-.40212000000000E+01 +-.28939000000000E+01 +-.17810000000000E+01 +-.66704000000000E+00 +0.46031000000000E+00 +0.15966000000000E+01 +0.27791000000000E+01 +0.39498000000000E+01 +0.50846000000000E+01 +-.10078000000000E+02 +-.89275000000000E+01 +-.77771000000000E+01 +-.66270000000000E+01 +-.54785000000000E+01 +-.43350000000000E+01 +-.32028000000000E+01 +-.20860000000000E+01 +-.97324000000000E+00 +0.15121000000000E+00 +0.12869000000000E+01 +0.24608000000000E+01 +0.36272000000000E+01 +0.47686000000000E+01 +-.10343000000000E+02 +-.91921000000000E+01 +-.80415000000000E+01 +-.68911000000000E+01 +-.57419000000000E+01 +-.45967000000000E+01 +-.34610000000000E+01 +-.23402000000000E+01 +-.12273000000000E+01 +-.10525000000000E+00 +0.10295000000000E+01 +0.21953000000000E+01 +0.33571000000000E+01 +0.45020000000000E+01 +-.10585000000000E+02 +-.94346000000000E+01 +-.82837000000000E+01 +-.71332000000000E+01 +-.59835000000000E+01 +-.48369000000000E+01 +-.36983000000000E+01 +-.25738000000000E+01 +-.14600000000000E+01 +-.34005000000000E+00 +0.79335000000000E+00 +0.19524000000000E+01 +0.31105000000000E+01 +0.42571000000000E+01 +-.10848000000000E+02 +-.96973000000000E+01 +-.85464000000000E+01 +-.73956000000000E+01 +-.62456000000000E+01 +-.50979000000000E+01 +-.39567000000000E+01 +-.28283000000000E+01 +-.17128000000000E+01 +-.59506000000000E+00 +0.53612000000000E+00 +0.16899000000000E+01 +0.28452000000000E+01 +0.39931000000000E+01 +0.74912000000000E+01 +0.74930000000000E+01 +0.74946000000000E+01 +0.74960000000000E+01 +0.74969000000000E+01 +0.74977000000000E+01 +0.74980000000000E+01 +0.74982000000000E+01 +0.74978000000000E+01 +0.74990000000000E+01 +0.72970000000000E+01 +0.60507000000000E+01 +0.62593000000000E+01 +0.67147000000000E+01 +0.67667000000000E+01 +0.75909000000000E+01 +0.74872000000000E+01 +0.74893000000000E+01 +0.74911000000000E+01 +0.74927000000000E+01 +0.74932000000000E+01 +0.74937000000000E+01 +0.74937000000000E+01 +0.74880000000000E+01 +0.72723000000000E+01 +0.60560000000000E+01 +0.62543000000000E+01 +0.67086000000000E+01 +0.79015000000000E+01 +0.79065000000000E+01 +0.81458000000000E+01 +0.74783000000000E+01 +0.74810000000000E+01 +0.75208000000000E+01 +0.74857000000000E+01 +0.74873000000000E+01 +0.74790000000000E+01 +0.74741000000000E+01 +0.72574000000000E+01 +0.60803000000000E+01 +0.62463000000000E+01 +0.67001000000000E+01 +0.60709000000000E+01 +0.60845000000000E+01 +0.78195000000000E+01 +0.76025000000000E+01 +0.78148000000000E+01 +0.76702000000000E+01 +0.75486000000000E+01 +0.74750000000000E+01 +0.74697000000000E+01 +0.74535000000000E+01 +0.72494000000000E+01 +0.61409000000000E+01 +0.62347000000000E+01 +0.66880000000000E+01 +0.58892000000000E+01 +0.61035000000000E+01 +0.61526000000000E+01 +0.73125000000000E+01 +0.74275000000000E+01 +0.77472000000000E+01 +0.76136000000000E+01 +0.74976000000000E+01 +0.74464000000000E+01 +0.74250000000000E+01 +0.72427000000000E+01 +0.62454000000000E+01 +0.62191000000000E+01 +0.66711000000000E+01 +0.57137000000000E+01 +0.58435000000000E+01 +0.59204000000000E+01 +0.63785000000000E+01 +0.70378000000000E+01 +0.72307000000000E+01 +0.76208000000000E+01 +0.75071000000000E+01 +0.74143000000000E+01 +0.73888000000000E+01 +0.72319000000000E+01 +0.63885000000000E+01 +0.61903000000000E+01 +0.66431000000000E+01 +0.49862000000000E+01 +0.54330000000000E+01 +0.56780000000000E+01 +0.58943000000000E+01 +0.63636000000000E+01 +0.68795000000000E+01 +0.70139000000000E+01 +0.74828000000000E+01 +0.73728000000000E+01 +0.73453000000000E+01 +0.72141000000000E+01 +0.65485000000000E+01 +0.61785000000000E+01 +0.65956000000000E+01 +0.34967000000000E+01 +0.43352000000000E+01 +0.50294000000000E+01 +0.54507000000000E+01 +0.58260000000000E+01 +0.63501000000000E+01 +0.66981000000000E+01 +0.68240000000000E+01 +0.73201000000000E+01 +0.72938000000000E+01 +0.71869000000000E+01 +0.66898000000000E+01 +0.61989000000000E+01 +0.65461000000000E+01 +0.16646000000000E+01 +0.27404000000000E+01 +0.37282000000000E+01 +0.46122000000000E+01 +0.52073000000000E+01 +0.57500000000000E+01 +0.63230000000000E+01 +0.66553000000000E+01 +0.66678000000000E+01 +0.72294000000000E+01 +0.71462000000000E+01 +0.67910000000000E+01 +0.62595000000000E+01 +0.64865000000000E+01 +0.16786000000000E+00 +0.12298000000000E+01 +0.23128000000000E+01 +0.33522000000000E+01 +0.43230000000000E+01 +0.52510000000000E+01 +0.57135000000000E+01 +0.62246000000000E+01 +0.65520000000000E+01 +0.71406000000000E+01 +0.70840000000000E+01 +0.68412000000000E+01 +0.63477000000000E+01 +0.64227000000000E+01 +-.93132000000000E+00 +0.14331000000000E+00 +0.11461000000000E+01 +0.22100000000000E+01 +0.32563000000000E+01 +0.45260000000000E+01 +0.52585000000000E+01 +0.57682000000000E+01 +0.64125000000000E+01 +0.65461000000000E+01 +0.69905000000000E+01 +0.68358000000000E+01 +0.64401000000000E+01 +0.63577000000000E+01 +-.14436000000000E+01 +-.88100000000000E+00 +0.12614000000000E+00 +0.11102000000000E+01 +0.23886000000000E+01 +0.34153000000000E+01 +0.43527000000000E+01 +0.54071000000000E+01 +0.58837000000000E+01 +0.64521000000000E+01 +0.68633000000000E+01 +0.67788000000000E+01 +0.65000000000000E+01 +0.63132000000000E+01 +-.12065000000000E+01 +-.69328000000000E+00 +-.50137000000000E+00 +0.33205000000000E+00 +0.15032000000000E+01 +0.27887000000000E+01 +0.37726000000000E+01 +0.49967000000000E+01 +0.56279000000000E+01 +0.63080000000000E+01 +0.64680000000000E+01 +0.66843000000000E+01 +0.65105000000000E+01 +0.62963000000000E+01 +-.13731000000000E+01 +-.10105000000000E+01 +-.62437000000000E+00 +0.16572000000000E+00 +0.83003000000000E+00 +0.20430000000000E+01 +0.30253000000000E+01 +0.42415000000000E+01 +0.57466000000000E+01 +0.64988000000000E+01 +0.63416000000000E+01 +0.65685000000000E+01 +0.64775000000000E+01 +0.62909000000000E+01 +-.21864000000000E+01 +-.14720000000000E+01 +-.88956000000000E+00 +-.32604000000000E+00 +0.40332000000000E+00 +0.15655000000000E+01 +0.26171000000000E+01 +0.38580000000000E+01 +0.50106000000000E+01 +0.62308000000000E+01 +0.63929000000000E+01 +0.64371000000000E+01 +0.64163000000000E+01 +0.62836000000000E+01 +-.32459000000000E+01 +-.23816000000000E+01 +-.15424000000000E+01 +-.78084000000000E+00 +-.24409000000000E-01 +0.10797000000000E+01 +0.20740000000000E+01 +0.31523000000000E+01 +0.43160000000000E+01 +0.57954000000000E+01 +0.61328000000000E+01 +0.63285000000000E+01 +0.63347000000000E+01 +0.62726000000000E+01 +-.42537000000000E+01 +-.33381000000000E+01 +-.24163000000000E+01 +-.14964000000000E+01 +-.60489000000000E+00 +0.48472000000000E+00 +0.14963000000000E+01 +0.27289000000000E+01 +0.37802000000000E+01 +0.51799000000000E+01 +0.57471000000000E+01 +0.61013000000000E+01 +0.62952000000000E+01 +0.62377000000000E+01 +-.52023000000000E+01 +-.42136000000000E+01 +-.32595000000000E+01 +-.22911000000000E+01 +-.13115000000000E+01 +-.20742000000000E+00 +0.83626000000000E+00 +0.20359000000000E+01 +0.32260000000000E+01 +0.42207000000000E+01 +0.52316000000000E+01 +0.57839000000000E+01 +0.61182000000000E+01 +0.62546000000000E+01 +-.60851000000000E+01 +-.50248000000000E+01 +-.40197000000000E+01 +-.30322000000000E+01 +-.20242000000000E+01 +-.91513000000000E+00 +0.15530000000000E+00 +0.13298000000000E+01 +0.25037000000000E+01 +0.35596000000000E+01 +0.46278000000000E+01 +0.53765000000000E+01 +0.58804000000000E+01 +0.61453000000000E+01 +-.68821000000000E+01 +-.57784000000000E+01 +-.47158000000000E+01 +-.36959000000000E+01 +-.26777000000000E+01 +-.15764000000000E+01 +-.49297000000000E+00 +0.66359000000000E+00 +0.17679000000000E+01 +0.29601000000000E+01 +0.40173000000000E+01 +0.49082000000000E+01 +0.55815000000000E+01 +0.59994000000000E+01 +-.75916000000000E+01 +-.64668000000000E+01 +-.53635000000000E+01 +-.42999000000000E+01 +-.32642000000000E+01 +-.21731000000000E+01 +-.10867000000000E+01 +0.54841000000000E-01 +0.11670000000000E+01 +0.23439000000000E+01 +0.34335000000000E+01 +0.44131000000000E+01 +0.52324000000000E+01 +0.58074000000000E+01 +-.82229000000000E+01 +-.70885000000000E+01 +-.59628000000000E+01 +-.48623000000000E+01 +-.37972000000000E+01 +-.27090000000000E+01 +-.16233000000000E+01 +-.49522000000000E+00 +0.61890000000000E+00 +0.17845000000000E+01 +0.29009000000000E+01 +0.39298000000000E+01 +0.48495000000000E+01 +0.55665000000000E+01 +-.87832000000000E+01 +-.76439000000000E+01 +-.65071000000000E+01 +-.53829000000000E+01 +-.42867000000000E+01 +-.31898000000000E+01 +-.21025000000000E+01 +-.98581000000000E+00 +0.12693000000000E+00 +0.12832000000000E+01 +0.24092000000000E+01 +0.34742000000000E+01 +0.44670000000000E+01 +0.53033000000000E+01 +-.92847000000000E+01 +-.81423000000000E+01 +-.70000000000000E+01 +-.58632000000000E+01 +-.47437000000000E+01 +-.36305000000000E+01 +-.25367000000000E+01 +-.14274000000000E+01 +-.31747000000000E+00 +0.83084000000000E+00 +0.19640000000000E+01 +0.30580000000000E+01 +0.40929000000000E+01 +0.50199000000000E+01 +-.97410000000000E+01 +-.85964000000000E+01 +-.74513000000000E+01 +-.63079000000000E+01 +-.51742000000000E+01 +-.40452000000000E+01 +-.29399000000000E+01 +-.18331000000000E+01 +-.72586000000000E+00 +0.41539000000000E+00 +0.15502000000000E+01 +0.26595000000000E+01 +0.37325000000000E+01 +0.47202000000000E+01 +-.10163000000000E+02 +-.90173000000000E+01 +-.78704000000000E+01 +-.67238000000000E+01 +-.55823000000000E+01 +-.44420000000000E+01 +-.33235000000000E+01 +-.22141000000000E+01 +-.11081000000000E+01 +0.26825000000000E-01 +0.11613000000000E+01 +0.22806000000000E+01 +0.33755000000000E+01 +0.44099000000000E+01 +-.10561000000000E+02 +-.94143000000000E+01 +-.82661000000000E+01 +-.71178000000000E+01 +-.59723000000000E+01 +-.48254000000000E+01 +-.36955000000000E+01 +-.25795000000000E+01 +-.14726000000000E+01 +-.34300000000000E+00 +0.78993000000000E+00 +0.19156000000000E+01 +0.30251000000000E+01 +0.40923000000000E+01 +-.10923000000000E+02 +-.97751000000000E+01 +-.86262000000000E+01 +-.74769000000000E+01 +-.63291000000000E+01 +-.51792000000000E+01 +-.40409000000000E+01 +-.29168000000000E+01 +-.18062000000000E+01 +-.68056000000000E+00 +0.45032000000000E+00 +0.15804000000000E+01 +0.26995000000000E+01 +0.37902000000000E+01 +-.11261000000000E+02 +-.10112000000000E+02 +-.89624000000000E+01 +-.78126000000000E+01 +-.66636000000000E+01 +-.55122000000000E+01 +-.43688000000000E+01 +-.32372000000000E+01 +-.21210000000000E+01 +-.99760000000000E+00 +0.13102000000000E+00 +0.12626000000000E+01 +0.23893000000000E+01 +0.34968000000000E+01 +-.11594000000000E+02 +-.10445000000000E+02 +-.92947000000000E+01 +-.81445000000000E+01 +-.69948000000000E+01 +-.58429000000000E+01 +-.46963000000000E+01 +-.35589000000000E+01 +-.24367000000000E+01 +-.13136000000000E+01 +-.18731000000000E+00 +0.94452000000000E+00 +0.20760000000000E+01 +0.31951000000000E+01 +-.11925000000000E+02 +-.10775000000000E+02 +-.96245000000000E+01 +-.84739000000000E+01 +-.73239000000000E+01 +-.61718000000000E+01 +-.50234000000000E+01 +-.38818000000000E+01 +-.27535000000000E+01 +-.16293000000000E+01 +-.50491000000000E+00 +0.62611000000000E+00 +0.17610000000000E+01 +0.28876000000000E+01 +-.12251000000000E+02 +-.11101000000000E+02 +-.99504000000000E+01 +-.87996000000000E+01 +-.76492000000000E+01 +-.64972000000000E+01 +-.53478000000000E+01 +-.42031000000000E+01 +-.30697000000000E+01 +-.19430000000000E+01 +-.81982000000000E+00 +0.30974000000000E+00 +0.14457000000000E+01 +0.25781000000000E+01 +0.59215000000000E+01 +0.59225000000000E+01 +0.59232000000000E+01 +0.59240000000000E+01 +0.59243000000000E+01 +0.59247000000000E+01 +0.59248000000000E+01 +0.59248000000000E+01 +0.59247000000000E+01 +0.59252000000000E+01 +0.59275000000000E+01 +0.59385000000000E+01 +0.59805000000000E+01 +0.60994000000000E+01 +0.59161000000000E+01 +0.59176000000000E+01 +0.59188000000000E+01 +0.59199000000000E+01 +0.59208000000000E+01 +0.59216000000000E+01 +0.59218000000000E+01 +0.59220000000000E+01 +0.59219000000000E+01 +0.59225000000000E+01 +0.59246000000000E+01 +0.59357000000000E+01 +0.59775000000000E+01 +0.60959000000000E+01 +0.59053000000000E+01 +0.59088000000000E+01 +0.59117000000000E+01 +0.59135000000000E+01 +0.59149000000000E+01 +0.59163000000000E+01 +0.59172000000000E+01 +0.59180000000000E+01 +0.59175000000000E+01 +0.59181000000000E+01 +0.59203000000000E+01 +0.59313000000000E+01 +0.59730000000000E+01 +0.60912000000000E+01 +0.58896000000000E+01 +0.58948000000000E+01 +0.58993000000000E+01 +0.59032000000000E+01 +0.59061000000000E+01 +0.59081000000000E+01 +0.59099000000000E+01 +0.59110000000000E+01 +0.59117000000000E+01 +0.59119000000000E+01 +0.59137000000000E+01 +0.59249000000000E+01 +0.59667000000000E+01 +0.60846000000000E+01 +0.58674000000000E+01 +0.58750000000000E+01 +0.58815000000000E+01 +0.58871000000000E+01 +0.58921000000000E+01 +0.58964000000000E+01 +0.58990000000000E+01 +0.59011000000000E+01 +0.59023000000000E+01 +0.59030000000000E+01 +0.59044000000000E+01 +0.59153000000000E+01 +0.59578000000000E+01 +0.60756000000000E+01 +0.58203000000000E+01 +0.58407000000000E+01 +0.58544000000000E+01 +0.58640000000000E+01 +0.58717000000000E+01 +0.58784000000000E+01 +0.58839000000000E+01 +0.58872000000000E+01 +0.58894000000000E+01 +0.58906000000000E+01 +0.58921000000000E+01 +0.59019000000000E+01 +0.59426000000000E+01 +0.60618000000000E+01 +0.57195000000000E+01 +0.57596000000000E+01 +0.57946000000000E+01 +0.58209000000000E+01 +0.58390000000000E+01 +0.58517000000000E+01 +0.58611000000000E+01 +0.58674000000000E+01 +0.58712000000000E+01 +0.58737000000000E+01 +0.58755000000000E+01 +0.58846000000000E+01 +0.59233000000000E+01 +0.60330000000000E+01 +0.56281000000000E+01 +0.56543000000000E+01 +0.56925000000000E+01 +0.57352000000000E+01 +0.57738000000000E+01 +0.58036000000000E+01 +0.58241000000000E+01 +0.58376000000000E+01 +0.58455000000000E+01 +0.58500000000000E+01 +0.58530000000000E+01 +0.58611000000000E+01 +0.58992000000000E+01 +0.59990000000000E+01 +0.55828000000000E+01 +0.55894000000000E+01 +0.56040000000000E+01 +0.56324000000000E+01 +0.56741000000000E+01 +0.57196000000000E+01 +0.57593000000000E+01 +0.57877000000000E+01 +0.58062000000000E+01 +0.58164000000000E+01 +0.58224000000000E+01 +0.58312000000000E+01 +0.58702000000000E+01 +0.59618000000000E+01 +0.55201000000000E+01 +0.55377000000000E+01 +0.55466000000000E+01 +0.55574000000000E+01 +0.55789000000000E+01 +0.56162000000000E+01 +0.56638000000000E+01 +0.57090000000000E+01 +0.57438000000000E+01 +0.57667000000000E+01 +0.57799000000000E+01 +0.57917000000000E+01 +0.58300000000000E+01 +0.59142000000000E+01 +0.50693000000000E+01 +0.53048000000000E+01 +0.54237000000000E+01 +0.54749000000000E+01 +0.54998000000000E+01 +0.55237000000000E+01 +0.55597000000000E+01 +0.56073000000000E+01 +0.56558000000000E+01 +0.56956000000000E+01 +0.57218000000000E+01 +0.57406000000000E+01 +0.57793000000000E+01 +0.58506000000000E+01 +0.34686000000000E+01 +0.42438000000000E+01 +0.47898000000000E+01 +0.51309000000000E+01 +0.53169000000000E+01 +0.54070000000000E+01 +0.54557000000000E+01 +0.54999000000000E+01 +0.55513000000000E+01 +0.56041000000000E+01 +0.56475000000000E+01 +0.56785000000000E+01 +0.57177000000000E+01 +0.57798000000000E+01 +0.11263000000000E+01 +0.22178000000000E+01 +0.32218000000000E+01 +0.40552000000000E+01 +0.46586000000000E+01 +0.50405000000000E+01 +0.52535000000000E+01 +0.53661000000000E+01 +0.54338000000000E+01 +0.54985000000000E+01 +0.55590000000000E+01 +0.56074000000000E+01 +0.56528000000000E+01 +0.57107000000000E+01 +-.97678000000000E+00 +0.15018000000000E+00 +0.12674000000000E+01 +0.23472000000000E+01 +0.33317000000000E+01 +0.41365000000000E+01 +0.47069000000000E+01 +0.50587000000000E+01 +0.52560000000000E+01 +0.53740000000000E+01 +0.54553000000000E+01 +0.55244000000000E+01 +0.55853000000000E+01 +0.56449000000000E+01 +-.27200000000000E+01 +-.15901000000000E+01 +-.46579000000000E+00 +0.65460000000000E+00 +0.17558000000000E+01 +0.27986000000000E+01 +0.37112000000000E+01 +0.44127000000000E+01 +0.48781000000000E+01 +0.51570000000000E+01 +0.53243000000000E+01 +0.54282000000000E+01 +0.55142000000000E+01 +0.55837000000000E+01 +-.41792000000000E+01 +-.30391000000000E+01 +-.19093000000000E+01 +-.78690000000000E+00 +0.33253000000000E+00 +0.14391000000000E+01 +0.25018000000000E+01 +0.34592000000000E+01 +0.42283000000000E+01 +0.47656000000000E+01 +0.50997000000000E+01 +0.53088000000000E+01 +0.54307000000000E+01 +0.55228000000000E+01 +-.54050000000000E+01 +-.42590000000000E+01 +-.31198000000000E+01 +-.19908000000000E+01 +-.86954000000000E+00 +0.24889000000000E+00 +0.13555000000000E+01 +0.24208000000000E+01 +0.33883000000000E+01 +0.41804000000000E+01 +0.47454000000000E+01 +0.51100000000000E+01 +0.53401000000000E+01 +0.54502000000000E+01 +-.64387000000000E+01 +-.52904000000000E+01 +-.41458000000000E+01 +-.30081000000000E+01 +-.18805000000000E+01 +-.75970000000000E+00 +0.35783000000000E+00 +0.14606000000000E+01 +0.25186000000000E+01 +0.34771000000000E+01 +0.42588000000000E+01 +0.48184000000000E+01 +0.51827000000000E+01 +0.54034000000000E+01 +-.73181000000000E+01 +-.61689000000000E+01 +-.50217000000000E+01 +-.38786000000000E+01 +-.27430000000000E+01 +-.16169000000000E+01 +-.49638000000000E+00 +0.61902000000000E+00 +0.17146000000000E+01 +0.27586000000000E+01 +0.36896000000000E+01 +0.44352000000000E+01 +0.49624000000000E+01 +0.52903000000000E+01 +-.80750000000000E+01 +-.69255000000000E+01 +-.57772000000000E+01 +-.46311000000000E+01 +-.34896000000000E+01 +-.23566000000000E+01 +-.12322000000000E+01 +-.11225000000000E+00 +0.99945000000000E+00 +0.20849000000000E+01 +0.31027000000000E+01 +0.39888000000000E+01 +0.46771000000000E+01 +0.51385000000000E+01 +-.87356000000000E+01 +-.75861000000000E+01 +-.64371000000000E+01 +-.52894000000000E+01 +-.41444000000000E+01 +-.30055000000000E+01 +-.18757000000000E+01 +-.75252000000000E+00 +0.36655000000000E+00 +0.14728000000000E+01 +0.25388000000000E+01 +0.35171000000000E+01 +0.43397000000000E+01 +0.49424000000000E+01 +-.93169000000000E+01 +-.81672000000000E+01 +-.70182000000000E+01 +-.58695000000000E+01 +-.47224000000000E+01 +-.35794000000000E+01 +-.24440000000000E+01 +-.13170000000000E+01 +-.19375000000000E+00 +0.92360000000000E+00 +0.20170000000000E+01 +0.30529000000000E+01 +0.39744000000000E+01 +0.47056000000000E+01 +-.98416000000000E+01 +-.86919000000000E+01 +-.75425000000000E+01 +-.63932000000000E+01 +-.52448000000000E+01 +-.40991000000000E+01 +-.29595000000000E+01 +-.18279000000000E+01 +-.70145000000000E+00 +0.42201000000000E+00 +0.15339000000000E+01 +0.26023000000000E+01 +0.35931000000000E+01 +0.44338000000000E+01 +-.10320000000000E+02 +-.91699000000000E+01 +-.80203000000000E+01 +-.68705000000000E+01 +-.57213000000000E+01 +-.45740000000000E+01 +-.34311000000000E+01 +-.22951000000000E+01 +-.11653000000000E+01 +-.38000000000000E-01 +0.10832000000000E+01 +0.21754000000000E+01 +0.32137000000000E+01 +0.41393000000000E+01 +-.10740000000000E+02 +-.95903000000000E+01 +-.84404000000000E+01 +-.72904000000000E+01 +-.61406000000000E+01 +-.49922000000000E+01 +-.38470000000000E+01 +-.27073000000000E+01 +-.15739000000000E+01 +-.44346000000000E+00 +0.68387000000000E+00 +0.17925000000000E+01 +0.28642000000000E+01 +0.38547000000000E+01 +-.11129000000000E+02 +-.99788000000000E+01 +-.88284000000000E+01 +-.76781000000000E+01 +-.65280000000000E+01 +-.53788000000000E+01 +-.42319000000000E+01 +-.30893000000000E+01 +-.19525000000000E+01 +-.81950000000000E+00 +0.31171000000000E+00 +0.14315000000000E+01 +0.25256000000000E+01 +0.35624000000000E+01 +-.11497000000000E+02 +-.10346000000000E+02 +-.91960000000000E+01 +-.80457000000000E+01 +-.68951000000000E+01 +-.57454000000000E+01 +-.45974000000000E+01 +-.34526000000000E+01 +-.23127000000000E+01 +-.11774000000000E+01 +-.43640000000000E-01 +0.10845000000000E+01 +0.21930000000000E+01 +0.32621000000000E+01 +-.11856000000000E+02 +-.10706000000000E+02 +-.95549000000000E+01 +-.84043000000000E+01 +-.72537000000000E+01 +-.61035000000000E+01 +-.49546000000000E+01 +-.38082000000000E+01 +-.26658000000000E+01 +-.15282000000000E+01 +-.39278000000000E+00 +0.73941000000000E+00 +0.18589000000000E+01 +0.29504000000000E+01 +-.12209000000000E+02 +-.11058000000000E+02 +-.99075000000000E+01 +-.87566000000000E+01 +-.76058000000000E+01 +-.64554000000000E+01 +-.53060000000000E+01 +-.41583000000000E+01 +-.30138000000000E+01 +-.18740000000000E+01 +-.73724000000000E+00 +0.39756000000000E+00 +0.15247000000000E+01 +0.26322000000000E+01 +-.12524000000000E+02 +-.11373000000000E+02 +-.10222000000000E+02 +-.90710000000000E+01 +-.79202000000000E+01 +-.67695000000000E+01 +-.56196000000000E+01 +-.44709000000000E+01 +-.33248000000000E+01 +-.21830000000000E+01 +-.10449000000000E+01 +0.91875000000000E-01 +0.12246000000000E+01 +0.23439000000000E+01 +-.12826000000000E+02 +-.11675000000000E+02 +-.10524000000000E+02 +-.93728000000000E+01 +-.82217000000000E+01 +-.70710000000000E+01 +-.59208000000000E+01 +-.47715000000000E+01 +-.36241000000000E+01 +-.24805000000000E+01 +-.13409000000000E+01 +-.20288000000000E+00 +0.93388000000000E+00 +0.20612000000000E+01 +-.13130000000000E+02 +-.11979000000000E+02 +-.10828000000000E+02 +-.96770000000000E+01 +-.85259000000000E+01 +-.73749000000000E+01 +-.62244000000000E+01 +-.50746000000000E+01 +-.39262000000000E+01 +-.27811000000000E+01 +-.16402000000000E+01 +-.50125000000000E+00 +0.63753000000000E+00 +0.17708000000000E+01 +0.50386000000000E+01 +0.50394000000000E+01 +0.50402000000000E+01 +0.50408000000000E+01 +0.50413000000000E+01 +0.50415000000000E+01 +0.50417000000000E+01 +0.50417000000000E+01 +0.50415000000000E+01 +0.50420000000000E+01 +0.50443000000000E+01 +0.50552000000000E+01 +0.50961000000000E+01 +0.52117000000000E+01 +0.50341000000000E+01 +0.50354000000000E+01 +0.50366000000000E+01 +0.50376000000000E+01 +0.50385000000000E+01 +0.50392000000000E+01 +0.50394000000000E+01 +0.50397000000000E+01 +0.50396000000000E+01 +0.50400000000000E+01 +0.50422000000000E+01 +0.50531000000000E+01 +0.50939000000000E+01 +0.52090000000000E+01 +0.50266000000000E+01 +0.50289000000000E+01 +0.50309000000000E+01 +0.50325000000000E+01 +0.50339000000000E+01 +0.50352000000000E+01 +0.50361000000000E+01 +0.50367000000000E+01 +0.50364000000000E+01 +0.50370000000000E+01 +0.50391000000000E+01 +0.50499000000000E+01 +0.50906000000000E+01 +0.52054000000000E+01 +0.50154000000000E+01 +0.50190000000000E+01 +0.50221000000000E+01 +0.50247000000000E+01 +0.50270000000000E+01 +0.50289000000000E+01 +0.50305000000000E+01 +0.50317000000000E+01 +0.50322000000000E+01 +0.50325000000000E+01 +0.50342000000000E+01 +0.50453000000000E+01 +0.50859000000000E+01 +0.52006000000000E+01 +0.49988000000000E+01 +0.50045000000000E+01 +0.50093000000000E+01 +0.50133000000000E+01 +0.50167000000000E+01 +0.50198000000000E+01 +0.50223000000000E+01 +0.50243000000000E+01 +0.50255000000000E+01 +0.50260000000000E+01 +0.50276000000000E+01 +0.50381000000000E+01 +0.50796000000000E+01 +0.51940000000000E+01 +0.49584000000000E+01 +0.49767000000000E+01 +0.49884000000000E+01 +0.49962000000000E+01 +0.50021000000000E+01 +0.50067000000000E+01 +0.50107000000000E+01 +0.50138000000000E+01 +0.50160000000000E+01 +0.50171000000000E+01 +0.50186000000000E+01 +0.50282000000000E+01 +0.50679000000000E+01 +0.51836000000000E+01 +0.48671000000000E+01 +0.49043000000000E+01 +0.49368000000000E+01 +0.49608000000000E+01 +0.49766000000000E+01 +0.49868000000000E+01 +0.49939000000000E+01 +0.49990000000000E+01 +0.50027000000000E+01 +0.50049000000000E+01 +0.50067000000000E+01 +0.50156000000000E+01 +0.50535000000000E+01 +0.51642000000000E+01 +0.47859000000000E+01 +0.48101000000000E+01 +0.48458000000000E+01 +0.48856000000000E+01 +0.49213000000000E+01 +0.49480000000000E+01 +0.49655000000000E+01 +0.49764000000000E+01 +0.49835000000000E+01 +0.49879000000000E+01 +0.49907000000000E+01 +0.49988000000000E+01 +0.50358000000000E+01 +0.51426000000000E+01 +0.47504000000000E+01 +0.47561000000000E+01 +0.47694000000000E+01 +0.47959000000000E+01 +0.48346000000000E+01 +0.48765000000000E+01 +0.49122000000000E+01 +0.49375000000000E+01 +0.49535000000000E+01 +0.49633000000000E+01 +0.49689000000000E+01 +0.49768000000000E+01 +0.50134000000000E+01 +0.51173000000000E+01 +0.47001000000000E+01 +0.47168000000000E+01 +0.47250000000000E+01 +0.47349000000000E+01 +0.47546000000000E+01 +0.47888000000000E+01 +0.48323000000000E+01 +0.48735000000000E+01 +0.49050000000000E+01 +0.49260000000000E+01 +0.49385000000000E+01 +0.49491000000000E+01 +0.49845000000000E+01 +0.50920000000000E+01 +0.42682000000000E+01 +0.45009000000000E+01 +0.46180000000000E+01 +0.46683000000000E+01 +0.46920000000000E+01 +0.47137000000000E+01 +0.47465000000000E+01 +0.47902000000000E+01 +0.48348000000000E+01 +0.48713000000000E+01 +0.48959000000000E+01 +0.49135000000000E+01 +0.49492000000000E+01 +0.50563000000000E+01 +0.26900000000000E+01 +0.34626000000000E+01 +0.40056000000000E+01 +0.43439000000000E+01 +0.45275000000000E+01 +0.46151000000000E+01 +0.46614000000000E+01 +0.47023000000000E+01 +0.47500000000000E+01 +0.47991000000000E+01 +0.48391000000000E+01 +0.48683000000000E+01 +0.49084000000000E+01 +0.50132000000000E+01 +0.36586000000000E+00 +0.14561000000000E+01 +0.24587000000000E+01 +0.32900000000000E+01 +0.38904000000000E+01 +0.42686000000000E+01 +0.44773000000000E+01 +0.45853000000000E+01 +0.46520000000000E+01 +0.47128000000000E+01 +0.47689000000000E+01 +0.48146000000000E+01 +0.48644000000000E+01 +0.49711000000000E+01 +-.17264000000000E+01 +-.59657000000000E+00 +0.52034000000000E+00 +0.15992000000000E+01 +0.25819000000000E+01 +0.33836000000000E+01 +0.39493000000000E+01 +0.42958000000000E+01 +0.44878000000000E+01 +0.46018000000000E+01 +0.46823000000000E+01 +0.47513000000000E+01 +0.48179000000000E+01 +0.49277000000000E+01 +-.34713000000000E+01 +-.23327000000000E+01 +-.12022000000000E+01 +-.80818000000000E-01 +0.10193000000000E+01 +0.20600000000000E+01 +0.29690000000000E+01 +0.36655000000000E+01 +0.41251000000000E+01 +0.43977000000000E+01 +0.45630000000000E+01 +0.46711000000000E+01 +0.47666000000000E+01 +0.48860000000000E+01 +-.49285000000000E+01 +-.37838000000000E+01 +-.26453000000000E+01 +-.15153000000000E+01 +-.39412000000000E+00 +0.71088000000000E+00 +0.17706000000000E+01 +0.27241000000000E+01 +0.34882000000000E+01 +0.40189000000000E+01 +0.43516000000000E+01 +0.45608000000000E+01 +0.46980000000000E+01 +0.48411000000000E+01 +-.61477000000000E+01 +-.50005000000000E+01 +-.38567000000000E+01 +-.27191000000000E+01 +-.15904000000000E+01 +-.47082000000000E+00 +0.63322000000000E+00 +0.16951000000000E+01 +0.26587000000000E+01 +0.34450000000000E+01 +0.40077000000000E+01 +0.43751000000000E+01 +0.46078000000000E+01 +0.47802000000000E+01 +-.71725000000000E+01 +-.60242000000000E+01 +-.48778000000000E+01 +-.37352000000000E+01 +-.25993000000000E+01 +-.14727000000000E+01 +-.35562000000000E+00 +0.74403000000000E+00 +0.17985000000000E+01 +0.27521000000000E+01 +0.35309000000000E+01 +0.40917000000000E+01 +0.44628000000000E+01 +0.47142000000000E+01 +-.80396000000000E+01 +-.68910000000000E+01 +-.57434000000000E+01 +-.45979000000000E+01 +-.34568000000000E+01 +-.23234000000000E+01 +-.11997000000000E+01 +-.86191000000000E-01 +0.10062000000000E+01 +0.20459000000000E+01 +0.29751000000000E+01 +0.37209000000000E+01 +0.42560000000000E+01 +0.46122000000000E+01 +-.87810000000000E+01 +-.76322000000000E+01 +-.64839000000000E+01 +-.53369000000000E+01 +-.41925000000000E+01 +-.30538000000000E+01 +-.19239000000000E+01 +-.80334000000000E+00 +0.30576000000000E+00 +0.13873000000000E+01 +0.24041000000000E+01 +0.32894000000000E+01 +0.39857000000000E+01 +0.44712000000000E+01 +-.94238000000000E+01 +-.82747000000000E+01 +-.71260000000000E+01 +-.59780000000000E+01 +-.48317000000000E+01 +-.36893000000000E+01 +-.25540000000000E+01 +-.14277000000000E+01 +-.30980000000000E+00 +0.79306000000000E+00 +0.18580000000000E+01 +0.28349000000000E+01 +0.36646000000000E+01 +0.42864000000000E+01 +-.99900000000000E+01 +-.88408000000000E+01 +-.76918000000000E+01 +-.65431000000000E+01 +-.53955000000000E+01 +-.42506000000000E+01 +-.31113000000000E+01 +-.19797000000000E+01 +-.85576000000000E+00 +0.25890000000000E+00 +0.13510000000000E+01 +0.23842000000000E+01 +0.33105000000000E+01 +0.40541000000000E+01 +-.10499000000000E+02 +-.93499000000000E+01 +-.82004000000000E+01 +-.70514000000000E+01 +-.59028000000000E+01 +-.47563000000000E+01 +-.36141000000000E+01 +-.24780000000000E+01 +-.13490000000000E+01 +-.22714000000000E+00 +0.88066000000000E+00 +0.19485000000000E+01 +0.29422000000000E+01 +0.37905000000000E+01 +-.10962000000000E+02 +-.98125000000000E+01 +-.86631000000000E+01 +-.75134000000000E+01 +-.63643000000000E+01 +-.52167000000000E+01 +-.40721000000000E+01 +-.29326000000000E+01 +-.17991000000000E+01 +-.67180000000000E+00 +0.44618000000000E+00 +0.15375000000000E+01 +0.25769000000000E+01 +0.35070000000000E+01 +-.11387000000000E+02 +-.10238000000000E+02 +-.90879000000000E+01 +-.79380000000000E+01 +-.67883000000000E+01 +-.56399000000000E+01 +-.44939000000000E+01 +-.33514000000000E+01 +-.22140000000000E+01 +-.10824000000000E+01 +0.42451000000000E-01 +0.11493000000000E+01 +0.22203000000000E+01 +0.32112000000000E+01 +-.11765000000000E+02 +-.10615000000000E+02 +-.94656000000000E+01 +-.83152000000000E+01 +-.71652000000000E+01 +-.60160000000000E+01 +-.48688000000000E+01 +-.37242000000000E+01 +-.25835000000000E+01 +-.14480000000000E+01 +-.31803000000000E+00 +0.80171000000000E+00 +0.18935000000000E+01 +0.29298000000000E+01 +-.12117000000000E+02 +-.10967000000000E+02 +-.98164000000000E+01 +-.86660000000000E+01 +-.75156000000000E+01 +-.63660000000000E+01 +-.52178000000000E+01 +-.40715000000000E+01 +-.29283000000000E+01 +-.17895000000000E+01 +-.65567000000000E+00 +0.47111000000000E+00 +0.15792000000000E+01 +0.26481000000000E+01 +-.12461000000000E+02 +-.11311000000000E+02 +-.10160000000000E+02 +-.90095000000000E+01 +-.78591000000000E+01 +-.67090000000000E+01 +-.55601000000000E+01 +-.44126000000000E+01 +-.32674000000000E+01 +-.21260000000000E+01 +-.98918000000000E+00 +0.14235000000000E+00 +0.12615000000000E+01 +0.23527000000000E+01 +-.12801000000000E+02 +-.11650000000000E+02 +-.10500000000000E+02 +-.93486000000000E+01 +-.81978000000000E+01 +-.70476000000000E+01 +-.58981000000000E+01 +-.47498000000000E+01 +-.36029000000000E+01 +-.24594000000000E+01 +-.13201000000000E+01 +-.18521000000000E+00 +0.94168000000000E+00 +0.20488000000000E+01 +-.13136000000000E+02 +-.11986000000000E+02 +-.10835000000000E+02 +-.96841000000000E+01 +-.85332000000000E+01 +-.73826000000000E+01 +-.62327000000000E+01 +-.50836000000000E+01 +-.39357000000000E+01 +-.27904000000000E+01 +-.16491000000000E+01 +-.51169000000000E+00 +0.62140000000000E+00 +0.17390000000000E+01 +-.13440000000000E+02 +-.12289000000000E+02 +-.11138000000000E+02 +-.99875000000000E+01 +-.88364000000000E+01 +-.76858000000000E+01 +-.65355000000000E+01 +-.53859000000000E+01 +-.42371000000000E+01 +-.30904000000000E+01 +-.19472000000000E+01 +-.80769000000000E+00 +0.32892000000000E+00 +0.14554000000000E+01 +-.13726000000000E+02 +-.12575000000000E+02 +-.11424000000000E+02 +-.10273000000000E+02 +-.91218000000000E+01 +-.79711000000000E+01 +-.68206000000000E+01 +-.56705000000000E+01 +-.45211000000000E+01 +-.33733000000000E+01 +-.22286000000000E+01 +-.10873000000000E+01 +0.51835000000000E-01 +0.11846000000000E+01 +0.43485000000000E+01 +0.43490000000000E+01 +0.43495000000000E+01 +0.43499000000000E+01 +0.43501000000000E+01 +0.43502000000000E+01 +0.43503000000000E+01 +0.43503000000000E+01 +0.43501000000000E+01 +0.43503000000000E+01 +0.43529000000000E+01 +0.43643000000000E+01 +0.44047000000000E+01 +0.45176000000000E+01 +0.43456000000000E+01 +0.43464000000000E+01 +0.43473000000000E+01 +0.43479000000000E+01 +0.43484000000000E+01 +0.43488000000000E+01 +0.43490000000000E+01 +0.43490000000000E+01 +0.43490000000000E+01 +0.43491000000000E+01 +0.43516000000000E+01 +0.43629000000000E+01 +0.44032000000000E+01 +0.45157000000000E+01 +0.43403000000000E+01 +0.43419000000000E+01 +0.43434000000000E+01 +0.43445000000000E+01 +0.43455000000000E+01 +0.43462000000000E+01 +0.43467000000000E+01 +0.43470000000000E+01 +0.43469000000000E+01 +0.43470000000000E+01 +0.43494000000000E+01 +0.43607000000000E+01 +0.44009000000000E+01 +0.45131000000000E+01 +0.43317000000000E+01 +0.43345000000000E+01 +0.43369000000000E+01 +0.43389000000000E+01 +0.43405000000000E+01 +0.43418000000000E+01 +0.43428000000000E+01 +0.43435000000000E+01 +0.43437000000000E+01 +0.43439000000000E+01 +0.43458000000000E+01 +0.43573000000000E+01 +0.43975000000000E+01 +0.45095000000000E+01 +0.43181000000000E+01 +0.43229000000000E+01 +0.43269000000000E+01 +0.43302000000000E+01 +0.43329000000000E+01 +0.43351000000000E+01 +0.43369000000000E+01 +0.43381000000000E+01 +0.43389000000000E+01 +0.43392000000000E+01 +0.43408000000000E+01 +0.43518000000000E+01 +0.43927000000000E+01 +0.45046000000000E+01 +0.42815000000000E+01 +0.42987000000000E+01 +0.43094000000000E+01 +0.43164000000000E+01 +0.43213000000000E+01 +0.43251000000000E+01 +0.43281000000000E+01 +0.43304000000000E+01 +0.43319000000000E+01 +0.43328000000000E+01 +0.43341000000000E+01 +0.43441000000000E+01 +0.43833000000000E+01 +0.44965000000000E+01 +0.41954000000000E+01 +0.42313000000000E+01 +0.42625000000000E+01 +0.42853000000000E+01 +0.42999000000000E+01 +0.43090000000000E+01 +0.43148000000000E+01 +0.43190000000000E+01 +0.43219000000000E+01 +0.43236000000000E+01 +0.43252000000000E+01 +0.43344000000000E+01 +0.43716000000000E+01 +0.44797000000000E+01 +0.41199000000000E+01 +0.41431000000000E+01 +0.41775000000000E+01 +0.42159000000000E+01 +0.42500000000000E+01 +0.42751000000000E+01 +0.42911000000000E+01 +0.43009000000000E+01 +0.43070000000000E+01 +0.43107000000000E+01 +0.43131000000000E+01 +0.43212000000000E+01 +0.43575000000000E+01 +0.44618000000000E+01 +0.40896000000000E+01 +0.40948000000000E+01 +0.41077000000000E+01 +0.41332000000000E+01 +0.41703000000000E+01 +0.42103000000000E+01 +0.42441000000000E+01 +0.42678000000000E+01 +0.42825000000000E+01 +0.42914000000000E+01 +0.42964000000000E+01 +0.43041000000000E+01 +0.43400000000000E+01 +0.44414000000000E+01 +0.40457000000000E+01 +0.40619000000000E+01 +0.40698000000000E+01 +0.40792000000000E+01 +0.40980000000000E+01 +0.41306000000000E+01 +0.41720000000000E+01 +0.42113000000000E+01 +0.42412000000000E+01 +0.42607000000000E+01 +0.42722000000000E+01 +0.42817000000000E+01 +0.43149000000000E+01 +0.44170000000000E+01 +0.36227000000000E+01 +0.38539000000000E+01 +0.39700000000000E+01 +0.40198000000000E+01 +0.40430000000000E+01 +0.40636000000000E+01 +0.40946000000000E+01 +0.41362000000000E+01 +0.41791000000000E+01 +0.42137000000000E+01 +0.42368000000000E+01 +0.42528000000000E+01 +0.42856000000000E+01 +0.43862000000000E+01 +0.20538000000000E+01 +0.28250000000000E+01 +0.33663000000000E+01 +0.37029000000000E+01 +0.38852000000000E+01 +0.39715000000000E+01 +0.40165000000000E+01 +0.40558000000000E+01 +0.41017000000000E+01 +0.41487000000000E+01 +0.41869000000000E+01 +0.42142000000000E+01 +0.42513000000000E+01 +0.43495000000000E+01 +-.26500000000000E+00 +0.82417000000000E+00 +0.18258000000000E+01 +0.26558000000000E+01 +0.32545000000000E+01 +0.36304000000000E+01 +0.38370000000000E+01 +0.39427000000000E+01 +0.40085000000000E+01 +0.40673000000000E+01 +0.41212000000000E+01 +0.41646000000000E+01 +0.42106000000000E+01 +0.43099000000000E+01 +-.23572000000000E+01 +-.12261000000000E+01 +-.11003000000000E+00 +0.96758000000000E+00 +0.19490000000000E+01 +0.27489000000000E+01 +0.33120000000000E+01 +0.36556000000000E+01 +0.38449000000000E+01 +0.39559000000000E+01 +0.40365000000000E+01 +0.41027000000000E+01 +0.41649000000000E+01 +0.42709000000000E+01 +-.41073000000000E+01 +-.29661000000000E+01 +-.18330000000000E+01 +-.71179000000000E+00 +0.38660000000000E+00 +0.14255000000000E+01 +0.23323000000000E+01 +0.30261000000000E+01 +0.34826000000000E+01 +0.37517000000000E+01 +0.39128000000000E+01 +0.40219000000000E+01 +0.41128000000000E+01 +0.42329000000000E+01 +-.55682000000000E+01 +-.44226000000000E+01 +-.32816000000000E+01 +-.21487000000000E+01 +-.10273000000000E+01 +0.75409000000000E-01 +0.11327000000000E+01 +0.20836000000000E+01 +0.28450000000000E+01 +0.33721000000000E+01 +0.37003000000000E+01 +0.39048000000000E+01 +0.40466000000000E+01 +0.41914000000000E+01 +-.67900000000000E+01 +-.56427000000000E+01 +-.44979000000000E+01 +-.33579000000000E+01 +-.22265000000000E+01 +-.11071000000000E+01 +-.59000000000000E-02 +0.10532000000000E+01 +0.20141000000000E+01 +0.27972000000000E+01 +0.33553000000000E+01 +0.37173000000000E+01 +0.39528000000000E+01 +0.41372000000000E+01 +-.78159000000000E+01 +-.66678000000000E+01 +-.55212000000000E+01 +-.43774000000000E+01 +-.32391000000000E+01 +-.21104000000000E+01 +-.99452000000000E+00 +0.10191000000000E+00 +0.11535000000000E+01 +0.21042000000000E+01 +0.28788000000000E+01 +0.34377000000000E+01 +0.38112000000000E+01 +0.40709000000000E+01 +-.86821000000000E+01 +-.75336000000000E+01 +-.63860000000000E+01 +-.52401000000000E+01 +-.40978000000000E+01 +-.29621000000000E+01 +-.18374000000000E+01 +-.72617000000000E+00 +0.36288000000000E+00 +0.13995000000000E+01 +0.23248000000000E+01 +0.30704000000000E+01 +0.36053000000000E+01 +0.39739000000000E+01 +-.94180000000000E+01 +-.82693000000000E+01 +-.71212000000000E+01 +-.59741000000000E+01 +-.48292000000000E+01 +-.36891000000000E+01 +-.25574000000000E+01 +-.14373000000000E+01 +-.33125000000000E+00 +0.74690000000000E+00 +0.17599000000000E+01 +0.26469000000000E+01 +0.33425000000000E+01 +0.38420000000000E+01 +-.10051000000000E+02 +-.89016000000000E+01 +-.77533000000000E+01 +-.66052000000000E+01 +-.54587000000000E+01 +-.43157000000000E+01 +-.31790000000000E+01 +-.20518000000000E+01 +-.93585000000000E+00 +0.16351000000000E+00 +0.12248000000000E+01 +0.22041000000000E+01 +0.30323000000000E+01 +0.36680000000000E+01 +-.10602000000000E+02 +-.94534000000000E+01 +-.83047000000000E+01 +-.71561000000000E+01 +-.60084000000000E+01 +-.48634000000000E+01 +-.37231000000000E+01 +-.25903000000000E+01 +-.14670000000000E+01 +-.35535000000000E+00 +0.73309000000000E+00 +0.17656000000000E+01 +0.26929000000000E+01 +0.34482000000000E+01 +-.11100000000000E+02 +-.99507000000000E+01 +-.88015000000000E+01 +-.76525000000000E+01 +-.65040000000000E+01 +-.53575000000000E+01 +-.42148000000000E+01 +-.30778000000000E+01 +-.19485000000000E+01 +-.82877000000000E+00 +0.27538000000000E+00 +0.13418000000000E+01 +0.23354000000000E+01 +0.31918000000000E+01 +-.11549000000000E+02 +-.10400000000000E+02 +-.92505000000000E+01 +-.81011000000000E+01 +-.69519000000000E+01 +-.58044000000000E+01 +-.46599000000000E+01 +-.35197000000000E+01 +-.23853000000000E+01 +-.12592000000000E+01 +-.14445000000000E+00 +0.94456000000000E+00 +0.19835000000000E+01 +0.29187000000000E+01 +-.11960000000000E+02 +-.10811000000000E+02 +-.96611000000000E+01 +-.85112000000000E+01 +-.73617000000000E+01 +-.62134000000000E+01 +-.50675000000000E+01 +-.39247000000000E+01 +-.27863000000000E+01 +-.16548000000000E+01 +-.53262000000000E+00 +0.57387000000000E+00 +0.16416000000000E+01 +0.26356000000000E+01 +-.12342000000000E+02 +-.11193000000000E+02 +-.10043000000000E+02 +-.88926000000000E+01 +-.77427000000000E+01 +-.65937000000000E+01 +-.54468000000000E+01 +-.43020000000000E+01 +-.31605000000000E+01 +-.20247000000000E+01 +-.89674000000000E+00 +0.21986000000000E+00 +0.13098000000000E+01 +0.23465000000000E+01 +-.12682000000000E+02 +-.11532000000000E+02 +-.10382000000000E+02 +-.92317000000000E+01 +-.80815000000000E+01 +-.69320000000000E+01 +-.57839000000000E+01 +-.46377000000000E+01 +-.34938000000000E+01 +-.23543000000000E+01 +-.12216000000000E+01 +-.97370000000000E-01 +0.10088000000000E+01 +0.20775000000000E+01 +-.13009000000000E+02 +-.11859000000000E+02 +-.10708000000000E+02 +-.95576000000000E+01 +-.84072000000000E+01 +-.72573000000000E+01 +-.61085000000000E+01 +-.49611000000000E+01 +-.38152000000000E+01 +-.26730000000000E+01 +-.15365000000000E+01 +-.40687000000000E+00 +0.71054000000000E+00 +0.18013000000000E+01 +-.13333000000000E+02 +-.12182000000000E+02 +-.11032000000000E+02 +-.98809000000000E+01 +-.87302000000000E+01 +-.75800000000000E+01 +-.64307000000000E+01 +-.52822000000000E+01 +-.41351000000000E+01 +-.29906000000000E+01 +-.18511000000000E+01 +-.71744000000000E+00 +0.40791000000000E+00 +0.15146000000000E+01 +-.13654000000000E+02 +-.12504000000000E+02 +-.11353000000000E+02 +-.10202000000000E+02 +-.90513000000000E+01 +-.79009000000000E+01 +-.67511000000000E+01 +-.56021000000000E+01 +-.44539000000000E+01 +-.33077000000000E+01 +-.21657000000000E+01 +-.10290000000000E+01 +0.10273000000000E+00 +0.12198000000000E+01 +-.13973000000000E+02 +-.12822000000000E+02 +-.11671000000000E+02 +-.10520000000000E+02 +-.93691000000000E+01 +-.82185000000000E+01 +-.70684000000000E+01 +-.59188000000000E+01 +-.47699000000000E+01 +-.36224000000000E+01 +-.24784000000000E+01 +-.13391000000000E+01 +-.20383000000000E+00 +0.92165000000000E+00 +-.14262000000000E+02 +-.13112000000000E+02 +-.11961000000000E+02 +-.10810000000000E+02 +-.96584000000000E+01 +-.85076000000000E+01 +-.73573000000000E+01 +-.62073000000000E+01 +-.50577000000000E+01 +-.39094000000000E+01 +-.27636000000000E+01 +-.16221000000000E+01 +-.48406000000000E+00 +0.64757000000000E+00 +0.36838000000000E+01 +0.36843000000000E+01 +0.36847000000000E+01 +0.36850000000000E+01 +0.36852000000000E+01 +0.36853000000000E+01 +0.36853000000000E+01 +0.36852000000000E+01 +0.36851000000000E+01 +0.36854000000000E+01 +0.36876000000000E+01 +0.36992000000000E+01 +0.37402000000000E+01 +0.38541000000000E+01 +0.36812000000000E+01 +0.36821000000000E+01 +0.36828000000000E+01 +0.36833000000000E+01 +0.36838000000000E+01 +0.36841000000000E+01 +0.36843000000000E+01 +0.36843000000000E+01 +0.36842000000000E+01 +0.36844000000000E+01 +0.36865000000000E+01 +0.36981000000000E+01 +0.37390000000000E+01 +0.38524000000000E+01 +0.36765000000000E+01 +0.36780000000000E+01 +0.36794000000000E+01 +0.36804000000000E+01 +0.36813000000000E+01 +0.36820000000000E+01 +0.36825000000000E+01 +0.36827000000000E+01 +0.36826000000000E+01 +0.36827000000000E+01 +0.36848000000000E+01 +0.36963000000000E+01 +0.37371000000000E+01 +0.38503000000000E+01 +0.36686000000000E+01 +0.36713000000000E+01 +0.36736000000000E+01 +0.36755000000000E+01 +0.36771000000000E+01 +0.36783000000000E+01 +0.36793000000000E+01 +0.36799000000000E+01 +0.36802000000000E+01 +0.36802000000000E+01 +0.36819000000000E+01 +0.36936000000000E+01 +0.37344000000000E+01 +0.38474000000000E+01 +0.36562000000000E+01 +0.36608000000000E+01 +0.36647000000000E+01 +0.36679000000000E+01 +0.36705000000000E+01 +0.36727000000000E+01 +0.36744000000000E+01 +0.36756000000000E+01 +0.36763000000000E+01 +0.36766000000000E+01 +0.36779000000000E+01 +0.36891000000000E+01 +0.37306000000000E+01 +0.38434000000000E+01 +0.36224000000000E+01 +0.36387000000000E+01 +0.36490000000000E+01 +0.36557000000000E+01 +0.36605000000000E+01 +0.36641000000000E+01 +0.36671000000000E+01 +0.36693000000000E+01 +0.36707000000000E+01 +0.36714000000000E+01 +0.36724000000000E+01 +0.36827000000000E+01 +0.37224000000000E+01 +0.38365000000000E+01 +0.35421000000000E+01 +0.35762000000000E+01 +0.36057000000000E+01 +0.36274000000000E+01 +0.36414000000000E+01 +0.36501000000000E+01 +0.36558000000000E+01 +0.36598000000000E+01 +0.36625000000000E+01 +0.36642000000000E+01 +0.36653000000000E+01 +0.36747000000000E+01 +0.37126000000000E+01 +0.38217000000000E+01 +0.34716000000000E+01 +0.34938000000000E+01 +0.35269000000000E+01 +0.35635000000000E+01 +0.35959000000000E+01 +0.36198000000000E+01 +0.36349000000000E+01 +0.36444000000000E+01 +0.36503000000000E+01 +0.36538000000000E+01 +0.36558000000000E+01 +0.36640000000000E+01 +0.37010000000000E+01 +0.38063000000000E+01 +0.34451000000000E+01 +0.34502000000000E+01 +0.34625000000000E+01 +0.34871000000000E+01 +0.35227000000000E+01 +0.35609000000000E+01 +0.35930000000000E+01 +0.36154000000000E+01 +0.36293000000000E+01 +0.36381000000000E+01 +0.36425000000000E+01 +0.36503000000000E+01 +0.36868000000000E+01 +0.37892000000000E+01 +0.34057000000000E+01 +0.34219000000000E+01 +0.34297000000000E+01 +0.34389000000000E+01 +0.34570000000000E+01 +0.34884000000000E+01 +0.35280000000000E+01 +0.35653000000000E+01 +0.35937000000000E+01 +0.36122000000000E+01 +0.36230000000000E+01 +0.36326000000000E+01 +0.36662000000000E+01 +0.37693000000000E+01 +0.29886000000000E+01 +0.32198000000000E+01 +0.33359000000000E+01 +0.33857000000000E+01 +0.34086000000000E+01 +0.34288000000000E+01 +0.34587000000000E+01 +0.34986000000000E+01 +0.35393000000000E+01 +0.35722000000000E+01 +0.35939000000000E+01 +0.36088000000000E+01 +0.36402000000000E+01 +0.37383000000000E+01 +0.14269000000000E+01 +0.21981000000000E+01 +0.27395000000000E+01 +0.30762000000000E+01 +0.32584000000000E+01 +0.33446000000000E+01 +0.33891000000000E+01 +0.34274000000000E+01 +0.34714000000000E+01 +0.35162000000000E+01 +0.35523000000000E+01 +0.35780000000000E+01 +0.36131000000000E+01 +0.37079000000000E+01 +-.88393000000000E+00 +0.20557000000000E+00 +0.12072000000000E+01 +0.20372000000000E+01 +0.26359000000000E+01 +0.30118000000000E+01 +0.32182000000000E+01 +0.33235000000000E+01 +0.33882000000000E+01 +0.34449000000000E+01 +0.34965000000000E+01 +0.35375000000000E+01 +0.35814000000000E+01 +0.36776000000000E+01 +-.29727000000000E+01 +-.18382000000000E+01 +-.72052000000000E+00 +0.35730000000000E+00 +0.13387000000000E+01 +0.21385000000000E+01 +0.27016000000000E+01 +0.30449000000000E+01 +0.32336000000000E+01 +0.33431000000000E+01 +0.34214000000000E+01 +0.34849000000000E+01 +0.35441000000000E+01 +0.36456000000000E+01 +-.47198000000000E+01 +-.35765000000000E+01 +-.24398000000000E+01 +-.13155000000000E+01 +-.21621000000000E+00 +0.82268000000000E+00 +0.17294000000000E+01 +0.24229000000000E+01 +0.28791000000000E+01 +0.31473000000000E+01 +0.33065000000000E+01 +0.34127000000000E+01 +0.35000000000000E+01 +0.36152000000000E+01 +-.61765000000000E+01 +-.50302000000000E+01 +-.38872000000000E+01 +-.27506000000000E+01 +-.16255000000000E+01 +-.52136000000000E+00 +0.53590000000000E+00 +0.14867000000000E+01 +0.22477000000000E+01 +0.27742000000000E+01 +0.31009000000000E+01 +0.33030000000000E+01 +0.34411000000000E+01 +0.35831000000000E+01 +-.73944000000000E+01 +-.62468000000000E+01 +-.51013000000000E+01 +-.39594000000000E+01 +-.28241000000000E+01 +-.17008000000000E+01 +-.59804000000000E+00 +0.46099000000000E+00 +0.14216000000000E+01 +0.22042000000000E+01 +0.27612000000000E+01 +0.31210000000000E+01 +0.33530000000000E+01 +0.35377000000000E+01 +-.84165000000000E+01 +-.72684000000000E+01 +-.61216000000000E+01 +-.49769000000000E+01 +-.38364000000000E+01 +-.27036000000000E+01 +-.15841000000000E+01 +-.48650000000000E+00 +0.56490000000000E+00 +0.15151000000000E+01 +0.22888000000000E+01 +0.28461000000000E+01 +0.32166000000000E+01 +0.34799000000000E+01 +-.92788000000000E+01 +-.81301000000000E+01 +-.69825000000000E+01 +-.58363000000000E+01 +-.46927000000000E+01 +-.35545000000000E+01 +-.24256000000000E+01 +-.13114000000000E+01 +-.22182000000000E+00 +0.81433000000000E+00 +0.17389000000000E+01 +0.24833000000000E+01 +0.30204000000000E+01 +0.33903000000000E+01 +-.10010000000000E+02 +-.88611000000000E+01 +-.77130000000000E+01 +-.65657000000000E+01 +-.54203000000000E+01 +-.42786000000000E+01 +-.31437000000000E+01 +-.20197000000000E+01 +-.91182000000000E+00 +0.16614000000000E+00 +0.11784000000000E+01 +0.20641000000000E+01 +0.27649000000000E+01 +0.32655000000000E+01 +-.10634000000000E+02 +-.94846000000000E+01 +-.83362000000000E+01 +-.71881000000000E+01 +-.60414000000000E+01 +-.48975000000000E+01 +-.37587000000000E+01 +-.26279000000000E+01 +-.15090000000000E+01 +-.40915000000000E+00 +0.65150000000000E+00 +0.16298000000000E+01 +0.24617000000000E+01 +0.31033000000000E+01 +-.11173000000000E+02 +-.10024000000000E+02 +-.88755000000000E+01 +-.77268000000000E+01 +-.65790000000000E+01 +-.54335000000000E+01 +-.42920000000000E+01 +-.31564000000000E+01 +-.20297000000000E+01 +-.91669000000000E+00 +0.17144000000000E+00 +0.12067000000000E+01 +0.21337000000000E+01 +0.28950000000000E+01 +-.11656000000000E+02 +-.10506000000000E+02 +-.93574000000000E+01 +-.82083000000000E+01 +-.70597000000000E+01 +-.59130000000000E+01 +-.47695000000000E+01 +-.36306000000000E+01 +-.24982000000000E+01 +-.13763000000000E+01 +-.27203000000000E+00 +0.79701000000000E+00 +0.17902000000000E+01 +0.26525000000000E+01 +-.12093000000000E+02 +-.10944000000000E+02 +-.97947000000000E+01 +-.86450000000000E+01 +-.74960000000000E+01 +-.63484000000000E+01 +-.52035000000000E+01 +-.40619000000000E+01 +-.29251000000000E+01 +-.17965000000000E+01 +-.68108000000000E+00 +0.41017000000000E+00 +0.14481000000000E+01 +0.23876000000000E+01 +-.12490000000000E+02 +-.11341000000000E+02 +-.10191000000000E+02 +-.90415000000000E+01 +-.78920000000000E+01 +-.67435000000000E+01 +-.55974000000000E+01 +-.44539000000000E+01 +-.33137000000000E+01 +-.21797000000000E+01 +-.10562000000000E+01 +0.49981000000000E-01 +0.11188000000000E+01 +0.21155000000000E+01 +-.12857000000000E+02 +-.11708000000000E+02 +-.10558000000000E+02 +-.94077000000000E+01 +-.82578000000000E+01 +-.71089000000000E+01 +-.59617000000000E+01 +-.48165000000000E+01 +-.36736000000000E+01 +-.25356000000000E+01 +-.14059000000000E+01 +-.28913000000000E+00 +0.80135000000000E+00 +0.18399000000000E+01 +-.13204000000000E+02 +-.12055000000000E+02 +-.10905000000000E+02 +-.97542000000000E+01 +-.86040000000000E+01 +-.74545000000000E+01 +-.63065000000000E+01 +-.51599000000000E+01 +-.40151000000000E+01 +-.28738000000000E+01 +-.17392000000000E+01 +-.61484000000000E+00 +0.49102000000000E+00 +0.15596000000000E+01 +-.13515000000000E+02 +-.12365000000000E+02 +-.11215000000000E+02 +-.10064000000000E+02 +-.89136000000000E+01 +-.77638000000000E+01 +-.66151000000000E+01 +-.54674000000000E+01 +-.43209000000000E+01 +-.31771000000000E+01 +-.20386000000000E+01 +-.90826000000000E+00 +0.20900000000000E+00 +0.12997000000000E+01 +-.13821000000000E+02 +-.12670000000000E+02 +-.11520000000000E+02 +-.10369000000000E+02 +-.92185000000000E+01 +-.80684000000000E+01 +-.69191000000000E+01 +-.57705000000000E+01 +-.46228000000000E+01 +-.34771000000000E+01 +-.23356000000000E+01 +-.12007000000000E+01 +-.74970000000000E-01 +0.10316000000000E+01 +-.14125000000000E+02 +-.12975000000000E+02 +-.11824000000000E+02 +-.10674000000000E+02 +-.95227000000000E+01 +-.83721000000000E+01 +-.72224000000000E+01 +-.60734000000000E+01 +-.49247000000000E+01 +-.37776000000000E+01 +-.26337000000000E+01 +-.14953000000000E+01 +-.36314000000000E+00 +0.75417000000000E+00 +-.14430000000000E+02 +-.13280000000000E+02 +-.12129000000000E+02 +-.10978000000000E+02 +-.98269000000000E+01 +-.86760000000000E+01 +-.75260000000000E+01 +-.63765000000000E+01 +-.52272000000000E+01 +-.40790000000000E+01 +-.29333000000000E+01 +-.17922000000000E+01 +-.65605000000000E+00 +0.46966000000000E+00 +-.14738000000000E+02 +-.13587000000000E+02 +-.12436000000000E+02 +-.11285000000000E+02 +-.10134000000000E+02 +-.89829000000000E+01 +-.78325000000000E+01 +-.66825000000000E+01 +-.55327000000000E+01 +-.43838000000000E+01 +-.32368000000000E+01 +-.20934000000000E+01 +-.95435000000000E+00 +0.17732000000000E+00 +0.31281000000000E+01 +0.31284000000000E+01 +0.31286000000000E+01 +0.31288000000000E+01 +0.31289000000000E+01 +0.31290000000000E+01 +0.31290000000000E+01 +0.31289000000000E+01 +0.31288000000000E+01 +0.31290000000000E+01 +0.31317000000000E+01 +0.31437000000000E+01 +0.31854000000000E+01 +0.32996000000000E+01 +0.31267000000000E+01 +0.31273000000000E+01 +0.31279000000000E+01 +0.31282000000000E+01 +0.31285000000000E+01 +0.31287000000000E+01 +0.31288000000000E+01 +0.31288000000000E+01 +0.31287000000000E+01 +0.31288000000000E+01 +0.31314000000000E+01 +0.31435000000000E+01 +0.31850000000000E+01 +0.32988000000000E+01 +0.31237000000000E+01 +0.31250000000000E+01 +0.31260000000000E+01 +0.31269000000000E+01 +0.31276000000000E+01 +0.31281000000000E+01 +0.31283000000000E+01 +0.31284000000000E+01 +0.31284000000000E+01 +0.31284000000000E+01 +0.31309000000000E+01 +0.31430000000000E+01 +0.31844000000000E+01 +0.32979000000000E+01 +0.31180000000000E+01 +0.31205000000000E+01 +0.31224000000000E+01 +0.31241000000000E+01 +0.31253000000000E+01 +0.31263000000000E+01 +0.31270000000000E+01 +0.31274000000000E+01 +0.31274000000000E+01 +0.31276000000000E+01 +0.31296000000000E+01 +0.31419000000000E+01 +0.31833000000000E+01 +0.32966000000000E+01 +0.31082000000000E+01 +0.31125000000000E+01 +0.31160000000000E+01 +0.31188000000000E+01 +0.31211000000000E+01 +0.31228000000000E+01 +0.31242000000000E+01 +0.31251000000000E+01 +0.31256000000000E+01 +0.31259000000000E+01 +0.31274000000000E+01 +0.31392000000000E+01 +0.31813000000000E+01 +0.32945000000000E+01 +0.30781000000000E+01 +0.30934000000000E+01 +0.31032000000000E+01 +0.31093000000000E+01 +0.31136000000000E+01 +0.31168000000000E+01 +0.31193000000000E+01 +0.31211000000000E+01 +0.31223000000000E+01 +0.31229000000000E+01 +0.31241000000000E+01 +0.31349000000000E+01 +0.31753000000000E+01 +0.32897000000000E+01 +0.30048000000000E+01 +0.30367000000000E+01 +0.30644000000000E+01 +0.30848000000000E+01 +0.30978000000000E+01 +0.31057000000000E+01 +0.31107000000000E+01 +0.31143000000000E+01 +0.31166000000000E+01 +0.31181000000000E+01 +0.31194000000000E+01 +0.31293000000000E+01 +0.31677000000000E+01 +0.32772000000000E+01 +0.29413000000000E+01 +0.29619000000000E+01 +0.29927000000000E+01 +0.30269000000000E+01 +0.30573000000000E+01 +0.30793000000000E+01 +0.30933000000000E+01 +0.31020000000000E+01 +0.31073000000000E+01 +0.31105000000000E+01 +0.31125000000000E+01 +0.31211000000000E+01 +0.31587000000000E+01 +0.32642000000000E+01 +0.29188000000000E+01 +0.29235000000000E+01 +0.29350000000000E+01 +0.29578000000000E+01 +0.29910000000000E+01 +0.30266000000000E+01 +0.30563000000000E+01 +0.30771000000000E+01 +0.30900000000000E+01 +0.30981000000000E+01 +0.31023000000000E+01 +0.31104000000000E+01 +0.31474000000000E+01 +0.32501000000000E+01 +0.28829000000000E+01 +0.28991000000000E+01 +0.29067000000000E+01 +0.29154000000000E+01 +0.29323000000000E+01 +0.29615000000000E+01 +0.29980000000000E+01 +0.30327000000000E+01 +0.30592000000000E+01 +0.30765000000000E+01 +0.30867000000000E+01 +0.30962000000000E+01 +0.31302000000000E+01 +0.32336000000000E+01 +0.24695000000000E+01 +0.27007000000000E+01 +0.28169000000000E+01 +0.28666000000000E+01 +0.28892000000000E+01 +0.29083000000000E+01 +0.29359000000000E+01 +0.29729000000000E+01 +0.30109000000000E+01 +0.30417000000000E+01 +0.30621000000000E+01 +0.30765000000000E+01 +0.31081000000000E+01 +0.32065000000000E+01 +0.91066000000000E+00 +0.16819000000000E+01 +0.22234000000000E+01 +0.25601000000000E+01 +0.27422000000000E+01 +0.28281000000000E+01 +0.28715000000000E+01 +0.29076000000000E+01 +0.29487000000000E+01 +0.29906000000000E+01 +0.30243000000000E+01 +0.30480000000000E+01 +0.30806000000000E+01 +0.31705000000000E+01 +-.13996000000000E+01 +-.31037000000000E+00 +0.69078000000000E+00 +0.15206000000000E+01 +0.21193000000000E+01 +0.24952000000000E+01 +0.27012000000000E+01 +0.28049000000000E+01 +0.28676000000000E+01 +0.29213000000000E+01 +0.29696000000000E+01 +0.30079000000000E+01 +0.30486000000000E+01 +0.31390000000000E+01 +-.34941000000000E+01 +-.23590000000000E+01 +-.12417000000000E+01 +-.16526000000000E+00 +0.81508000000000E+00 +0.16144000000000E+01 +0.21772000000000E+01 +0.25201000000000E+01 +0.27067000000000E+01 +0.28130000000000E+01 +0.28891000000000E+01 +0.29491000000000E+01 +0.30049000000000E+01 +0.31010000000000E+01 +-.52537000000000E+01 +-.41099000000000E+01 +-.29729000000000E+01 +-.18494000000000E+01 +-.75293000000000E+00 +0.28318000000000E+00 +0.11884000000000E+01 +0.18811000000000E+01 +0.23364000000000E+01 +0.26017000000000E+01 +0.27568000000000E+01 +0.28610000000000E+01 +0.29437000000000E+01 +0.30522000000000E+01 +-.67292000000000E+01 +-.55829000000000E+01 +-.44398000000000E+01 +-.33033000000000E+01 +-.21799000000000E+01 +-.10801000000000E+01 +-.27781000000000E-01 +0.91998000000000E+00 +0.16795000000000E+01 +0.22044000000000E+01 +0.25270000000000E+01 +0.27241000000000E+01 +0.28596000000000E+01 +0.29942000000000E+01 +-.79713000000000E+01 +-.68237000000000E+01 +-.56782000000000E+01 +-.45363000000000E+01 +-.34017000000000E+01 +-.22810000000000E+01 +-.11846000000000E+01 +-.13245000000000E+00 +0.82397000000000E+00 +0.16042000000000E+01 +0.21581000000000E+01 +0.25129000000000E+01 +0.27393000000000E+01 +0.29194000000000E+01 +-.90198000000000E+01 +-.78717000000000E+01 +-.67247000000000E+01 +-.55802000000000E+01 +-.44399000000000E+01 +-.33084000000000E+01 +-.21930000000000E+01 +-.11036000000000E+01 +-.60200000000000E-01 +0.88524000000000E+00 +0.16560000000000E+01 +0.22083000000000E+01 +0.25730000000000E+01 +0.28295000000000E+01 +-.99070000000000E+01 +-.87583000000000E+01 +-.76107000000000E+01 +-.64645000000000E+01 +-.53212000000000E+01 +-.41833000000000E+01 +-.30566000000000E+01 +-.19485000000000E+01 +-.86873000000000E+00 +0.15943000000000E+00 +0.10795000000000E+01 +0.18192000000000E+01 +0.23508000000000E+01 +0.27189000000000E+01 +-.10659000000000E+02 +-.95103000000000E+01 +-.83621000000000E+01 +-.72147000000000E+01 +-.60695000000000E+01 +-.49280000000000E+01 +-.37943000000000E+01 +-.26738000000000E+01 +-.15744000000000E+01 +-.50668000000000E+00 +0.49860000000000E+00 +0.13793000000000E+01 +0.20749000000000E+01 +0.25763000000000E+01 +-.11299000000000E+02 +-.10150000000000E+02 +-.90012000000000E+01 +-.78533000000000E+01 +-.67065000000000E+01 +-.55627000000000E+01 +-.44246000000000E+01 +-.32959000000000E+01 +-.21830000000000E+01 +-.10934000000000E+01 +-.42025000000000E-01 +0.93016000000000E+00 +0.17611000000000E+01 +0.24011000000000E+01 +-.11844000000000E+02 +-.10696000000000E+02 +-.95469000000000E+01 +-.83982000000000E+01 +-.72504000000000E+01 +-.61050000000000E+01 +-.49639000000000E+01 +-.38295000000000E+01 +-.27067000000000E+01 +-.16024000000000E+01 +-.52452000000000E+00 +0.50343000000000E+00 +0.14311000000000E+01 +0.21915000000000E+01 +-.12326000000000E+02 +-.11177000000000E+02 +-.10028000000000E+02 +-.88787000000000E+01 +-.77303000000000E+01 +-.65837000000000E+01 +-.54404000000000E+01 +-.43022000000000E+01 +-.31724000000000E+01 +-.20571000000000E+01 +-.96294000000000E+00 +0.97500000000000E-01 +0.10883000000000E+01 +0.19520000000000E+01 +-.12754000000000E+02 +-.11605000000000E+02 +-.10456000000000E+02 +-.93064000000000E+01 +-.81572000000000E+01 +-.70099000000000E+01 +-.58651000000000E+01 +-.47240000000000E+01 +-.35887000000000E+01 +-.24648000000000E+01 +-.13583000000000E+01 +-.27602000000000E+00 +0.75861000000000E+00 +0.16999000000000E+01 +-.13143000000000E+02 +-.11994000000000E+02 +-.10844000000000E+02 +-.96946000000000E+01 +-.85449000000000E+01 +-.73967000000000E+01 +-.62507000000000E+01 +-.51075000000000E+01 +-.39683000000000E+01 +-.28376000000000E+01 +-.17214000000000E+01 +-.62425000000000E+00 +0.43981000000000E+00 +0.14370000000000E+01 +-.13498000000000E+02 +-.12349000000000E+02 +-.11199000000000E+02 +-.10049000000000E+02 +-.88987000000000E+01 +-.77499000000000E+01 +-.66028000000000E+01 +-.54579000000000E+01 +-.43157000000000E+01 +-.31799000000000E+01 +-.20558000000000E+01 +-.94756000000000E+00 +0.13707000000000E+00 +0.11746000000000E+01 +-.13829000000000E+02 +-.12679000000000E+02 +-.11529000000000E+02 +-.10378000000000E+02 +-.92280000000000E+01 +-.80786000000000E+01 +-.69307000000000E+01 +-.57844000000000E+01 +-.46400000000000E+01 +-.35002000000000E+01 +-.23699000000000E+01 +-.12529000000000E+01 +-.15353000000000E+00 +0.91293000000000E+00 +-.14151000000000E+02 +-.13001000000000E+02 +-.11851000000000E+02 +-.10700000000000E+02 +-.95498000000000E+01 +-.83999000000000E+01 +-.72513000000000E+01 +-.61040000000000E+01 +-.49579000000000E+01 +-.38152000000000E+01 +-.26800000000000E+01 +-.15562000000000E+01 +-.44616000000000E+00 +0.64009000000000E+00 +-.14437000000000E+02 +-.13287000000000E+02 +-.12136000000000E+02 +-.10985000000000E+02 +-.98347000000000E+01 +-.86846000000000E+01 +-.75353000000000E+01 +-.63870000000000E+01 +-.52396000000000E+01 +-.40946000000000E+01 +-.29555000000000E+01 +-.18260000000000E+01 +-.70628000000000E+00 +0.39475000000000E+00 +-.14717000000000E+02 +-.13567000000000E+02 +-.12416000000000E+02 +-.11265000000000E+02 +-.10114000000000E+02 +-.89639000000000E+01 +-.78141000000000E+01 +-.66650000000000E+01 +-.55167000000000E+01 +-.43701000000000E+01 +-.32279000000000E+01 +-.20937000000000E+01 +-.96803000000000E+00 +0.14457000000000E+00 +-.15002000000000E+02 +-.13851000000000E+02 +-.12700000000000E+02 +-.11549000000000E+02 +-.10398000000000E+02 +-.92478000000000E+01 +-.80977000000000E+01 +-.69481000000000E+01 +-.57991000000000E+01 +-.46512000000000E+01 +-.35068000000000E+01 +-.23689000000000E+01 +-.12386000000000E+01 +-.11790000000000E+00 +-.15292000000000E+02 +-.14142000000000E+02 +-.12991000000000E+02 +-.11840000000000E+02 +-.10688000000000E+02 +-.95378000000000E+01 +-.83875000000000E+01 +-.72374000000000E+01 +-.60878000000000E+01 +-.49391000000000E+01 +-.37929000000000E+01 +-.26521000000000E+01 +-.15180000000000E+01 +-.39160000000000E+00 +0.22142000000000E+01 +0.22145000000000E+01 +0.22146000000000E+01 +0.22147000000000E+01 +0.22148000000000E+01 +0.22148000000000E+01 +0.22148000000000E+01 +0.22148000000000E+01 +0.22147000000000E+01 +0.22151000000000E+01 +0.22184000000000E+01 +0.22321000000000E+01 +0.22767000000000E+01 +0.23963000000000E+01 +0.22133000000000E+01 +0.22138000000000E+01 +0.22142000000000E+01 +0.22145000000000E+01 +0.22147000000000E+01 +0.22148000000000E+01 +0.22149000000000E+01 +0.22149000000000E+01 +0.22148000000000E+01 +0.22150000000000E+01 +0.22184000000000E+01 +0.22320000000000E+01 +0.22765000000000E+01 +0.23956000000000E+01 +0.22111000000000E+01 +0.22122000000000E+01 +0.22131000000000E+01 +0.22138000000000E+01 +0.22143000000000E+01 +0.22147000000000E+01 +0.22148000000000E+01 +0.22149000000000E+01 +0.22149000000000E+01 +0.22150000000000E+01 +0.22182000000000E+01 +0.22318000000000E+01 +0.22762000000000E+01 +0.23950000000000E+01 +0.22067000000000E+01 +0.22089000000000E+01 +0.22108000000000E+01 +0.22122000000000E+01 +0.22133000000000E+01 +0.22141000000000E+01 +0.22145000000000E+01 +0.22148000000000E+01 +0.22149000000000E+01 +0.22150000000000E+01 +0.22178000000000E+01 +0.22316000000000E+01 +0.22760000000000E+01 +0.23945000000000E+01 +0.21989000000000E+01 +0.22030000000000E+01 +0.22063000000000E+01 +0.22089000000000E+01 +0.22110000000000E+01 +0.22125000000000E+01 +0.22136000000000E+01 +0.22144000000000E+01 +0.22148000000000E+01 +0.22150000000000E+01 +0.22172000000000E+01 +0.22305000000000E+01 +0.22757000000000E+01 +0.23941000000000E+01 +0.21735000000000E+01 +0.21876000000000E+01 +0.21967000000000E+01 +0.22025000000000E+01 +0.22065000000000E+01 +0.22094000000000E+01 +0.22116000000000E+01 +0.22132000000000E+01 +0.22142000000000E+01 +0.22148000000000E+01 +0.22166000000000E+01 +0.22288000000000E+01 +0.22721000000000E+01 +0.23918000000000E+01 +0.21094000000000E+01 +0.21385000000000E+01 +0.21640000000000E+01 +0.21829000000000E+01 +0.21950000000000E+01 +0.22025000000000E+01 +0.22072000000000E+01 +0.22104000000000E+01 +0.22125000000000E+01 +0.22137000000000E+01 +0.22155000000000E+01 +0.22267000000000E+01 +0.22681000000000E+01 +0.23828000000000E+01 +0.20554000000000E+01 +0.20740000000000E+01 +0.21021000000000E+01 +0.21335000000000E+01 +0.21615000000000E+01 +0.21821000000000E+01 +0.21952000000000E+01 +0.22032000000000E+01 +0.22081000000000E+01 +0.22111000000000E+01 +0.22134000000000E+01 +0.22231000000000E+01 +0.22635000000000E+01 +0.23743000000000E+01 +0.20396000000000E+01 +0.20438000000000E+01 +0.20541000000000E+01 +0.20748000000000E+01 +0.21052000000000E+01 +0.21379000000000E+01 +0.21656000000000E+01 +0.21850000000000E+01 +0.21971000000000E+01 +0.22045000000000E+01 +0.22089000000000E+01 +0.22178000000000E+01 +0.22577000000000E+01 +0.23655000000000E+01 +0.20102000000000E+01 +0.20261000000000E+01 +0.20333000000000E+01 +0.20413000000000E+01 +0.20566000000000E+01 +0.20833000000000E+01 +0.21170000000000E+01 +0.21492000000000E+01 +0.21739000000000E+01 +0.21901000000000E+01 +0.21998000000000E+01 +0.22100000000000E+01 +0.22466000000000E+01 +0.23552000000000E+01 +0.16058000000000E+01 +0.18359000000000E+01 +0.19513000000000E+01 +0.20004000000000E+01 +0.20223000000000E+01 +0.20401000000000E+01 +0.20656000000000E+01 +0.20998000000000E+01 +0.21351000000000E+01 +0.21638000000000E+01 +0.21831000000000E+01 +0.21976000000000E+01 +0.22314000000000E+01 +0.23349000000000E+01 +0.58097000000000E-01 +0.82832000000000E+00 +0.13685000000000E+01 +0.17039000000000E+01 +0.18849000000000E+01 +0.19696000000000E+01 +0.20118000000000E+01 +0.20458000000000E+01 +0.20843000000000E+01 +0.21233000000000E+01 +0.21550000000000E+01 +0.21782000000000E+01 +0.22124000000000E+01 +0.23071000000000E+01 +-.22433000000000E+01 +-.11530000000000E+01 +-.15195000000000E+00 +0.67705000000000E+00 +0.12743000000000E+01 +0.16486000000000E+01 +0.18528000000000E+01 +0.19550000000000E+01 +0.20156000000000E+01 +0.20663000000000E+01 +0.21117000000000E+01 +0.21477000000000E+01 +0.21870000000000E+01 +0.22758000000000E+01 +-.43317000000000E+01 +-.31946000000000E+01 +-.20745000000000E+01 +-.99655000000000E+00 +-.16436000000000E-01 +0.78169000000000E+00 +0.13425000000000E+01 +0.16830000000000E+01 +0.18679000000000E+01 +0.19716000000000E+01 +0.20443000000000E+01 +0.21005000000000E+01 +0.21517000000000E+01 +0.22399000000000E+01 +-.60841000000000E+01 +-.49397000000000E+01 +-.38007000000000E+01 +-.26736000000000E+01 +-.15739000000000E+01 +-.53735000000000E+00 +0.36642000000000E+00 +0.10569000000000E+01 +0.15096000000000E+01 +0.17727000000000E+01 +0.19248000000000E+01 +0.20250000000000E+01 +0.21033000000000E+01 +0.22054000000000E+01 +-.75558000000000E+01 +-.64093000000000E+01 +-.52655000000000E+01 +-.41270000000000E+01 +-.29995000000000E+01 +-.18959000000000E+01 +-.84332000000000E+00 +0.10204000000000E+00 +0.85855000000000E+00 +0.13800000000000E+01 +0.16999000000000E+01 +0.18932000000000E+01 +0.20238000000000E+01 +0.21516000000000E+01 +-.88030000000000E+01 +-.76555000000000E+01 +-.65099000000000E+01 +-.53672000000000E+01 +-.42305000000000E+01 +-.31060000000000E+01 +-.20066000000000E+01 +-.95663000000000E+00 +-.54566000000000E-02 +0.76967000000000E+00 +0.13192000000000E+01 +0.16699000000000E+01 +0.18910000000000E+01 +0.20630000000000E+01 +-.98721000000000E+01 +-.87239000000000E+01 +-.75770000000000E+01 +-.64323000000000E+01 +-.52913000000000E+01 +-.41577000000000E+01 +-.30394000000000E+01 +-.19505000000000E+01 +-.91510000000000E+00 +0.19773000000000E-01 +0.78198000000000E+00 +0.13288000000000E+01 +0.16877000000000E+01 +0.19362000000000E+01 +-.10798000000000E+02 +-.96492000000000E+01 +-.85015000000000E+01 +-.73553000000000E+01 +-.62118000000000E+01 +-.50734000000000E+01 +-.39452000000000E+01 +-.28368000000000E+01 +-.17646000000000E+01 +-.75363000000000E+00 +0.14959000000000E+00 +0.87880000000000E+00 +0.14030000000000E+01 +0.17630000000000E+01 +-.11604000000000E+02 +-.10455000000000E+02 +-.93066000000000E+01 +-.81594000000000E+01 +-.70143000000000E+01 +-.58728000000000E+01 +-.47386000000000E+01 +-.36183000000000E+01 +-.25244000000000E+01 +-.14756000000000E+01 +-.49655000000000E+00 +0.36472000000000E+00 +0.10488000000000E+01 +0.15433000000000E+01 +-.12304000000000E+02 +-.11155000000000E+02 +-.10007000000000E+02 +-.88586000000000E+01 +-.77120000000000E+01 +-.65685000000000E+01 +-.54304000000000E+01 +-.43021000000000E+01 +-.31929000000000E+01 +-.21192000000000E+01 +-.10984000000000E+01 +-.15541000000000E+00 +0.65785000000000E+00 +0.12915000000000E+01 +-.12909000000000E+02 +-.11760000000000E+02 +-.10611000000000E+02 +-.94626000000000E+01 +-.83149000000000E+01 +-.71698000000000E+01 +-.60289000000000E+01 +-.48951000000000E+01 +-.37748000000000E+01 +-.26819000000000E+01 +-.16329000000000E+01 +-.64055000000000E+00 +0.26210000000000E+00 +0.10150000000000E+01 +-.13437000000000E+02 +-.12288000000000E+02 +-.11139000000000E+02 +-.99902000000000E+01 +-.88418000000000E+01 +-.76954000000000E+01 +-.65526000000000E+01 +-.54149000000000E+01 +-.42867000000000E+01 +-.31791000000000E+01 +-.21083000000000E+01 +-.10847000000000E+01 +-.12140000000000E+00 +0.72887000000000E+00 +-.13896000000000E+02 +-.12747000000000E+02 +-.11597000000000E+02 +-.10448000000000E+02 +-.92988000000000E+01 +-.81514000000000E+01 +-.70070000000000E+01 +-.58665000000000E+01 +-.47324000000000E+01 +-.36135000000000E+01 +-.25244000000000E+01 +-.14760000000000E+01 +-.47146000000000E+00 +0.45266000000000E+00 +-.14294000000000E+02 +-.13145000000000E+02 +-.11995000000000E+02 +-.10845000000000E+02 +-.96958000000000E+01 +-.85476000000000E+01 +-.74021000000000E+01 +-.62593000000000E+01 +-.51211000000000E+01 +-.39937000000000E+01 +-.28897000000000E+01 +-.18209000000000E+01 +-.78697000000000E+00 +0.19062000000000E+00 +-.14644000000000E+02 +-.13495000000000E+02 +-.12345000000000E+02 +-.11195000000000E+02 +-.10045000000000E+02 +-.88962000000000E+01 +-.77495000000000E+01 +-.66050000000000E+01 +-.54635000000000E+01 +-.43300000000000E+01 +-.32144000000000E+01 +-.21285000000000E+01 +-.10724000000000E+01 +-.56648000000000E-01 +-.14965000000000E+02 +-.13815000000000E+02 +-.12665000000000E+02 +-.11514000000000E+02 +-.10364000000000E+02 +-.92148000000000E+01 +-.80671000000000E+01 +-.69214000000000E+01 +-.57775000000000E+01 +-.46393000000000E+01 +-.35148000000000E+01 +-.24149000000000E+01 +-.13415000000000E+01 +-.29864000000000E+00 +-.15266000000000E+02 +-.14116000000000E+02 +-.12966000000000E+02 +-.11815000000000E+02 +-.10665000000000E+02 +-.95154000000000E+01 +-.83669000000000E+01 +-.72198000000000E+01 +-.60742000000000E+01 +-.49326000000000E+01 +-.38014000000000E+01 +-.26901000000000E+01 +-.16028000000000E+01 +-.54060000000000E+00 +-.15551000000000E+02 +-.14400000000000E+02 +-.13250000000000E+02 +-.12099000000000E+02 +-.10948000000000E+02 +-.97983000000000E+01 +-.86494000000000E+01 +-.75013000000000E+01 +-.63544000000000E+01 +-.52102000000000E+01 +-.40739000000000E+01 +-.29534000000000E+01 +-.18543000000000E+01 +-.77672000000000E+00 +-.15826000000000E+02 +-.14676000000000E+02 +-.13525000000000E+02 +-.12375000000000E+02 +-.11224000000000E+02 +-.10073000000000E+02 +-.89238000000000E+01 +-.77750000000000E+01 +-.66270000000000E+01 +-.54810000000000E+01 +-.43407000000000E+01 +-.32131000000000E+01 +-.21041000000000E+01 +-.10145000000000E+01 +-.16064000000000E+02 +-.14913000000000E+02 +-.13762000000000E+02 +-.12612000000000E+02 +-.11461000000000E+02 +-.10310000000000E+02 +-.91602000000000E+01 +-.80107000000000E+01 +-.68618000000000E+01 +-.57144000000000E+01 +-.45713000000000E+01 +-.34382000000000E+01 +-.23209000000000E+01 +-.12211000000000E+01 +-.16314000000000E+02 +-.15164000000000E+02 +-.14013000000000E+02 +-.12862000000000E+02 +-.11711000000000E+02 +-.10560000000000E+02 +-.94097000000000E+01 +-.82598000000000E+01 +-.71102000000000E+01 +-.59618000000000E+01 +-.48167000000000E+01 +-.36792000000000E+01 +-.25552000000000E+01 +-.14474000000000E+01 +0.33839000000000E+00 +0.33855000000000E+00 +0.33867000000000E+00 +0.33875000000000E+00 +0.33881000000000E+00 +0.33884000000000E+00 +0.33883000000000E+00 +0.33880000000000E+00 +0.33877000000000E+00 +0.33924000000000E+00 +0.34436000000000E+00 +0.36340000000000E+00 +0.42310000000000E+00 +0.57428000000000E+00 +0.33768000000000E+00 +0.33808000000000E+00 +0.33839000000000E+00 +0.33863000000000E+00 +0.33878000000000E+00 +0.33884000000000E+00 +0.33892000000000E+00 +0.33888000000000E+00 +0.33884000000000E+00 +0.33921000000000E+00 +0.34422000000000E+00 +0.36326000000000E+00 +0.42280000000000E+00 +0.57347000000000E+00 +0.33579000000000E+00 +0.33677000000000E+00 +0.33752000000000E+00 +0.33808000000000E+00 +0.33849000000000E+00 +0.33875000000000E+00 +0.33885000000000E+00 +0.33884000000000E+00 +0.33895000000000E+00 +0.33920000000000E+00 +0.34406000000000E+00 +0.36305000000000E+00 +0.42252000000000E+00 +0.57283000000000E+00 +0.33192000000000E+00 +0.33389000000000E+00 +0.33549000000000E+00 +0.33671000000000E+00 +0.33761000000000E+00 +0.33824000000000E+00 +0.33865000000000E+00 +0.33885000000000E+00 +0.33889000000000E+00 +0.33925000000000E+00 +0.34357000000000E+00 +0.36276000000000E+00 +0.42223000000000E+00 +0.57228000000000E+00 +0.32491000000000E+00 +0.32858000000000E+00 +0.33154000000000E+00 +0.33388000000000E+00 +0.33568000000000E+00 +0.33699000000000E+00 +0.33794000000000E+00 +0.33858000000000E+00 +0.33891000000000E+00 +0.33933000000000E+00 +0.34296000000000E+00 +0.36153000000000E+00 +0.42188000000000E+00 +0.57181000000000E+00 +0.30136000000000E+00 +0.31451000000000E+00 +0.32285000000000E+00 +0.32819000000000E+00 +0.33184000000000E+00 +0.33445000000000E+00 +0.33635000000000E+00 +0.33775000000000E+00 +0.33865000000000E+00 +0.33936000000000E+00 +0.34244000000000E+00 +0.35964000000000E+00 +0.41788000000000E+00 +0.56943000000000E+00 +0.24197000000000E+00 +0.26921000000000E+00 +0.29298000000000E+00 +0.31058000000000E+00 +0.32184000000000E+00 +0.32861000000000E+00 +0.33286000000000E+00 +0.33577000000000E+00 +0.33775000000000E+00 +0.33914000000000E+00 +0.34203000000000E+00 +0.35796000000000E+00 +0.41388000000000E+00 +0.55974000000000E+00 +0.19307000000000E+00 +0.21042000000000E+00 +0.23654000000000E+00 +0.26584000000000E+00 +0.29194000000000E+00 +0.31111000000000E+00 +0.32324000000000E+00 +0.33061000000000E+00 +0.33517000000000E+00 +0.33816000000000E+00 +0.34152000000000E+00 +0.35552000000000E+00 +0.41032000000000E+00 +0.55180000000000E+00 +0.18124000000000E+00 +0.18508000000000E+00 +0.19465000000000E+00 +0.21394000000000E+00 +0.24220000000000E+00 +0.27263000000000E+00 +0.29847000000000E+00 +0.31660000000000E+00 +0.32800000000000E+00 +0.33505000000000E+00 +0.34030000000000E+00 +0.35307000000000E+00 +0.40697000000000E+00 +0.54518000000000E+00 +0.15760000000000E+00 +0.17314000000000E+00 +0.18018000000000E+00 +0.18762000000000E+00 +0.20189000000000E+00 +0.22656000000000E+00 +0.25797000000000E+00 +0.28808000000000E+00 +0.31133000000000E+00 +0.32684000000000E+00 +0.33701000000000E+00 +0.35049000000000E+00 +0.40024000000000E+00 +0.53943000000000E+00 +-.23482000000000E+00 +-.66886000000000E-02 +0.10743000000000E+00 +0.15593000000000E+00 +0.17724000000000E+00 +0.19400000000000E+00 +0.21774000000000E+00 +0.24971000000000E+00 +0.28290000000000E+00 +0.31023000000000E+00 +0.32936000000000E+00 +0.34673000000000E+00 +0.39235000000000E+00 +0.52567000000000E+00 +-.17652000000000E+01 +-.99643000000000E+00 +-.45852000000000E+00 +-.12545000000000E+00 +0.53775000000000E-01 +0.13723000000000E+00 +0.17819000000000E+00 +0.21054000000000E+00 +0.24678000000000E+00 +0.28388000000000E+00 +0.31477000000000E+00 +0.34007000000000E+00 +0.38486000000000E+00 +0.50777000000000E+00 +-.40513000000000E+01 +-.29598000000000E+01 +-.19583000000000E+01 +-.11302000000000E+01 +-.53508000000000E+00 +-.16336000000000E+00 +0.38618000000000E-01 +0.13891000000000E+00 +0.19787000000000E+00 +0.24656000000000E+00 +0.29060000000000E+00 +0.32800000000000E+00 +0.37649000000000E+00 +0.49194000000000E+00 +-.61211000000000E+01 +-.49830000000000E+01 +-.38612000000000E+01 +-.27809000000000E+01 +-.17997000000000E+01 +-.10025000000000E+01 +-.44408000000000E+00 +-.10630000000000E+00 +0.76048000000000E-01 +0.17744000000000E+00 +0.24902000000000E+00 +0.30584000000000E+00 +0.36468000000000E+00 +0.47682000000000E+00 +-.78484000000000E+01 +-.67039000000000E+01 +-.55638000000000E+01 +-.44346000000000E+01 +-.33312000000000E+01 +-.22912000000000E+01 +-.13864000000000E+01 +-.69739000000000E+00 +-.24752000000000E+00 +0.12631000000000E-01 +0.16192000000000E+00 +0.26206000000000E+00 +0.34374000000000E+00 +0.45984000000000E+00 +-.92888000000000E+01 +-.81423000000000E+01 +-.69984000000000E+01 +-.58588000000000E+01 +-.47286000000000E+01 +-.36196000000000E+01 +-.25607000000000E+01 +-.16118000000000E+01 +-.85547000000000E+00 +-.33662000000000E+00 +-.20138000000000E-01 +0.17023000000000E+00 +0.30183000000000E+00 +0.43510000000000E+00 +-.10500000000000E+02 +-.93523000000000E+01 +-.82063000000000E+01 +-.70634000000000E+01 +-.59252000000000E+01 +-.47968000000000E+01 +-.36893000000000E+01 +-.26290000000000E+01 +-.16711000000000E+01 +-.89496000000000E+00 +-.34814000000000E+00 +-.14760000000000E-02 +0.21579000000000E+00 +0.38661000000000E+00 +-.11529000000000E+02 +-.10380000000000E+02 +-.92334000000000E+01 +-.80884000000000E+01 +-.69468000000000E+01 +-.58109000000000E+01 +-.46863000000000E+01 +-.35847000000000E+01 +-.25337000000000E+01 +-.15891000000000E+01 +-.82578000000000E+00 +-.28304000000000E+00 +0.69019000000000E-01 +0.30759000000000E+00 +-.12411000000000E+02 +-.11263000000000E+02 +-.10115000000000E+02 +-.89690000000000E+01 +-.78251000000000E+01 +-.66853000000000E+01 +-.55530000000000E+01 +-.44340000000000E+01 +-.33422000000000E+01 +-.23102000000000E+01 +-.13966000000000E+01 +-.66763000000000E+00 +-.14880000000000E+00 +0.20345000000000E+00 +-.13180000000000E+02 +-.12031000000000E+02 +-.10883000000000E+02 +-.97358000000000E+01 +-.85903000000000E+01 +-.74480000000000E+01 +-.63113000000000E+01 +-.51833000000000E+01 +-.40719000000000E+01 +-.29963000000000E+01 +-.19956000000000E+01 +-.11288000000000E+01 +-.44931000000000E+00 +0.37568000000000E-01 +-.13860000000000E+02 +-.12711000000000E+02 +-.11562000000000E+02 +-.10415000000000E+02 +-.92678000000000E+01 +-.81238000000000E+01 +-.69840000000000E+01 +-.58507000000000E+01 +-.47284000000000E+01 +-.36292000000000E+01 +-.25801000000000E+01 +-.16258000000000E+01 +-.81906000000000E+00 +-.19768000000000E+00 +-.14471000000000E+02 +-.13322000000000E+02 +-.12173000000000E+02 +-.11025000000000E+02 +-.98770000000000E+01 +-.87314000000000E+01 +-.75897000000000E+01 +-.64526000000000E+01 +-.53232000000000E+01 +-.42101000000000E+01 +-.31329000000000E+01 +-.21257000000000E+01 +-.12350000000000E+01 +-.50610000000000E+00 +-.15046000000000E+02 +-.13897000000000E+02 +-.12748000000000E+02 +-.11599000000000E+02 +-.10450000000000E+02 +-.93035000000000E+01 +-.81602000000000E+01 +-.70206000000000E+01 +-.58866000000000E+01 +-.47646000000000E+01 +-.36707000000000E+01 +-.26330000000000E+01 +-.16885000000000E+01 +-.87895000000000E+00 +-.15603000000000E+02 +-.14454000000000E+02 +-.13304000000000E+02 +-.12155000000000E+02 +-.11006000000000E+02 +-.98584000000000E+01 +-.87136000000000E+01 +-.75721000000000E+01 +-.64347000000000E+01 +-.53065000000000E+01 +-.42004000000000E+01 +-.31412000000000E+01 +-.21623000000000E+01 +-.13007000000000E+01 +-.16151000000000E+02 +-.15002000000000E+02 +-.13852000000000E+02 +-.12702000000000E+02 +-.11553000000000E+02 +-.10405000000000E+02 +-.92590000000000E+01 +-.81157000000000E+01 +-.69755000000000E+01 +-.58424000000000E+01 +-.47274000000000E+01 +-.36520000000000E+01 +-.26485000000000E+01 +-.17529000000000E+01 +-.16699000000000E+02 +-.15550000000000E+02 +-.14400000000000E+02 +-.13250000000000E+02 +-.12100000000000E+02 +-.10951000000000E+02 +-.98047000000000E+01 +-.86599000000000E+01 +-.75175000000000E+01 +-.63806000000000E+01 +-.52584000000000E+01 +-.41696000000000E+01 +-.31450000000000E+01 +-.22224000000000E+01 +-.17240000000000E+02 +-.16090000000000E+02 +-.14940000000000E+02 +-.13790000000000E+02 +-.12640000000000E+02 +-.11490000000000E+02 +-.10343000000000E+02 +-.91968000000000E+01 +-.80525000000000E+01 +-.69125000000000E+01 +-.57842000000000E+01 +-.46833000000000E+01 +-.36384000000000E+01 +-.26880000000000E+01 +-.17766000000000E+02 +-.16616000000000E+02 +-.15466000000000E+02 +-.14315000000000E+02 +-.13165000000000E+02 +-.12015000000000E+02 +-.10867000000000E+02 +-.97197000000000E+01 +-.85737000000000E+01 +-.74313000000000E+01 +-.62979000000000E+01 +-.51862000000000E+01 +-.41207000000000E+01 +-.31403000000000E+01 +-.18237000000000E+02 +-.17086000000000E+02 +-.15936000000000E+02 +-.14785000000000E+02 +-.13635000000000E+02 +-.12485000000000E+02 +-.11336000000000E+02 +-.10188000000000E+02 +-.90408000000000E+01 +-.78961000000000E+01 +-.67583000000000E+01 +-.56372000000000E+01 +-.45526000000000E+01 +-.35400000000000E+01 +-.18420000000000E+02 +-.17481000000000E+02 +-.16331000000000E+02 +-.15180000000000E+02 +-.14029000000000E+02 +-.12879000000000E+02 +-.11729000000000E+02 +-.10581000000000E+02 +-.94326000000000E+01 +-.82861000000000E+01 +-.71450000000000E+01 +-.60162000000000E+01 +-.49156000000000E+01 +-.38738000000000E+01 +-.18420000000000E+02 +-.17823000000000E+02 +-.16672000000000E+02 +-.15521000000000E+02 +-.14371000000000E+02 +-.13220000000000E+02 +-.12070000000000E+02 +-.10921000000000E+02 +-.97720000000000E+01 +-.86243000000000E+01 +-.74803000000000E+01 +-.63457000000000E+01 +-.52323000000000E+01 +-.41653000000000E+01 +-.18420000000000E+02 +-.18101000000000E+02 +-.16950000000000E+02 +-.15799000000000E+02 +-.14648000000000E+02 +-.13498000000000E+02 +-.12347000000000E+02 +-.11198000000000E+02 +-.10048000000000E+02 +-.88992000000000E+01 +-.77535000000000E+01 +-.66145000000000E+01 +-.54915000000000E+01 +-.44052000000000E+01 +-.40186000000000E+01 +-.40183000000000E+01 +-.40181000000000E+01 +-.40179000000000E+01 +-.40179000000000E+01 +-.40178000000000E+01 +-.40178000000000E+01 +-.40178000000000E+01 +-.40178000000000E+01 +-.40167000000000E+01 +-.40079000000000E+01 +-.39761000000000E+01 +-.38806000000000E+01 +-.36572000000000E+01 +-.40194000000000E+01 +-.40189000000000E+01 +-.40186000000000E+01 +-.40182000000000E+01 +-.40179000000000E+01 +-.40178000000000E+01 +-.40178000000000E+01 +-.40178000000000E+01 +-.40177000000000E+01 +-.40167000000000E+01 +-.40081000000000E+01 +-.39764000000000E+01 +-.38810000000000E+01 +-.36583000000000E+01 +-.40216000000000E+01 +-.40204000000000E+01 +-.40195000000000E+01 +-.40189000000000E+01 +-.40184000000000E+01 +-.40181000000000E+01 +-.40178000000000E+01 +-.40177000000000E+01 +-.40176000000000E+01 +-.40167000000000E+01 +-.40083000000000E+01 +-.39767000000000E+01 +-.38814000000000E+01 +-.36591000000000E+01 +-.40258000000000E+01 +-.40236000000000E+01 +-.40219000000000E+01 +-.40205000000000E+01 +-.40194000000000E+01 +-.40187000000000E+01 +-.40181000000000E+01 +-.40178000000000E+01 +-.40176000000000E+01 +-.40166000000000E+01 +-.40090000000000E+01 +-.39771000000000E+01 +-.38818000000000E+01 +-.36598000000000E+01 +-.40331000000000E+01 +-.40293000000000E+01 +-.40261000000000E+01 +-.40236000000000E+01 +-.40216000000000E+01 +-.40200000000000E+01 +-.40189000000000E+01 +-.40181000000000E+01 +-.40176000000000E+01 +-.40165000000000E+01 +-.40099000000000E+01 +-.39789000000000E+01 +-.38823000000000E+01 +-.36604000000000E+01 +-.40564000000000E+01 +-.40433000000000E+01 +-.40350000000000E+01 +-.40295000000000E+01 +-.40256000000000E+01 +-.40228000000000E+01 +-.40206000000000E+01 +-.40190000000000E+01 +-.40178000000000E+01 +-.40165000000000E+01 +-.40106000000000E+01 +-.39816000000000E+01 +-.38879000000000E+01 +-.36635000000000E+01 +-.41145000000000E+01 +-.40878000000000E+01 +-.40645000000000E+01 +-.40470000000000E+01 +-.40358000000000E+01 +-.40288000000000E+01 +-.40243000000000E+01 +-.40211000000000E+01 +-.40187000000000E+01 +-.40166000000000E+01 +-.40111000000000E+01 +-.39839000000000E+01 +-.38934000000000E+01 +-.36761000000000E+01 +-.41625000000000E+01 +-.41453000000000E+01 +-.41196000000000E+01 +-.40908000000000E+01 +-.40652000000000E+01 +-.40461000000000E+01 +-.40339000000000E+01 +-.40262000000000E+01 +-.40212000000000E+01 +-.40175000000000E+01 +-.40116000000000E+01 +-.39874000000000E+01 +-.38984000000000E+01 +-.36863000000000E+01 +-.41741000000000E+01 +-.41702000000000E+01 +-.41608000000000E+01 +-.41417000000000E+01 +-.41139000000000E+01 +-.40839000000000E+01 +-.40582000000000E+01 +-.40402000000000E+01 +-.40283000000000E+01 +-.40205000000000E+01 +-.40127000000000E+01 +-.39907000000000E+01 +-.39031000000000E+01 +-.36950000000000E+01 +-.41976000000000E+01 +-.41821000000000E+01 +-.41750000000000E+01 +-.41676000000000E+01 +-.41534000000000E+01 +-.41290000000000E+01 +-.40980000000000E+01 +-.40681000000000E+01 +-.40447000000000E+01 +-.40284000000000E+01 +-.40157000000000E+01 +-.39938000000000E+01 +-.39124000000000E+01 +-.37025000000000E+01 +-.45905000000000E+01 +-.43621000000000E+01 +-.42478000000000E+01 +-.41992000000000E+01 +-.41779000000000E+01 +-.41611000000000E+01 +-.41375000000000E+01 +-.41057000000000E+01 +-.40725000000000E+01 +-.40446000000000E+01 +-.40231000000000E+01 +-.39977000000000E+01 +-.39232000000000E+01 +-.37205000000000E+01 +-.61213000000000E+01 +-.53523000000000E+01 +-.48141000000000E+01 +-.44808000000000E+01 +-.43014000000000E+01 +-.42178000000000E+01 +-.41766000000000E+01 +-.41443000000000E+01 +-.41079000000000E+01 +-.40702000000000E+01 +-.40370000000000E+01 +-.40042000000000E+01 +-.39330000000000E+01 +-.37440000000000E+01 +-.84075000000000E+01 +-.73159000000000E+01 +-.63142000000000E+01 +-.54860000000000E+01 +-.48905000000000E+01 +-.45184000000000E+01 +-.43160000000000E+01 +-.42153000000000E+01 +-.41562000000000E+01 +-.41067000000000E+01 +-.40603000000000E+01 +-.40156000000000E+01 +-.39429000000000E+01 +-.37647000000000E+01 +-.10477000000000E+02 +-.93389000000000E+01 +-.82168000000000E+01 +-.71365000000000E+01 +-.61550000000000E+01 +-.53575000000000E+01 +-.47986000000000E+01 +-.44601000000000E+01 +-.42770000000000E+01 +-.41743000000000E+01 +-.41006000000000E+01 +-.40366000000000E+01 +-.39552000000000E+01 +-.37837000000000E+01 +-.12203000000000E+02 +-.11058000000000E+02 +-.99180000000000E+01 +-.87886000000000E+01 +-.76851000000000E+01 +-.66447000000000E+01 +-.57394000000000E+01 +-.50496000000000E+01 +-.45986000000000E+01 +-.43368000000000E+01 +-.41841000000000E+01 +-.40774000000000E+01 +-.39745000000000E+01 +-.38025000000000E+01 +-.13638000000000E+02 +-.12492000000000E+02 +-.11348000000000E+02 +-.10208000000000E+02 +-.90776000000000E+01 +-.79684000000000E+01 +-.69088000000000E+01 +-.59587000000000E+01 +-.52010000000000E+01 +-.46799000000000E+01 +-.43595000000000E+01 +-.41609000000000E+01 +-.40104000000000E+01 +-.38247000000000E+01 +-.14838000000000E+02 +-.13691000000000E+02 +-.12545000000000E+02 +-.11402000000000E+02 +-.10263000000000E+02 +-.91345000000000E+01 +-.80264000000000E+01 +-.69647000000000E+01 +-.60045000000000E+01 +-.52251000000000E+01 +-.46733000000000E+01 +-.43180000000000E+01 +-.40817000000000E+01 +-.38647000000000E+01 +-.15846000000000E+02 +-.14698000000000E+02 +-.13551000000000E+02 +-.12406000000000E+02 +-.11264000000000E+02 +-.10128000000000E+02 +-.90024000000000E+01 +-.78994000000000E+01 +-.68455000000000E+01 +-.58960000000000E+01 +-.51257000000000E+01 +-.45730000000000E+01 +-.42020000000000E+01 +-.39202000000000E+01 +-.16698000000000E+02 +-.15549000000000E+02 +-.14402000000000E+02 +-.13255000000000E+02 +-.12111000000000E+02 +-.10971000000000E+02 +-.98379000000000E+01 +-.87173000000000E+01 +-.76228000000000E+01 +-.65848000000000E+01 +-.56617000000000E+01 +-.49210000000000E+01 +-.43859000000000E+01 +-.40023000000000E+01 +-.17422000000000E+02 +-.16273000000000E+02 +-.15125000000000E+02 +-.13978000000000E+02 +-.12832000000000E+02 +-.11689000000000E+02 +-.10552000000000E+02 +-.94229000000000E+01 +-.83086000000000E+01 +-.72268000000000E+01 +-.62142000000000E+01 +-.53311000000000E+01 +-.46332000000000E+01 +-.41215000000000E+01 +-.18043000000000E+02 +-.16895000000000E+02 +-.15746000000000E+02 +-.14598000000000E+02 +-.13451000000000E+02 +-.12307000000000E+02 +-.11166000000000E+02 +-.10032000000000E+02 +-.89070000000000E+01 +-.78019000000000E+01 +-.67394000000000E+01 +-.57627000000000E+01 +-.49298000000000E+01 +-.42823000000000E+01 +-.18420000000000E+02 +-.17433000000000E+02 +-.16284000000000E+02 +-.15135000000000E+02 +-.13988000000000E+02 +-.12842000000000E+02 +-.11699000000000E+02 +-.10562000000000E+02 +-.94302000000000E+01 +-.83113000000000E+01 +-.72203000000000E+01 +-.61858000000000E+01 +-.52583000000000E+01 +-.44960000000000E+01 +-.18420000000000E+02 +-.17922000000000E+02 +-.16773000000000E+02 +-.15624000000000E+02 +-.14475000000000E+02 +-.13329000000000E+02 +-.12185000000000E+02 +-.11045000000000E+02 +-.99089000000000E+01 +-.87822000000000E+01 +-.76753000000000E+01 +-.66080000000000E+01 +-.56145000000000E+01 +-.47531000000000E+01 +-.18420000000000E+02 +-.18332000000000E+02 +-.17183000000000E+02 +-.16033000000000E+02 +-.14884000000000E+02 +-.13737000000000E+02 +-.12592000000000E+02 +-.11449000000000E+02 +-.10310000000000E+02 +-.91772000000000E+01 +-.80581000000000E+01 +-.69664000000000E+01 +-.59249000000000E+01 +-.49799000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.17550000000000E+02 +-.16400000000000E+02 +-.15251000000000E+02 +-.14103000000000E+02 +-.12956000000000E+02 +-.11812000000000E+02 +-.10670000000000E+02 +-.95332000000000E+01 +-.84058000000000E+01 +-.72979000000000E+01 +-.62241000000000E+01 +-.52192000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.17887000000000E+02 +-.16737000000000E+02 +-.15588000000000E+02 +-.14439000000000E+02 +-.13292000000000E+02 +-.12146000000000E+02 +-.11002000000000E+02 +-.98616000000000E+01 +-.87283000000000E+01 +-.76091000000000E+01 +-.65137000000000E+01 +-.54668000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18198000000000E+02 +-.17047000000000E+02 +-.15897000000000E+02 +-.14748000000000E+02 +-.13600000000000E+02 +-.12453000000000E+02 +-.11308000000000E+02 +-.10165000000000E+02 +-.90269000000000E+01 +-.78995000000000E+01 +-.67888000000000E+01 +-.57122000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17348000000000E+02 +-.16197000000000E+02 +-.15047000000000E+02 +-.13899000000000E+02 +-.12751000000000E+02 +-.11604000000000E+02 +-.10459000000000E+02 +-.93184000000000E+01 +-.81851000000000E+01 +-.70638000000000E+01 +-.59672000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17658000000000E+02 +-.16507000000000E+02 +-.15357000000000E+02 +-.14208000000000E+02 +-.13060000000000E+02 +-.11912000000000E+02 +-.10765000000000E+02 +-.96216000000000E+01 +-.84839000000000E+01 +-.73551000000000E+01 +-.62438000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17963000000000E+02 +-.16812000000000E+02 +-.15662000000000E+02 +-.14512000000000E+02 +-.13363000000000E+02 +-.12214000000000E+02 +-.11067000000000E+02 +-.99211000000000E+01 +-.87800000000000E+01 +-.76453000000000E+01 +-.65233000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18263000000000E+02 +-.17112000000000E+02 +-.15962000000000E+02 +-.14812000000000E+02 +-.13662000000000E+02 +-.12513000000000E+02 +-.11364000000000E+02 +-.10217000000000E+02 +-.90735000000000E+01 +-.79343000000000E+01 +-.68046000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17396000000000E+02 +-.16246000000000E+02 +-.15096000000000E+02 +-.13946000000000E+02 +-.12796000000000E+02 +-.11646000000000E+02 +-.10498000000000E+02 +-.93525000000000E+01 +-.82102000000000E+01 +-.70748000000000E+01 +0.82329000000000E+01 +0.87043000000000E+01 +0.92195000000000E+01 +0.96541000000000E+01 +0.10005000000000E+02 +0.10270000000000E+02 +0.10765000000000E+02 +0.10758000000000E+02 +0.10689000000000E+02 +0.11055000000000E+02 +0.11007000000000E+02 +0.10821000000000E+02 +0.11082000000000E+02 +0.11279000000000E+02 +0.66826000000000E+01 +0.78170000000000E+01 +0.87141000000000E+01 +0.93245000000000E+01 +0.96741000000000E+01 +0.10336000000000E+02 +0.10487000000000E+02 +0.10640000000000E+02 +0.10575000000000E+02 +0.10909000000000E+02 +0.10795000000000E+02 +0.10344000000000E+02 +0.10548000000000E+02 +0.10746000000000E+02 +0.52362000000000E+01 +0.64882000000000E+01 +0.76407000000000E+01 +0.92632000000000E+01 +0.99565000000000E+01 +0.10311000000000E+02 +0.10487000000000E+02 +0.10481000000000E+02 +0.10424000000000E+02 +0.10664000000000E+02 +0.10579000000000E+02 +0.99722000000000E+01 +0.10046000000000E+02 +0.10245000000000E+02 +0.41210000000000E+01 +0.54879000000000E+01 +0.72882000000000E+01 +0.85361000000000E+01 +0.94561000000000E+01 +0.99036000000000E+01 +0.10066000000000E+02 +0.10151000000000E+02 +0.10186000000000E+02 +0.10248000000000E+02 +0.10251000000000E+02 +0.96946000000000E+01 +0.95940000000000E+01 +0.97944000000000E+01 +0.34642000000000E+01 +0.47583000000000E+01 +0.65629000000000E+01 +0.78373000000000E+01 +0.88437000000000E+01 +0.93237000000000E+01 +0.95044000000000E+01 +0.95864000000000E+01 +0.96929000000000E+01 +0.97434000000000E+01 +0.98667000000000E+01 +0.94714000000000E+01 +0.92539000000000E+01 +0.94526000000000E+01 +0.30063000000000E+01 +0.40173000000000E+01 +0.51245000000000E+01 +0.72290000000000E+01 +0.81855000000000E+01 +0.87114000000000E+01 +0.89307000000000E+01 +0.90645000000000E+01 +0.91626000000000E+01 +0.92793000000000E+01 +0.95369000000000E+01 +0.92830000000000E+01 +0.90691000000000E+01 +0.92581000000000E+01 +0.26851000000000E+01 +0.35490000000000E+01 +0.43531000000000E+01 +0.55338000000000E+01 +0.75139000000000E+01 +0.81111000000000E+01 +0.84177000000000E+01 +0.86448000000000E+01 +0.87756000000000E+01 +0.89189000000000E+01 +0.92959000000000E+01 +0.91399000000000E+01 +0.89927000000000E+01 +0.91807000000000E+01 +0.21815000000000E+01 +0.32075000000000E+01 +0.41332000000000E+01 +0.52516000000000E+01 +0.67535000000000E+01 +0.75798000000000E+01 +0.80203000000000E+01 +0.82095000000000E+01 +0.84607000000000E+01 +0.85862000000000E+01 +0.90825000000000E+01 +0.90093000000000E+01 +0.89231000000000E+01 +0.91035000000000E+01 +0.12991000000000E+01 +0.24301000000000E+01 +0.35012000000000E+01 +0.45605000000000E+01 +0.56564000000000E+01 +0.67939000000000E+01 +0.76942000000000E+01 +0.81008000000000E+01 +0.83513000000000E+01 +0.83418000000000E+01 +0.88096000000000E+01 +0.87979000000000E+01 +0.87581000000000E+01 +0.89197000000000E+01 +0.42925000000000E+00 +0.15630000000000E+01 +0.26584000000000E+01 +0.37344000000000E+01 +0.48999000000000E+01 +0.59419000000000E+01 +0.70800000000000E+01 +0.76445000000000E+01 +0.79888000000000E+01 +0.82700000000000E+01 +0.84314000000000E+01 +0.84690000000000E+01 +0.84829000000000E+01 +0.86387000000000E+01 +-.30112000000000E+00 +0.73473000000000E+00 +0.17763000000000E+01 +0.28346000000000E+01 +0.39980000000000E+01 +0.50258000000000E+01 +0.60614000000000E+01 +0.69226000000000E+01 +0.74181000000000E+01 +0.77620000000000E+01 +0.79506000000000E+01 +0.80557000000000E+01 +0.81165000000000E+01 +0.82751000000000E+01 +-.11226000000000E+01 +-.14875000000000E+00 +0.84157000000000E+00 +0.18615000000000E+01 +0.29200000000000E+01 +0.40087000000000E+01 +0.50328000000000E+01 +0.60092000000000E+01 +0.66674000000000E+01 +0.71527000000000E+01 +0.74584000000000E+01 +0.76055000000000E+01 +0.77194000000000E+01 +0.78477000000000E+01 +-.19361000000000E+01 +-.10086000000000E+01 +-.79460000000000E-01 +0.89919000000000E+00 +0.19504000000000E+01 +0.30367000000000E+01 +0.40624000000000E+01 +0.50704000000000E+01 +0.58945000000000E+01 +0.65437000000000E+01 +0.69250000000000E+01 +0.71807000000000E+01 +0.73331000000000E+01 +0.74045000000000E+01 +-.24026000000000E+01 +-.16372000000000E+01 +-.82088000000000E+00 +0.12525000000000E+00 +0.11253000000000E+01 +0.22187000000000E+01 +0.32313000000000E+01 +0.43894000000000E+01 +0.54366000000000E+01 +0.61824000000000E+01 +0.64276000000000E+01 +0.67382000000000E+01 +0.69163000000000E+01 +0.69559000000000E+01 +-.29465000000000E+01 +-.21157000000000E+01 +-.13071000000000E+01 +-.46732000000000E+00 +0.45943000000000E+00 +0.15499000000000E+01 +0.26572000000000E+01 +0.37187000000000E+01 +0.48026000000000E+01 +0.56556000000000E+01 +0.60747000000000E+01 +0.62185000000000E+01 +0.63879000000000E+01 +0.64564000000000E+01 +-.38555000000000E+01 +-.29258000000000E+01 +-.20057000000000E+01 +-.10961000000000E+01 +-.15789000000000E+00 +0.91310000000000E+00 +0.19555000000000E+01 +0.30310000000000E+01 +0.40465000000000E+01 +0.49298000000000E+01 +0.53860000000000E+01 +0.56758000000000E+01 +0.57816000000000E+01 +0.58937000000000E+01 +-.49185000000000E+01 +-.39440000000000E+01 +-.29794000000000E+01 +-.20240000000000E+01 +-.10702000000000E+01 +-.50948000000000E-01 +0.97464000000000E+00 +0.20372000000000E+01 +0.30319000000000E+01 +0.39266000000000E+01 +0.45249000000000E+01 +0.49178000000000E+01 +0.51606000000000E+01 +0.52972000000000E+01 +-.60229000000000E+01 +-.49969000000000E+01 +-.40061000000000E+01 +-.30337000000000E+01 +-.20833000000000E+01 +-.11284000000000E+01 +-.17668000000000E+00 +0.81978000000000E+00 +0.18228000000000E+01 +0.27594000000000E+01 +0.35471000000000E+01 +0.41100000000000E+01 +0.44824000000000E+01 +0.47301000000000E+01 +-.70945000000000E+01 +-.60250000000000E+01 +-.49990000000000E+01 +-.40057000000000E+01 +-.30416000000000E+01 +-.21024000000000E+01 +-.12000000000000E+01 +-.27810000000000E+00 +0.67944000000000E+00 +0.16447000000000E+01 +0.25411000000000E+01 +0.32739000000000E+01 +0.38038000000000E+01 +0.41638000000000E+01 +-.80811000000000E+01 +-.69879000000000E+01 +-.59296000000000E+01 +-.49097000000000E+01 +-.39234000000000E+01 +-.29680000000000E+01 +-.20686000000000E+01 +-.11858000000000E+01 +-.28475000000000E+00 +0.65102000000000E+00 +0.15817000000000E+01 +0.24277000000000E+01 +0.31080000000000E+01 +0.35983000000000E+01 +-.89685000000000E+01 +-.78638000000000E+01 +-.67845000000000E+01 +-.57390000000000E+01 +-.47296000000000E+01 +-.37510000000000E+01 +-.28295000000000E+01 +-.19494000000000E+01 +-.10813000000000E+01 +-.19281000000000E+00 +0.71519000000000E+00 +0.16023000000000E+01 +0.23899000000000E+01 +0.30096000000000E+01 +-.97573000000000E+01 +-.86472000000000E+01 +-.75579000000000E+01 +-.64951000000000E+01 +-.54648000000000E+01 +-.44652000000000E+01 +-.35161000000000E+01 +-.26177000000000E+01 +-.17565000000000E+01 +-.90205000000000E+00 +-.35990000000000E-01 +0.83925000000000E+00 +0.16766000000000E+01 +0.23940000000000E+01 +-.10460000000000E+02 +-.93469000000000E+01 +-.82532000000000E+01 +-.71818000000000E+01 +-.61370000000000E+01 +-.51207000000000E+01 +-.41479000000000E+01 +-.32250000000000E+01 +-.23530000000000E+01 +-.15125000000000E+01 +-.68199000000000E+00 +0.15747000000000E+00 +0.99585000000000E+00 +0.17694000000000E+01 +-.11098000000000E+02 +-.99827000000000E+01 +-.88850000000000E+01 +-.78081000000000E+01 +-.67533000000000E+01 +-.57234000000000E+01 +-.47314000000000E+01 +-.37847000000000E+01 +-.28928000000000E+01 +-.20494000000000E+01 +-.12389000000000E+01 +-.43640000000000E+00 +0.37075000000000E+00 +0.11468000000000E+01 +-.11688000000000E+02 +-.10569000000000E+02 +-.94668000000000E+01 +-.83848000000000E+01 +-.73229000000000E+01 +-.62820000000000E+01 +-.52747000000000E+01 +-.43080000000000E+01 +-.33951000000000E+01 +-.25404000000000E+01 +-.17386000000000E+01 +-.96930000000000E+00 +-.21325000000000E+00 +0.51578000000000E+00 +-.12255000000000E+02 +-.11132000000000E+02 +-.10025000000000E+02 +-.89375000000000E+01 +-.78696000000000E+01 +-.68202000000000E+01 +-.58004000000000E+01 +-.48177000000000E+01 +-.38856000000000E+01 +-.30170000000000E+01 +-.22178000000000E+01 +-.14782000000000E+01 +-.78171000000000E+00 +-.12880000000000E+00 +-.12831000000000E+02 +-.11704000000000E+02 +-.10592000000000E+02 +-.94985000000000E+01 +-.84255000000000E+01 +-.73710000000000E+01 +-.63422000000000E+01 +-.53464000000000E+01 +-.43970000000000E+01 +-.35135000000000E+01 +-.27136000000000E+01 +-.19986000000000E+01 +-.13572000000000E+01 +-.77962000000000E+00 +-.13448000000000E+02 +-.12317000000000E+02 +-.11199000000000E+02 +-.10100000000000E+02 +-.90212000000000E+01 +-.79628000000000E+01 +-.69277000000000E+01 +-.59218000000000E+01 +-.49572000000000E+01 +-.40575000000000E+01 +-.32505000000000E+01 +-.25492000000000E+01 +-.19460000000000E+01 +-.14222000000000E+01 +-.14118000000000E+02 +-.12984000000000E+02 +-.11861000000000E+02 +-.10755000000000E+02 +-.96699000000000E+01 +-.86060000000000E+01 +-.75648000000000E+01 +-.65494000000000E+01 +-.55708000000000E+01 +-.46521000000000E+01 +-.38281000000000E+01 +-.31230000000000E+01 +-.25344000000000E+01 +-.20356000000000E+01 +-.14826000000000E+02 +-.13689000000000E+02 +-.12562000000000E+02 +-.11449000000000E+02 +-.10357000000000E+02 +-.92859000000000E+01 +-.82383000000000E+01 +-.72159000000000E+01 +-.62263000000000E+01 +-.52897000000000E+01 +-.44427000000000E+01 +-.37186000000000E+01 +-.31222000000000E+01 +-.26234000000000E+01 +-.15560000000000E+02 +-.14420000000000E+02 +-.13289000000000E+02 +-.12170000000000E+02 +-.11070000000000E+02 +-.99907000000000E+01 +-.89355000000000E+01 +-.79062000000000E+01 +-.69071000000000E+01 +-.59535000000000E+01 +-.50807000000000E+01 +-.43273000000000E+01 +-.37073000000000E+01 +-.31941000000000E+01 +-.16293000000000E+02 +-.15152000000000E+02 +-.14018000000000E+02 +-.12895000000000E+02 +-.11789000000000E+02 +-.10704000000000E+02 +-.96411000000000E+01 +-.86038000000000E+01 +-.75948000000000E+01 +-.66252000000000E+01 +-.57266000000000E+01 +-.49399000000000E+01 +-.42864000000000E+01 +-.37451000000000E+01 +-.29072000000000E+01 +-.20347000000000E+01 +-.11202000000000E+01 +-.12801000000000E+00 +0.93143000000000E+00 +0.20077000000000E+01 +0.30574000000000E+01 +0.40895000000000E+01 +0.51267000000000E+01 +0.60991000000000E+01 +0.68149000000000E+01 +0.71099000000000E+01 +0.71511000000000E+01 +0.71549000000000E+01 +-.32521000000000E+01 +-.23516000000000E+01 +-.14212000000000E+01 +-.42259000000000E+00 +0.64189000000000E+00 +0.17303000000000E+01 +0.28046000000000E+01 +0.38673000000000E+01 +0.49319000000000E+01 +0.59431000000000E+01 +0.67446000000000E+01 +0.71486000000000E+01 +0.72275000000000E+01 +0.72328000000000E+01 +-.35447000000000E+01 +-.26163000000000E+01 +-.16688000000000E+01 +-.66312000000000E+00 +0.40535000000000E+00 +0.15024000000000E+01 +0.25942000000000E+01 +0.36791000000000E+01 +0.47650000000000E+01 +0.58085000000000E+01 +0.66848000000000E+01 +0.72041000000000E+01 +0.73445000000000E+01 +0.73550000000000E+01 +-.38065000000000E+01 +-.28528000000000E+01 +-.18898000000000E+01 +-.87854000000000E+00 +0.19193000000000E+00 +0.12945000000000E+01 +0.23984000000000E+01 +0.34993000000000E+01 +0.46012000000000E+01 +0.56708000000000E+01 +0.66102000000000E+01 +0.72429000000000E+01 +0.74694000000000E+01 +0.74938000000000E+01 +-.40503000000000E+01 +-.30746000000000E+01 +-.20982000000000E+01 +-.10830000000000E+01 +-.12383000000000E-01 +0.10933000000000E+01 +0.22059000000000E+01 +0.33186000000000E+01 +0.44327000000000E+01 +0.55229000000000E+01 +0.65135000000000E+01 +0.72505000000000E+01 +0.75833000000000E+01 +0.76372000000000E+01 +-.42435000000000E+01 +-.32499000000000E+01 +-.22612000000000E+01 +-.12414000000000E+01 +-.16985000000000E+00 +0.93851000000000E+00 +0.20582000000000E+01 +0.31803000000000E+01 +0.43042000000000E+01 +0.54104000000000E+01 +0.64418000000000E+01 +0.72699000000000E+01 +0.77211000000000E+01 +0.78265000000000E+01 +-.44117000000000E+01 +-.34033000000000E+01 +-.24042000000000E+01 +-.13803000000000E+01 +-.30833000000000E+00 +0.80171000000000E+00 +0.19265000000000E+01 +0.30557000000000E+01 +0.41869000000000E+01 +0.53052000000000E+01 +0.63680000000000E+01 +0.72726000000000E+01 +0.78442000000000E+01 +0.80269000000000E+01 +-.46074000000000E+01 +-.35856000000000E+01 +-.25778000000000E+01 +-.15522000000000E+01 +-.48252000000000E+00 +0.62672000000000E+00 +0.17541000000000E+01 +0.28878000000000E+01 +0.40239000000000E+01 +0.51512000000000E+01 +0.62379000000000E+01 +0.72039000000000E+01 +0.78896000000000E+01 +0.81726000000000E+01 +-.48269000000000E+01 +-.37930000000000E+01 +-.27772000000000E+01 +-.17510000000000E+01 +-.68555000000000E+00 +0.42085000000000E+00 +0.15489000000000E+01 +0.26854000000000E+01 +0.38250000000000E+01 +0.49587000000000E+01 +0.60631000000000E+01 +0.70771000000000E+01 +0.78644000000000E+01 +0.82637000000000E+01 +-.50671000000000E+01 +-.40217000000000E+01 +-.29982000000000E+01 +-.19717000000000E+01 +-.91171000000000E+00 +0.19001000000000E+00 +0.13171000000000E+01 +0.24550000000000E+01 +0.35970000000000E+01 +0.47354000000000E+01 +0.58527000000000E+01 +0.69034000000000E+01 +0.77764000000000E+01 +0.82986000000000E+01 +-.53250000000000E+01 +-.42689000000000E+01 +-.32374000000000E+01 +-.22101000000000E+01 +-.11561000000000E+01 +-.60735000000000E-01 +0.10640000000000E+01 +0.22021000000000E+01 +0.33455000000000E+01 +0.44872000000000E+01 +0.56140000000000E+01 +0.66923000000000E+01 +0.76345000000000E+01 +0.82761000000000E+01 +-.55978000000000E+01 +-.45317000000000E+01 +-.34919000000000E+01 +-.24627000000000E+01 +-.14147000000000E+01 +-.32702000000000E+00 +0.79376000000000E+00 +0.19312000000000E+01 +0.30753000000000E+01 +0.42191000000000E+01 +0.53528000000000E+01 +0.64514000000000E+01 +0.74480000000000E+01 +0.81980000000000E+01 +-.58832000000000E+01 +-.48076000000000E+01 +-.37592000000000E+01 +-.27269000000000E+01 +-.16841000000000E+01 +-.60512000000000E+00 +0.51016000000000E+00 +0.16458000000000E+01 +0.27900000000000E+01 +0.39353000000000E+01 +0.50739000000000E+01 +0.61873000000000E+01 +0.72253000000000E+01 +0.80681000000000E+01 +-.61791000000000E+01 +-.50947000000000E+01 +-.40375000000000E+01 +-.30007000000000E+01 +-.19617000000000E+01 +-.89185000000000E+00 +0.21638000000000E+00 +0.13492000000000E+01 +0.24927000000000E+01 +0.36389000000000E+01 +0.47808000000000E+01 +0.59049000000000E+01 +0.69742000000000E+01 +0.78931000000000E+01 +-.64835000000000E+01 +-.53911000000000E+01 +-.43251000000000E+01 +-.32826000000000E+01 +-.22455000000000E+01 +-.11846000000000E+01 +-.84864000000000E-01 +0.10438000000000E+01 +0.21860000000000E+01 +0.33326000000000E+01 +0.44768000000000E+01 +0.56086000000000E+01 +0.67008000000000E+01 +0.76797000000000E+01 +-.67526000000000E+01 +-.56537000000000E+01 +-.45800000000000E+01 +-.35316000000000E+01 +-.24943000000000E+01 +-.14402000000000E+01 +-.34860000000000E+00 +0.77545000000000E+00 +0.19161000000000E+01 +0.30626000000000E+01 +0.42084000000000E+01 +0.53457000000000E+01 +0.64546000000000E+01 +0.74796000000000E+01 +-.70045000000000E+01 +-.59004000000000E+01 +-.48199000000000E+01 +-.37654000000000E+01 +-.27266000000000E+01 +-.16778000000000E+01 +-.59412000000000E+00 +0.52477000000000E+00 +0.16634000000000E+01 +0.28095000000000E+01 +0.39564000000000E+01 +0.50975000000000E+01 +0.62185000000000E+01 +0.72781000000000E+01 +-.72776000000000E+01 +-.61685000000000E+01 +-.50811000000000E+01 +-.40198000000000E+01 +-.29781000000000E+01 +-.19337000000000E+01 +-.85887000000000E+00 +0.25330000000000E+00 +0.13889000000000E+01 +0.25342000000000E+01 +0.36816000000000E+01 +0.48254000000000E+01 +0.59551000000000E+01 +0.70403000000000E+01 +-.75658000000000E+01 +-.64521000000000E+01 +-.53580000000000E+01 +-.42896000000000E+01 +-.32437000000000E+01 +-.22021000000000E+01 +-.11363000000000E+01 +-.32314000000000E-01 +0.10992000000000E+01 +0.22431000000000E+01 +0.33906000000000E+01 +0.45363000000000E+01 +0.56720000000000E+01 +0.67760000000000E+01 +-.78654000000000E+01 +-.67476000000000E+01 +-.56472000000000E+01 +-.45713000000000E+01 +-.35200000000000E+01 +-.24794000000000E+01 +-.14220000000000E+01 +-.32736000000000E+00 +0.79881000000000E+00 +0.19407000000000E+01 +0.30879000000000E+01 +0.42347000000000E+01 +0.53749000000000E+01 +0.64923000000000E+01 +-.81731000000000E+01 +-.70519000000000E+01 +-.59458000000000E+01 +-.48624000000000E+01 +-.38047000000000E+01 +-.27631000000000E+01 +-.17127000000000E+01 +-.62834000000000E+00 +0.49108000000000E+00 +0.16301000000000E+01 +0.27766000000000E+01 +0.39241000000000E+01 +0.50673000000000E+01 +0.61945000000000E+01 +-.84873000000000E+01 +-.73629000000000E+01 +-.62516000000000E+01 +-.51610000000000E+01 +-.40962000000000E+01 +-.30518000000000E+01 +-.20065000000000E+01 +-.93257000000000E+00 +0.17865000000000E+00 +0.13139000000000E+01 +0.24592000000000E+01 +0.36070000000000E+01 +0.47522000000000E+01 +0.58862000000000E+01 +-.88069000000000E+01 +-.76788000000000E+01 +-.65631000000000E+01 +-.54658000000000E+01 +-.43934000000000E+01 +-.33444000000000E+01 +-.23020000000000E+01 +-.12380000000000E+01 +-.13628000000000E+00 +0.99400000000000E+00 +0.21375000000000E+01 +0.32852000000000E+01 +0.44318000000000E+01 +0.55707000000000E+01 +-.91289000000000E+01 +-.79982000000000E+01 +-.68788000000000E+01 +-.57751000000000E+01 +-.46952000000000E+01 +-.36404000000000E+01 +-.25985000000000E+01 +-.15431000000000E+01 +-.45190000000000E+00 +0.67209000000000E+00 +0.18131000000000E+01 +0.29602000000000E+01 +0.41077000000000E+01 +0.52500000000000E+01 +-.94543000000000E+01 +-.83206000000000E+01 +-.71971000000000E+01 +-.60881000000000E+01 +-.50007000000000E+01 +-.39391000000000E+01 +-.28956000000000E+01 +-.18469000000000E+01 +-.76659000000000E+00 +0.34967000000000E+00 +0.14873000000000E+01 +0.26334000000000E+01 +0.37813000000000E+01 +0.49260000000000E+01 +-.97385000000000E+01 +-.86021000000000E+01 +-.74760000000000E+01 +-.63629000000000E+01 +-.52694000000000E+01 +-.42014000000000E+01 +-.31547000000000E+01 +-.21100000000000E+01 +-.10390000000000E+01 +0.69427000000000E-01 +0.12033000000000E+01 +0.23481000000000E+01 +0.34961000000000E+01 +0.46425000000000E+01 +-.10003000000000E+02 +-.88655000000000E+01 +-.77382000000000E+01 +-.66212000000000E+01 +-.55223000000000E+01 +-.44482000000000E+01 +-.33976000000000E+01 +-.23549000000000E+01 +-.12919000000000E+01 +-.19159000000000E+00 +0.93788000000000E+00 +0.20811000000000E+01 +0.32289000000000E+01 +0.43762000000000E+01 +-.10274000000000E+02 +-.91399000000000E+01 +-.80112000000000E+01 +-.68899000000000E+01 +-.57864000000000E+01 +-.47058000000000E+01 +-.36502000000000E+01 +-.26077000000000E+01 +-.15521000000000E+01 +-.46083000000000E+00 +0.66313000000000E+00 +0.18042000000000E+01 +0.29514000000000E+01 +0.40995000000000E+01 +-.10563000000000E+02 +-.94204000000000E+01 +-.82891000000000E+01 +-.71652000000000E+01 +-.60565000000000E+01 +-.49696000000000E+01 +-.39083000000000E+01 +-.28646000000000E+01 +-.18148000000000E+01 +-.73303000000000E+00 +0.38429000000000E+00 +0.15225000000000E+01 +0.26689000000000E+01 +0.38172000000000E+01 +-.10852000000000E+02 +-.97000000000000E+01 +-.85676000000000E+01 +-.74417000000000E+01 +-.63290000000000E+01 +-.52362000000000E+01 +-.41686000000000E+01 +-.31221000000000E+01 +-.20766000000000E+01 +-.10041000000000E+01 +0.10551000000000E+00 +0.12400000000000E+01 +0.23851000000000E+01 +0.35335000000000E+01 +-.11103000000000E+02 +-.99939000000000E+01 +-.88450000000000E+01 +-.77174000000000E+01 +-.66006000000000E+01 +-.55022000000000E+01 +-.44283000000000E+01 +-.33777000000000E+01 +-.23346000000000E+01 +-.12708000000000E+01 +-.16961000000000E+00 +0.96034000000000E+00 +0.21038000000000E+01 +0.32519000000000E+01 +-.11408000000000E+02 +-.10259000000000E+02 +-.91108000000000E+01 +-.79866000000000E+01 +-.68673000000000E+01 +-.57645000000000E+01 +-.46843000000000E+01 +-.36291000000000E+01 +-.25864000000000E+01 +-.15300000000000E+01 +-.43783000000000E+00 +0.68672000000000E+00 +0.18281000000000E+01 +0.29755000000000E+01 +-.61924000000000E+01 +-.50471000000000E+01 +-.39119000000000E+01 +-.28000000000000E+01 +-.17255000000000E+01 +-.69116000000000E+00 +0.30646000000000E+00 +0.13026000000000E+01 +0.23534000000000E+01 +0.34447000000000E+01 +0.45001000000000E+01 +0.54404000000000E+01 +0.62233000000000E+01 +0.63674000000000E+01 +-.64719000000000E+01 +-.53263000000000E+01 +-.41907000000000E+01 +-.30790000000000E+01 +-.20066000000000E+01 +-.97169000000000E+00 +0.41459000000000E-01 +0.10646000000000E+01 +0.21344000000000E+01 +0.32344000000000E+01 +0.43046000000000E+01 +0.52722000000000E+01 +0.60602000000000E+01 +0.62306000000000E+01 +-.67100000000000E+01 +-.55640000000000E+01 +-.44275000000000E+01 +-.33144000000000E+01 +-.22404000000000E+01 +-.12013000000000E+01 +-.17342000000000E+00 +0.87248000000000E+00 +0.19588000000000E+01 +0.30679000000000E+01 +0.41521000000000E+01 +0.51453000000000E+01 +0.59432000000000E+01 +0.61492000000000E+01 +-.69673000000000E+01 +-.58206000000000E+01 +-.46823000000000E+01 +-.35652000000000E+01 +-.24855000000000E+01 +-.14406000000000E+01 +-.40363000000000E+00 +0.65491000000000E+00 +0.17509000000000E+01 +0.28672000000000E+01 +0.39645000000000E+01 +0.49822000000000E+01 +0.57981000000000E+01 +0.60516000000000E+01 +-.72239000000000E+01 +-.60763000000000E+01 +-.49357000000000E+01 +-.38132000000000E+01 +-.27245000000000E+01 +-.16702000000000E+01 +-.62291000000000E+00 +0.44717000000000E+00 +0.15514000000000E+01 +0.26732000000000E+01 +0.37792000000000E+01 +0.48145000000000E+01 +0.56519000000000E+01 +0.59641000000000E+01 +-.74192000000000E+01 +-.62709000000000E+01 +-.51283000000000E+01 +-.40011000000000E+01 +-.29039000000000E+01 +-.18387000000000E+01 +-.78017000000000E+00 +0.30110000000000E+00 +0.14130000000000E+01 +0.25396000000000E+01 +0.36529000000000E+01 +0.47032000000000E+01 +0.55677000000000E+01 +0.59501000000000E+01 +-.76140000000000E+01 +-.64651000000000E+01 +-.53207000000000E+01 +-.41888000000000E+01 +-.30829000000000E+01 +-.20073000000000E+01 +-.93941000000000E+00 +0.14983000000000E+00 +0.12670000000000E+01 +0.23972000000000E+01 +0.35162000000000E+01 +0.45802000000000E+01 +0.54758000000000E+01 +0.59369000000000E+01 +-.77869000000000E+01 +-.66375000000000E+01 +-.54917000000000E+01 +-.43561000000000E+01 +-.32426000000000E+01 +-.21572000000000E+01 +-.10808000000000E+01 +0.14986000000000E-01 +0.11363000000000E+01 +0.22695000000000E+01 +0.33934000000000E+01 +0.44697000000000E+01 +0.53986000000000E+01 +0.59432000000000E+01 +-.79531000000000E+01 +-.68032000000000E+01 +-.56562000000000E+01 +-.45176000000000E+01 +-.33975000000000E+01 +-.23035000000000E+01 +-.12197000000000E+01 +-.11904000000000E+00 +0.10053000000000E+01 +0.21407000000000E+01 +0.32688000000000E+01 +0.43569000000000E+01 +0.53191000000000E+01 +0.59485000000000E+01 +-.81570000000000E+01 +-.70068000000000E+01 +-.58589000000000E+01 +-.47173000000000E+01 +-.35911000000000E+01 +-.24888000000000E+01 +-.13993000000000E+01 +-.29617000000000E+00 +0.82938000000000E+00 +0.19662000000000E+01 +0.30978000000000E+01 +0.41968000000000E+01 +0.51908000000000E+01 +0.59025000000000E+01 +-.83374000000000E+01 +-.71870000000000E+01 +-.60383000000000E+01 +-.48948000000000E+01 +-.37639000000000E+01 +-.26545000000000E+01 +-.15596000000000E+01 +-.45416000000000E+00 +0.67229000000000E+00 +0.18102000000000E+01 +0.29451000000000E+01 +0.40537000000000E+01 +0.50771000000000E+01 +0.58655000000000E+01 +-.85120000000000E+01 +-.73613000000000E+01 +-.62120000000000E+01 +-.50669000000000E+01 +-.39322000000000E+01 +-.28168000000000E+01 +-.17170000000000E+01 +-.60994000000000E+00 +0.51686000000000E+00 +0.16556000000000E+01 +0.27932000000000E+01 +0.39103000000000E+01 +0.49595000000000E+01 +0.58170000000000E+01 +-.87234000000000E+01 +-.75726000000000E+01 +-.64229000000000E+01 +-.52762000000000E+01 +-.41382000000000E+01 +-.30171000000000E+01 +-.19128000000000E+01 +-.80505000000000E+00 +0.32092000000000E+00 +0.14597000000000E+01 +0.25992000000000E+01 +0.37236000000000E+01 +0.47949000000000E+01 +0.57128000000000E+01 +-.89712000000000E+01 +-.78204000000000E+01 +-.66703000000000E+01 +-.55226000000000E+01 +-.43815000000000E+01 +-.32549000000000E+01 +-.21458000000000E+01 +-.10380000000000E+01 +0.86126000000000E-01 +0.12241000000000E+01 +0.23651000000000E+01 +0.34954000000000E+01 +0.45848000000000E+01 +0.55540000000000E+01 +-.92424000000000E+01 +-.80913000000000E+01 +-.69409000000000E+01 +-.57922000000000E+01 +-.46487000000000E+01 +-.35172000000000E+01 +-.24030000000000E+01 +-.12947000000000E+01 +-.17315000000000E+00 +0.96341000000000E+00 +0.21052000000000E+01 +0.32399000000000E+01 +0.43441000000000E+01 +0.53553000000000E+01 +-.95015000000000E+01 +-.83503000000000E+01 +-.71997000000000E+01 +-.60504000000000E+01 +-.49050000000000E+01 +-.37695000000000E+01 +-.26503000000000E+01 +-.15408000000000E+01 +-.42160000000000E+00 +0.71315000000000E+00 +0.18551000000000E+01 +0.29933000000000E+01 +0.41091000000000E+01 +0.51543000000000E+01 +-.97224000000000E+01 +-.85713000000000E+01 +-.74207000000000E+01 +-.62709000000000E+01 +-.51243000000000E+01 +-.39858000000000E+01 +-.28624000000000E+01 +-.17511000000000E+01 +-.63358000000000E+00 +0.49940000000000E+00 +0.16413000000000E+01 +0.27820000000000E+01 +0.39067000000000E+01 +0.49785000000000E+01 +-.99722000000000E+01 +-.88210000000000E+01 +-.76700000000000E+01 +-.65200000000000E+01 +-.53723000000000E+01 +-.42311000000000E+01 +-.31035000000000E+01 +-.19897000000000E+01 +-.87399000000000E+00 +0.25649000000000E+00 +0.13976000000000E+01 +0.25400000000000E+01 +0.36714000000000E+01 +0.47638000000000E+01 +-.10243000000000E+02 +-.90916000000000E+01 +-.79406000000000E+01 +-.67902000000000E+01 +-.56416000000000E+01 +-.44982000000000E+01 +-.33663000000000E+01 +-.22495000000000E+01 +-.11351000000000E+01 +-.76693000000000E-02 +0.11321000000000E+01 +0.22754000000000E+01 +0.34117000000000E+01 +0.45197000000000E+01 +-.10529000000000E+02 +-.93779000000000E+01 +-.82268000000000E+01 +-.70762000000000E+01 +-.59270000000000E+01 +-.47817000000000E+01 +-.36460000000000E+01 +-.25252000000000E+01 +-.14115000000000E+01 +-.28740000000000E+00 +0.85031000000000E+00 +0.19938000000000E+01 +0.31335000000000E+01 +0.42531000000000E+01 +-.10772000000000E+02 +-.96208000000000E+01 +-.84697000000000E+01 +-.73190000000000E+01 +-.61693000000000E+01 +-.50228000000000E+01 +-.38843000000000E+01 +-.27599000000000E+01 +-.16457000000000E+01 +-.52426000000000E+00 +0.61134000000000E+00 +0.17546000000000E+01 +0.28968000000000E+01 +0.40248000000000E+01 +-.11002000000000E+02 +-.98503000000000E+01 +-.86992000000000E+01 +-.75485000000000E+01 +-.63984000000000E+01 +-.52509000000000E+01 +-.41101000000000E+01 +-.29824000000000E+01 +-.18669000000000E+01 +-.74779000000000E+00 +0.38553000000000E+00 +0.15282000000000E+01 +0.26719000000000E+01 +0.38062000000000E+01 +-.11260000000000E+02 +-.10109000000000E+02 +-.89580000000000E+01 +-.78071000000000E+01 +-.66569000000000E+01 +-.55084000000000E+01 +-.43655000000000E+01 +-.32342000000000E+01 +-.21166000000000E+01 +-.99962000000000E+00 +0.13076000000000E+00 +0.12722000000000E+01 +0.24168000000000E+01 +0.35555000000000E+01 +-.11539000000000E+02 +-.10388000000000E+02 +-.92366000000000E+01 +-.80854000000000E+01 +-.69349000000000E+01 +-.57859000000000E+01 +-.46410000000000E+01 +-.35062000000000E+01 +-.23857000000000E+01 +-.12701000000000E+01 +-.14306000000000E+00 +0.99658000000000E+00 +0.21413000000000E+01 +0.32830000000000E+01 +-.11831000000000E+02 +-.10679000000000E+02 +-.95281000000000E+01 +-.83770000000000E+01 +-.72263000000000E+01 +-.60768000000000E+01 +-.49304000000000E+01 +-.37923000000000E+01 +-.26682000000000E+01 +-.15529000000000E+01 +-.42944000000000E+00 +0.70772000000000E+00 +0.18521000000000E+01 +0.29957000000000E+01 +-.12125000000000E+02 +-.10974000000000E+02 +-.98230000000000E+01 +-.86716000000000E+01 +-.75209000000000E+01 +-.63708000000000E+01 +-.52233000000000E+01 +-.40823000000000E+01 +-.29543000000000E+01 +-.18381000000000E+01 +-.71794000000000E+00 +0.41619000000000E+00 +0.15595000000000E+01 +0.27043000000000E+01 +-.12425000000000E+02 +-.11273000000000E+02 +-.10122000000000E+02 +-.89707000000000E+01 +-.78198000000000E+01 +-.66696000000000E+01 +-.55210000000000E+01 +-.43778000000000E+01 +-.32458000000000E+01 +-.21275000000000E+01 +-.10099000000000E+01 +0.12071000000000E+00 +0.12625000000000E+01 +0.24078000000000E+01 +-.12725000000000E+02 +-.11574000000000E+02 +-.10423000000000E+02 +-.92715000000000E+01 +-.81206000000000E+01 +-.69700000000000E+01 +-.58208000000000E+01 +-.46757000000000E+01 +-.35400000000000E+01 +-.24186000000000E+01 +-.13026000000000E+01 +-.17573000000000E+00 +0.96393000000000E+00 +0.21091000000000E+01 +-.13026000000000E+02 +-.11874000000000E+02 +-.10723000000000E+02 +-.95715000000000E+01 +-.84204000000000E+01 +-.72697000000000E+01 +-.61200000000000E+01 +-.49733000000000E+01 +-.38345000000000E+01 +-.27095000000000E+01 +-.15938000000000E+01 +-.47057000000000E+00 +0.66641000000000E+00 +0.18110000000000E+01 +-.13322000000000E+02 +-.12171000000000E+02 +-.11020000000000E+02 +-.98684000000000E+01 +-.87173000000000E+01 +-.75664000000000E+01 +-.64163000000000E+01 +-.52686000000000E+01 +-.41271000000000E+01 +-.29982000000000E+01 +-.18815000000000E+01 +-.76146000000000E+00 +0.37238000000000E+00 +0.15158000000000E+01 +-.13564000000000E+02 +-.12414000000000E+02 +-.11263000000000E+02 +-.10112000000000E+02 +-.89607000000000E+01 +-.78097000000000E+01 +-.66593000000000E+01 +-.55107000000000E+01 +-.43674000000000E+01 +-.32355000000000E+01 +-.21171000000000E+01 +-.99915000000000E+00 +0.13184000000000E+00 +0.12740000000000E+01 +-.13784000000000E+02 +-.12631000000000E+02 +-.11481000000000E+02 +-.10330000000000E+02 +-.91785000000000E+01 +-.80273000000000E+01 +-.68768000000000E+01 +-.57279000000000E+01 +-.45831000000000E+01 +-.34485000000000E+01 +-.23280000000000E+01 +-.12114000000000E+01 +-.83080000000000E-01 +0.10576000000000E+01 +-.82029000000000E+01 +-.70536000000000E+01 +-.59064000000000E+01 +-.47657000000000E+01 +-.36433000000000E+01 +-.25628000000000E+01 +-.15447000000000E+01 +-.54933000000000E+00 +0.49557000000000E+00 +0.15835000000000E+01 +0.26383000000000E+01 +0.35798000000000E+01 +0.44077000000000E+01 +0.51547000000000E+01 +-.84236000000000E+01 +-.72737000000000E+01 +-.61256000000000E+01 +-.49830000000000E+01 +-.38558000000000E+01 +-.27639000000000E+01 +-.17242000000000E+01 +-.70389000000000E+00 +0.35498000000000E+00 +0.14481000000000E+01 +0.25162000000000E+01 +0.34862000000000E+01 +0.43348000000000E+01 +0.50778000000000E+01 +-.86360000000000E+01 +-.74860000000000E+01 +-.63374000000000E+01 +-.51935000000000E+01 +-.40631000000000E+01 +-.29641000000000E+01 +-.19119000000000E+01 +-.87926000000000E+00 +0.18444000000000E+00 +0.12798000000000E+01 +0.23597000000000E+01 +0.33578000000000E+01 +0.42325000000000E+01 +0.49725000000000E+01 +-.88914000000000E+01 +-.77411000000000E+01 +-.65922000000000E+01 +-.54476000000000E+01 +-.43156000000000E+01 +-.32131000000000E+01 +-.21569000000000E+01 +-.11242000000000E+01 +-.65369000000000E-01 +0.10282000000000E+01 +0.21185000000000E+01 +0.31452000000000E+01 +0.40519000000000E+01 +0.47925000000000E+01 +-.91619000000000E+01 +-.80112000000000E+01 +-.68622000000000E+01 +-.57168000000000E+01 +-.45825000000000E+01 +-.34757000000000E+01 +-.24133000000000E+01 +-.13785000000000E+01 +-.32364000000000E+00 +0.76729000000000E+00 +0.18642000000000E+01 +0.29130000000000E+01 +0.38503000000000E+01 +0.45944000000000E+01 +-.93948000000000E+01 +-.82441000000000E+01 +-.70947000000000E+01 +-.59486000000000E+01 +-.48123000000000E+01 +-.37006000000000E+01 +-.26307000000000E+01 +-.15905000000000E+01 +-.53540000000000E+00 +0.55573000000000E+00 +0.16592000000000E+01 +0.27272000000000E+01 +0.36940000000000E+01 +0.44480000000000E+01 +-.96184000000000E+01 +-.84675000000000E+01 +-.73177000000000E+01 +-.61709000000000E+01 +-.50323000000000E+01 +-.39153000000000E+01 +-.28362000000000E+01 +-.17878000000000E+01 +-.72923000000000E+00 +0.36356000000000E+00 +0.14727000000000E+01 +0.25563000000000E+01 +0.35491000000000E+01 +0.43204000000000E+01 +-.98276000000000E+01 +-.86768000000000E+01 +-.75269000000000E+01 +-.63790000000000E+01 +-.52383000000000E+01 +-.41157000000000E+01 +-.30266000000000E+01 +-.19679000000000E+01 +-.90395000000000E+00 +0.19125000000000E+00 +0.13048000000000E+01 +0.24003000000000E+01 +0.34153000000000E+01 +0.42114000000000E+01 +-.99805000000000E+01 +-.88296000000000E+01 +-.76792000000000E+01 +-.65308000000000E+01 +-.53882000000000E+01 +-.42606000000000E+01 +-.31624000000000E+01 +-.20930000000000E+01 +-.10219000000000E+01 +0.77063000000000E-01 +0.11947000000000E+01 +0.22993000000000E+01 +0.33333000000000E+01 +0.41606000000000E+01 +-.10143000000000E+02 +-.89924000000000E+01 +-.78419000000000E+01 +-.66929000000000E+01 +-.55486000000000E+01 +-.44165000000000E+01 +-.33094000000000E+01 +-.22296000000000E+01 +-.11520000000000E+01 +-.50359000000000E-01 +0.10700000000000E+01 +0.21813000000000E+01 +0.32317000000000E+01 +0.40950000000000E+01 +-.10283000000000E+02 +-.91323000000000E+01 +-.79817000000000E+01 +-.68323000000000E+01 +-.56865000000000E+01 +-.45508000000000E+01 +-.34362000000000E+01 +-.23470000000000E+01 +-.12632000000000E+01 +-.15881000000000E+00 +0.96378000000000E+00 +0.20806000000000E+01 +0.31458000000000E+01 +0.40470000000000E+01 +-.10425000000000E+02 +-.92737000000000E+01 +-.81228000000000E+01 +-.69731000000000E+01 +-.58262000000000E+01 +-.46874000000000E+01 +-.35663000000000E+01 +-.24689000000000E+01 +-.13795000000000E+01 +-.27307000000000E+00 +0.85115000000000E+00 +0.19725000000000E+01 +0.30512000000000E+01 +0.39904000000000E+01 +-.10618000000000E+02 +-.94668000000000E+01 +-.83159000000000E+01 +-.71658000000000E+01 +-.60178000000000E+01 +-.48762000000000E+01 +-.37491000000000E+01 +-.26436000000000E+01 +-.15494000000000E+01 +-.44250000000000E+00 +0.68207000000000E+00 +0.18070000000000E+01 +0.28978000000000E+01 +0.38729000000000E+01 +-.10798000000000E+02 +-.96467000000000E+01 +-.84956000000000E+01 +-.73453000000000E+01 +-.61965000000000E+01 +-.50529000000000E+01 +-.39210000000000E+01 +-.28086000000000E+01 +-.17098000000000E+01 +-.60228000000000E+00 +0.52246000000000E+00 +0.16504000000000E+01 +0.27520000000000E+01 +0.37599000000000E+01 +-.10974000000000E+02 +-.98223000000000E+01 +-.86711000000000E+01 +-.75206000000000E+01 +-.63713000000000E+01 +-.52261000000000E+01 +-.40903000000000E+01 +-.29721000000000E+01 +-.18690000000000E+01 +-.76088000000000E+00 +0.36372000000000E+00 +0.14940000000000E+01 +0.26051000000000E+01 +0.36418000000000E+01 +-.11186000000000E+02 +-.10034000000000E+02 +-.88833000000000E+01 +-.77327000000000E+01 +-.65829000000000E+01 +-.54362000000000E+01 +-.42971000000000E+01 +-.31733000000000E+01 +-.20658000000000E+01 +-.95760000000000E+00 +0.16595000000000E+00 +0.12977000000000E+01 +0.24165000000000E+01 +0.34777000000000E+01 +-.11426000000000E+02 +-.10274000000000E+02 +-.91233000000000E+01 +-.79725000000000E+01 +-.68224000000000E+01 +-.56744000000000E+01 +-.45327000000000E+01 +-.34038000000000E+01 +-.22916000000000E+01 +-.11832000000000E+01 +-.61433000000000E-01 +0.10708000000000E+01 +0.21957000000000E+01 +0.32771000000000E+01 +-.11687000000000E+02 +-.10536000000000E+02 +-.93848000000000E+01 +-.82339000000000E+01 +-.70835000000000E+01 +-.59348000000000E+01 +-.47906000000000E+01 +-.36572000000000E+01 +-.25400000000000E+01 +-.14309000000000E+01 +-.31148000000000E+00 +0.82030000000000E+00 +0.19496000000000E+01 +0.30472000000000E+01 +-.11937000000000E+02 +-.10786000000000E+02 +-.96343000000000E+01 +-.84832000000000E+01 +-.73326000000000E+01 +-.61832000000000E+01 +-.50375000000000E+01 +-.39005000000000E+01 +-.27786000000000E+01 +-.16680000000000E+01 +-.55058000000000E+00 +0.58017000000000E+00 +0.17126000000000E+01 +0.28229000000000E+01 +-.12148000000000E+02 +-.10997000000000E+02 +-.98455000000000E+01 +-.86943000000000E+01 +-.75435000000000E+01 +-.63937000000000E+01 +-.52468000000000E+01 +-.41071000000000E+01 +-.29814000000000E+01 +-.18688000000000E+01 +-.75278000000000E+00 +0.37684000000000E+00 +0.15114000000000E+01 +0.26313000000000E+01 +-.12391000000000E+02 +-.11240000000000E+02 +-.10089000000000E+02 +-.89375000000000E+01 +-.77865000000000E+01 +-.66365000000000E+01 +-.54885000000000E+01 +-.43464000000000E+01 +-.32167000000000E+01 +-.21015000000000E+01 +-.98689000000000E+00 +0.14072000000000E+00 +0.12762000000000E+01 +0.24032000000000E+01 +-.12657000000000E+02 +-.11506000000000E+02 +-.10354000000000E+02 +-.92034000000000E+01 +-.80522000000000E+01 +-.69020000000000E+01 +-.57532000000000E+01 +-.46091000000000E+01 +-.34755000000000E+01 +-.23570000000000E+01 +-.12433000000000E+01 +-.11834000000000E+00 +0.10170000000000E+01 +0.21489000000000E+01 +-.12939000000000E+02 +-.11788000000000E+02 +-.10637000000000E+02 +-.94856000000000E+01 +-.83345000000000E+01 +-.71840000000000E+01 +-.60345000000000E+01 +-.48888000000000E+01 +-.37516000000000E+01 +-.26292000000000E+01 +-.15156000000000E+01 +-.39360000000000E+00 +0.74051000000000E+00 +0.18755000000000E+01 +-.13179000000000E+02 +-.12027000000000E+02 +-.10876000000000E+02 +-.97249000000000E+01 +-.85737000000000E+01 +-.74230000000000E+01 +-.62732000000000E+01 +-.51261000000000E+01 +-.39865000000000E+01 +-.28605000000000E+01 +-.17460000000000E+01 +-.62634000000000E+00 +0.50629000000000E+00 +0.16433000000000E+01 +-.13403000000000E+02 +-.12252000000000E+02 +-.11101000000000E+02 +-.99495000000000E+01 +-.87983000000000E+01 +-.76475000000000E+01 +-.64973000000000E+01 +-.53495000000000E+01 +-.42078000000000E+01 +-.30786000000000E+01 +-.19626000000000E+01 +-.84476000000000E+00 +0.28606000000000E+00 +0.14240000000000E+01 +-.13651000000000E+02 +-.12500000000000E+02 +-.11348000000000E+02 +-.10197000000000E+02 +-.90459000000000E+01 +-.78950000000000E+01 +-.67446000000000E+01 +-.55959000000000E+01 +-.44523000000000E+01 +-.33198000000000E+01 +-.22015000000000E+01 +-.10853000000000E+01 +0.42988000000000E-01 +0.11808000000000E+01 +-.13916000000000E+02 +-.12764000000000E+02 +-.11613000000000E+02 +-.10462000000000E+02 +-.93105000000000E+01 +-.81594000000000E+01 +-.70089000000000E+01 +-.58597000000000E+01 +-.47145000000000E+01 +-.35787000000000E+01 +-.24573000000000E+01 +-.13421000000000E+01 +-.21678000000000E+00 +0.92009000000000E+00 +-.14190000000000E+02 +-.13039000000000E+02 +-.11888000000000E+02 +-.10737000000000E+02 +-.95854000000000E+01 +-.84343000000000E+01 +-.72837000000000E+01 +-.61340000000000E+01 +-.49873000000000E+01 +-.38486000000000E+01 +-.27238000000000E+01 +-.16085000000000E+01 +-.48627000000000E+00 +0.64879000000000E+00 +-.14471000000000E+02 +-.13320000000000E+02 +-.12168000000000E+02 +-.11017000000000E+02 +-.98660000000000E+01 +-.87148000000000E+01 +-.75640000000000E+01 +-.64138000000000E+01 +-.52661000000000E+01 +-.41248000000000E+01 +-.29962000000000E+01 +-.18798000000000E+01 +-.76041000000000E+00 +0.37215000000000E+00 +-.14752000000000E+02 +-.13601000000000E+02 +-.12450000000000E+02 +-.11299000000000E+02 +-.10148000000000E+02 +-.89966000000000E+01 +-.78456000000000E+01 +-.66952000000000E+01 +-.55466000000000E+01 +-.44031000000000E+01 +-.32708000000000E+01 +-.21524000000000E+01 +-.10352000000000E+01 +0.94345000000000E-01 +-.15033000000000E+02 +-.13882000000000E+02 +-.12730000000000E+02 +-.11579000000000E+02 +-.10427000000000E+02 +-.92764000000000E+01 +-.81252000000000E+01 +-.69747000000000E+01 +-.58254000000000E+01 +-.46803000000000E+01 +-.35446000000000E+01 +-.24233000000000E+01 +-.13074000000000E+01 +-.18110000000000E+00 +-.15308000000000E+02 +-.14156000000000E+02 +-.13005000000000E+02 +-.11854000000000E+02 +-.10702000000000E+02 +-.95510000000000E+01 +-.83999000000000E+01 +-.72493000000000E+01 +-.60996000000000E+01 +-.49530000000000E+01 +-.38145000000000E+01 +-.26897000000000E+01 +-.15741000000000E+01 +-.45098000000000E+00 +-.10414000000000E+02 +-.92642000000000E+01 +-.81165000000000E+01 +-.69749000000000E+01 +-.58490000000000E+01 +-.47616000000000E+01 +-.37348000000000E+01 +-.27335000000000E+01 +-.16865000000000E+01 +-.59869000000000E+00 +0.45624000000000E+00 +0.13984000000000E+01 +0.22266000000000E+01 +0.30090000000000E+01 +-.10560000000000E+02 +-.94104000000000E+01 +-.82617000000000E+01 +-.71172000000000E+01 +-.59845000000000E+01 +-.48800000000000E+01 +-.38198000000000E+01 +-.27782000000000E+01 +-.17065000000000E+01 +-.60986000000000E+00 +0.45847000000000E+00 +0.14286000000000E+01 +0.22773000000000E+01 +0.30653000000000E+01 +-.10715000000000E+02 +-.95642000000000E+01 +-.84148000000000E+01 +-.72684000000000E+01 +-.61309000000000E+01 +-.50145000000000E+01 +-.39312000000000E+01 +-.28626000000000E+01 +-.17752000000000E+01 +-.67287000000000E+00 +0.40708000000000E+00 +0.14047000000000E+01 +0.22795000000000E+01 +0.30765000000000E+01 +-.10908000000000E+02 +-.97578000000000E+01 +-.86079000000000E+01 +-.74607000000000E+01 +-.63203000000000E+01 +-.51970000000000E+01 +-.41007000000000E+01 +-.30180000000000E+01 +-.19239000000000E+01 +-.82022000000000E+00 +0.26868000000000E+00 +0.12937000000000E+01 +0.22010000000000E+01 +0.30125000000000E+01 +-.11115000000000E+02 +-.99644000000000E+01 +-.88142000000000E+01 +-.76660000000000E+01 +-.65231000000000E+01 +-.53936000000000E+01 +-.42854000000000E+01 +-.31901000000000E+01 +-.20917000000000E+01 +-.99100000000000E+00 +0.99827000000000E-01 +0.11438000000000E+01 +0.20825000000000E+01 +0.29126000000000E+01 +-.11325000000000E+02 +-.10174000000000E+02 +-.90239000000000E+01 +-.78749000000000E+01 +-.67301000000000E+01 +-.55959000000000E+01 +-.44790000000000E+01 +-.33749000000000E+01 +-.22747000000000E+01 +-.11793000000000E+01 +-.89882000000000E-01 +0.96890000000000E+00 +0.19391000000000E+01 +0.27932000000000E+01 +-.11518000000000E+02 +-.10367000000000E+02 +-.92163000000000E+01 +-.80667000000000E+01 +-.69205000000000E+01 +-.57826000000000E+01 +-.46587000000000E+01 +-.35477000000000E+01 +-.24464000000000E+01 +-.13556000000000E+01 +-.26827000000000E+00 +0.80241000000000E+00 +0.18026000000000E+01 +0.26849000000000E+01 +-.11699000000000E+02 +-.10549000000000E+02 +-.93977000000000E+01 +-.82478000000000E+01 +-.71005000000000E+01 +-.59596000000000E+01 +-.48303000000000E+01 +-.37136000000000E+01 +-.26104000000000E+01 +-.15218000000000E+01 +-.43504000000000E+00 +0.64574000000000E+00 +0.16730000000000E+01 +0.25853000000000E+01 +-.11857000000000E+02 +-.10706000000000E+02 +-.95554000000000E+01 +-.84050000000000E+01 +-.72570000000000E+01 +-.61138000000000E+01 +-.49802000000000E+01 +-.38584000000000E+01 +-.27521000000000E+01 +-.16628000000000E+01 +-.57455000000000E+00 +0.51509000000000E+00 +0.15655000000000E+01 +0.25068000000000E+01 +-.12008000000000E+02 +-.10857000000000E+02 +-.97058000000000E+01 +-.85554000000000E+01 +-.74065000000000E+01 +-.62616000000000E+01 +-.51244000000000E+01 +-.39980000000000E+01 +-.28876000000000E+01 +-.17952000000000E+01 +-.70409000000000E+00 +0.39275000000000E+00 +0.14613000000000E+01 +0.24291000000000E+01 +-.12147000000000E+02 +-.10996000000000E+02 +-.98447000000000E+01 +-.86941000000000E+01 +-.75447000000000E+01 +-.63983000000000E+01 +-.52583000000000E+01 +-.41276000000000E+01 +-.30125000000000E+01 +-.19157000000000E+01 +-.82101000000000E+00 +0.28150000000000E+00 +0.13639000000000E+01 +0.23550000000000E+01 +-.12256000000000E+02 +-.11105000000000E+02 +-.99536000000000E+01 +-.88030000000000E+01 +-.76531000000000E+01 +-.65055000000000E+01 +-.53630000000000E+01 +-.42288000000000E+01 +-.31091000000000E+01 +-.20075000000000E+01 +-.90887000000000E+00 +0.19846000000000E+00 +0.12913000000000E+01 +0.23035000000000E+01 +-.12394000000000E+02 +-.11242000000000E+02 +-.10091000000000E+02 +-.89402000000000E+01 +-.77899000000000E+01 +-.66416000000000E+01 +-.54971000000000E+01 +-.43596000000000E+01 +-.32352000000000E+01 +-.21283000000000E+01 +-.10261000000000E+01 +0.84482000000000E-01 +0.11852000000000E+01 +0.22162000000000E+01 +-.12505000000000E+02 +-.11354000000000E+02 +-.10203000000000E+02 +-.90518000000000E+01 +-.79014000000000E+01 +-.67523000000000E+01 +-.56064000000000E+01 +-.44663000000000E+01 +-.33380000000000E+01 +-.22263000000000E+01 +-.11205000000000E+01 +-.68880000000000E-02 +0.11003000000000E+01 +0.21490000000000E+01 +-.12667000000000E+02 +-.11515000000000E+02 +-.10364000000000E+02 +-.92131000000000E+01 +-.80625000000000E+01 +-.69128000000000E+01 +-.57657000000000E+01 +-.46233000000000E+01 +-.34909000000000E+01 +-.23742000000000E+01 +-.12654000000000E+01 +-.14996000000000E+00 +0.96233000000000E+00 +0.20270000000000E+01 +-.12867000000000E+02 +-.11716000000000E+02 +-.10565000000000E+02 +-.94138000000000E+01 +-.82629000000000E+01 +-.71130000000000E+01 +-.59648000000000E+01 +-.48204000000000E+01 +-.36843000000000E+01 +-.25626000000000E+01 +-.14507000000000E+01 +-.33439000000000E+00 +0.78180000000000E+00 +0.18609000000000E+01 +-.13014000000000E+02 +-.11863000000000E+02 +-.10711000000000E+02 +-.95603000000000E+01 +-.84094000000000E+01 +-.72590000000000E+01 +-.61102000000000E+01 +-.49644000000000E+01 +-.38256000000000E+01 +-.27000000000000E+01 +-.15853000000000E+01 +-.46742000000000E+00 +0.65251000000000E+00 +0.17445000000000E+01 +-.13188000000000E+02 +-.12037000000000E+02 +-.10885000000000E+02 +-.97344000000000E+01 +-.85833000000000E+01 +-.74329000000000E+01 +-.62834000000000E+01 +-.51364000000000E+01 +-.39952000000000E+01 +-.28661000000000E+01 +-.17485000000000E+01 +-.62968000000000E+00 +0.49300000000000E+00 +0.15958000000000E+01 +-.13400000000000E+02 +-.12249000000000E+02 +-.11098000000000E+02 +-.99465000000000E+01 +-.87954000000000E+01 +-.76447000000000E+01 +-.64948000000000E+01 +-.53467000000000E+01 +-.42035000000000E+01 +-.30707000000000E+01 +-.19502000000000E+01 +-.83083000000000E+00 +0.29348000000000E+00 +0.14051000000000E+01 +-.13640000000000E+02 +-.12489000000000E+02 +-.11338000000000E+02 +-.10187000000000E+02 +-.90354000000000E+01 +-.78846000000000E+01 +-.67344000000000E+01 +-.55856000000000E+01 +-.44406000000000E+01 +-.33044000000000E+01 +-.21807000000000E+01 +-.10608000000000E+01 +0.64133000000000E-01 +0.11823000000000E+01 +-.13902000000000E+02 +-.12751000000000E+02 +-.11599000000000E+02 +-.10448000000000E+02 +-.92971000000000E+01 +-.81460000000000E+01 +-.69956000000000E+01 +-.58462000000000E+01 +-.46996000000000E+01 +-.35604000000000E+01 +-.24332000000000E+01 +-.13126000000000E+01 +-.18777000000000E+00 +0.93517000000000E+00 +-.14123000000000E+02 +-.12972000000000E+02 +-.11821000000000E+02 +-.10669000000000E+02 +-.95181000000000E+01 +-.83672000000000E+01 +-.72164000000000E+01 +-.60665000000000E+01 +-.49191000000000E+01 +-.37776000000000E+01 +-.26474000000000E+01 +-.15256000000000E+01 +-.40082000000000E+00 +0.72552000000000E+00 +-.14339000000000E+02 +-.13188000000000E+02 +-.12037000000000E+02 +-.10885000000000E+02 +-.97339000000000E+01 +-.85828000000000E+01 +-.74321000000000E+01 +-.62819000000000E+01 +-.51335000000000E+01 +-.39904000000000E+01 +-.28574000000000E+01 +-.17341000000000E+01 +-.60954000000000E+00 +0.51897000000000E+00 +-.14585000000000E+02 +-.13434000000000E+02 +-.12282000000000E+02 +-.11131000000000E+02 +-.99797000000000E+01 +-.88286000000000E+01 +-.76777000000000E+01 +-.65273000000000E+01 +-.53783000000000E+01 +-.42335000000000E+01 +-.30977000000000E+01 +-.19724000000000E+01 +-.84834000000000E+00 +0.28098000000000E+00 +-.14850000000000E+02 +-.13698000000000E+02 +-.12547000000000E+02 +-.11396000000000E+02 +-.10245000000000E+02 +-.90935000000000E+01 +-.79425000000000E+01 +-.67919000000000E+01 +-.56423000000000E+01 +-.44960000000000E+01 +-.33574000000000E+01 +-.22298000000000E+01 +-.11061000000000E+01 +0.23029000000000E-01 +-.15125000000000E+02 +-.13973000000000E+02 +-.12822000000000E+02 +-.11671000000000E+02 +-.10520000000000E+02 +-.93684000000000E+01 +-.82173000000000E+01 +-.70665000000000E+01 +-.59166000000000E+01 +-.47692000000000E+01 +-.36281000000000E+01 +-.24977000000000E+01 +-.13738000000000E+01 +-.24556000000000E+00 +-.15328000000000E+02 +-.14177000000000E+02 +-.13025000000000E+02 +-.11874000000000E+02 +-.10723000000000E+02 +-.95715000000000E+01 +-.84204000000000E+01 +-.72697000000000E+01 +-.61194000000000E+01 +-.49713000000000E+01 +-.38286000000000E+01 +-.26960000000000E+01 +-.15715000000000E+01 +-.44376000000000E+00 +-.15547000000000E+02 +-.14395000000000E+02 +-.13244000000000E+02 +-.12093000000000E+02 +-.10941000000000E+02 +-.97903000000000E+01 +-.86389000000000E+01 +-.74880000000000E+01 +-.63376000000000E+01 +-.51888000000000E+01 +-.40447000000000E+01 +-.29099000000000E+01 +-.17843000000000E+01 +-.65738000000000E+00 +-.15787000000000E+02 +-.14635000000000E+02 +-.13484000000000E+02 +-.12333000000000E+02 +-.11181000000000E+02 +-.10030000000000E+02 +-.88789000000000E+01 +-.77280000000000E+01 +-.65774000000000E+01 +-.54281000000000E+01 +-.42826000000000E+01 +-.31454000000000E+01 +-.20182000000000E+01 +-.89221000000000E+00 +-.16038000000000E+02 +-.14887000000000E+02 +-.13736000000000E+02 +-.12585000000000E+02 +-.11434000000000E+02 +-.10282000000000E+02 +-.91311000000000E+01 +-.79801000000000E+01 +-.68292000000000E+01 +-.56796000000000E+01 +-.45328000000000E+01 +-.33933000000000E+01 +-.22642000000000E+01 +-.11388000000000E+01 +-.16296000000000E+02 +-.15145000000000E+02 +-.13994000000000E+02 +-.12843000000000E+02 +-.11691000000000E+02 +-.10540000000000E+02 +-.93887000000000E+01 +-.82375000000000E+01 +-.70867000000000E+01 +-.59366000000000E+01 +-.47889000000000E+01 +-.36473000000000E+01 +-.25159000000000E+01 +-.13906000000000E+01 +-.16554000000000E+02 +-.15403000000000E+02 +-.14251000000000E+02 +-.13100000000000E+02 +-.11949000000000E+02 +-.10798000000000E+02 +-.96465000000000E+01 +-.84954000000000E+01 +-.73444000000000E+01 +-.61940000000000E+01 +-.50455000000000E+01 +-.39021000000000E+01 +-.27682000000000E+01 +-.16424000000000E+01 +-.12187000000000E+02 +-.11038000000000E+02 +-.98901000000000E+01 +-.87480000000000E+01 +-.76219000000000E+01 +-.65334000000000E+01 +-.55040000000000E+01 +-.44984000000000E+01 +-.34465000000000E+01 +-.23546000000000E+01 +-.12975000000000E+01 +-.35461000000000E+00 +0.47385000000000E+00 +0.12563000000000E+01 +-.12428000000000E+02 +-.11278000000000E+02 +-.10129000000000E+02 +-.89851000000000E+01 +-.78534000000000E+01 +-.67516000000000E+01 +-.56965000000000E+01 +-.46603000000000E+01 +-.35892000000000E+01 +-.24899000000000E+01 +-.14197000000000E+01 +-.44886000000000E+00 +0.40009000000000E+00 +0.11881000000000E+01 +-.12515000000000E+02 +-.11365000000000E+02 +-.10215000000000E+02 +-.90691000000000E+01 +-.79316000000000E+01 +-.68156000000000E+01 +-.57322000000000E+01 +-.46614000000000E+01 +-.35673000000000E+01 +-.24571000000000E+01 +-.13732000000000E+01 +-.37477000000000E+00 +0.50006000000000E+00 +0.12969000000000E+01 +-.12643000000000E+02 +-.11493000000000E+02 +-.10343000000000E+02 +-.91953000000000E+01 +-.80547000000000E+01 +-.69304000000000E+01 +-.58313000000000E+01 +-.47417000000000E+01 +-.36347000000000E+01 +-.25165000000000E+01 +-.14197000000000E+01 +-.39278000000000E+00 +0.51462000000000E+00 +0.13260000000000E+01 +-.12818000000000E+02 +-.11667000000000E+02 +-.10517000000000E+02 +-.93684000000000E+01 +-.82251000000000E+01 +-.70946000000000E+01 +-.59830000000000E+01 +-.48787000000000E+01 +-.37620000000000E+01 +-.26385000000000E+01 +-.15334000000000E+01 +-.48517000000000E+00 +0.45421000000000E+00 +0.12845000000000E+01 +-.12973000000000E+02 +-.11822000000000E+02 +-.10672000000000E+02 +-.95227000000000E+01 +-.83772000000000E+01 +-.72416000000000E+01 +-.61200000000000E+01 +-.50042000000000E+01 +-.38796000000000E+01 +-.27521000000000E+01 +-.16406000000000E+01 +-.57452000000000E+00 +0.39687000000000E+00 +0.12520000000000E+01 +-.13112000000000E+02 +-.11961000000000E+02 +-.10811000000000E+02 +-.96609000000000E+01 +-.85139000000000E+01 +-.73743000000000E+01 +-.62452000000000E+01 +-.51205000000000E+01 +-.39902000000000E+01 +-.28594000000000E+01 +-.17429000000000E+01 +-.66214000000000E+00 +0.33995000000000E+00 +0.12253000000000E+01 +-.13251000000000E+02 +-.12100000000000E+02 +-.10949000000000E+02 +-.97991000000000E+01 +-.86511000000000E+01 +-.75085000000000E+01 +-.63740000000000E+01 +-.52429000000000E+01 +-.41083000000000E+01 +-.29749000000000E+01 +-.18543000000000E+01 +-.76160000000000E+00 +0.26833000000000E+00 +0.11877000000000E+01 +-.13354000000000E+02 +-.12202000000000E+02 +-.11051000000000E+02 +-.99009000000000E+01 +-.87520000000000E+01 +-.76072000000000E+01 +-.64683000000000E+01 +-.53320000000000E+01 +-.41940000000000E+01 +-.30583000000000E+01 +-.19344000000000E+01 +-.83202000000000E+00 +0.22211000000000E+00 +0.11766000000000E+01 +-.13447000000000E+02 +-.12295000000000E+02 +-.11144000000000E+02 +-.99934000000000E+01 +-.88440000000000E+01 +-.76975000000000E+01 +-.65554000000000E+01 +-.54154000000000E+01 +-.42747000000000E+01 +-.31372000000000E+01 +-.20105000000000E+01 +-.90034000000000E+00 +0.17371000000000E+00 +0.11614000000000E+01 +-.13531000000000E+02 +-.12379000000000E+02 +-.11228000000000E+02 +-.10077000000000E+02 +-.89275000000000E+01 +-.77798000000000E+01 +-.66353000000000E+01 +-.54924000000000E+01 +-.43496000000000E+01 +-.32106000000000E+01 +-.20814000000000E+01 +-.96523000000000E+00 +0.12443000000000E+00 +0.11412000000000E+01 +-.13615000000000E+02 +-.12464000000000E+02 +-.11313000000000E+02 +-.10162000000000E+02 +-.90115000000000E+01 +-.78628000000000E+01 +-.67166000000000E+01 +-.55718000000000E+01 +-.44272000000000E+01 +-.32867000000000E+01 +-.21552000000000E+01 +-.10345000000000E+01 +0.66793000000000E-01 +0.11071000000000E+01 +-.13697000000000E+02 +-.12546000000000E+02 +-.11395000000000E+02 +-.10244000000000E+02 +-.90930000000000E+01 +-.79437000000000E+01 +-.67961000000000E+01 +-.56498000000000E+01 +-.45040000000000E+01 +-.33621000000000E+01 +-.22285000000000E+01 +-.11041000000000E+01 +0.56044000000000E-02 +0.10644000000000E+01 +-.13786000000000E+02 +-.12635000000000E+02 +-.11484000000000E+02 +-.10333000000000E+02 +-.91821000000000E+01 +-.80322000000000E+01 +-.68838000000000E+01 +-.57362000000000E+01 +-.45894000000000E+01 +-.34462000000000E+01 +-.23106000000000E+01 +-.11833000000000E+01 +-.67488000000000E-01 +0.10057000000000E+01 +-.13917000000000E+02 +-.12766000000000E+02 +-.11614000000000E+02 +-.10463000000000E+02 +-.93123000000000E+01 +-.81621000000000E+01 +-.70129000000000E+01 +-.58645000000000E+01 +-.47167000000000E+01 +-.35721000000000E+01 +-.24346000000000E+01 +-.13048000000000E+01 +-.18455000000000E+00 +0.90025000000000E+00 +-.14010000000000E+02 +-.12858000000000E+02 +-.11707000000000E+02 +-.10556000000000E+02 +-.94048000000000E+01 +-.82542000000000E+01 +-.71045000000000E+01 +-.59553000000000E+01 +-.48069000000000E+01 +-.36613000000000E+01 +-.25220000000000E+01 +-.13900000000000E+01 +-.26601000000000E+00 +0.82883000000000E+00 +-.14161000000000E+02 +-.13009000000000E+02 +-.11858000000000E+02 +-.10707000000000E+02 +-.95559000000000E+01 +-.84050000000000E+01 +-.72550000000000E+01 +-.61052000000000E+01 +-.49562000000000E+01 +-.38096000000000E+01 +-.26686000000000E+01 +-.15345000000000E+01 +-.40748000000000E+00 +0.69598000000000E+00 +-.14351000000000E+02 +-.13200000000000E+02 +-.12049000000000E+02 +-.10898000000000E+02 +-.97466000000000E+01 +-.85957000000000E+01 +-.74452000000000E+01 +-.62952000000000E+01 +-.51455000000000E+01 +-.39980000000000E+01 +-.28552000000000E+01 +-.17192000000000E+01 +-.58963000000000E+00 +0.52132000000000E+00 +-.14480000000000E+02 +-.13329000000000E+02 +-.12178000000000E+02 +-.11026000000000E+02 +-.98752000000000E+01 +-.87241000000000E+01 +-.75736000000000E+01 +-.64232000000000E+01 +-.52732000000000E+01 +-.41250000000000E+01 +-.29811000000000E+01 +-.18434000000000E+01 +-.71130000000000E+00 +0.40641000000000E+00 +-.14654000000000E+02 +-.13502000000000E+02 +-.12351000000000E+02 +-.11200000000000E+02 +-.10048000000000E+02 +-.88975000000000E+01 +-.77466000000000E+01 +-.65959000000000E+01 +-.54457000000000E+01 +-.42969000000000E+01 +-.31517000000000E+01 +-.20123000000000E+01 +-.87828000000000E+00 +0.24501000000000E+00 +-.14865000000000E+02 +-.13714000000000E+02 +-.12562000000000E+02 +-.11411000000000E+02 +-.10260000000000E+02 +-.91089000000000E+01 +-.79580000000000E+01 +-.68073000000000E+01 +-.56567000000000E+01 +-.45073000000000E+01 +-.33611000000000E+01 +-.22201000000000E+01 +-.10843000000000E+01 +0.43420000000000E-01 +-.15105000000000E+02 +-.13954000000000E+02 +-.12802000000000E+02 +-.11651000000000E+02 +-.10500000000000E+02 +-.93486000000000E+01 +-.81975000000000E+01 +-.70468000000000E+01 +-.58960000000000E+01 +-.47462000000000E+01 +-.35989000000000E+01 +-.24564000000000E+01 +-.13190000000000E+01 +-.18788000000000E+00 +-.15366000000000E+02 +-.14214000000000E+02 +-.13063000000000E+02 +-.11912000000000E+02 +-.10760000000000E+02 +-.96094000000000E+01 +-.84583000000000E+01 +-.73073000000000E+01 +-.61564000000000E+01 +-.50062000000000E+01 +-.38580000000000E+01 +-.27140000000000E+01 +-.15752000000000E+01 +-.44148000000000E+00 +-.15573000000000E+02 +-.14422000000000E+02 +-.13271000000000E+02 +-.12120000000000E+02 +-.10969000000000E+02 +-.98171000000000E+01 +-.86660000000000E+01 +-.75150000000000E+01 +-.63640000000000E+01 +-.52136000000000E+01 +-.40648000000000E+01 +-.29197000000000E+01 +-.17795000000000E+01 +-.64371000000000E+00 +-.15787000000000E+02 +-.14636000000000E+02 +-.13484000000000E+02 +-.12333000000000E+02 +-.11182000000000E+02 +-.10031000000000E+02 +-.88794000000000E+01 +-.77284000000000E+01 +-.65774000000000E+01 +-.54268000000000E+01 +-.42775000000000E+01 +-.31313000000000E+01 +-.19900000000000E+01 +-.85251000000000E+00 +-.16026000000000E+02 +-.14875000000000E+02 +-.13723000000000E+02 +-.12572000000000E+02 +-.11421000000000E+02 +-.10270000000000E+02 +-.91182000000000E+01 +-.79672000000000E+01 +-.68160000000000E+01 +-.56653000000000E+01 +-.45156000000000E+01 +-.33685000000000E+01 +-.22259000000000E+01 +-.10872000000000E+01 +-.16283000000000E+02 +-.15131000000000E+02 +-.13980000000000E+02 +-.12829000000000E+02 +-.11677000000000E+02 +-.10526000000000E+02 +-.93750000000000E+01 +-.82236000000000E+01 +-.70726000000000E+01 +-.59218000000000E+01 +-.47717000000000E+01 +-.36238000000000E+01 +-.24799000000000E+01 +-.13401000000000E+01 +-.16550000000000E+02 +-.15399000000000E+02 +-.14248000000000E+02 +-.13097000000000E+02 +-.11945000000000E+02 +-.10794000000000E+02 +-.96428000000000E+01 +-.84917000000000E+01 +-.73405000000000E+01 +-.61896000000000E+01 +-.50392000000000E+01 +-.38906000000000E+01 +-.27455000000000E+01 +-.16047000000000E+01 +-.16734000000000E+02 +-.15583000000000E+02 +-.14432000000000E+02 +-.13281000000000E+02 +-.12129000000000E+02 +-.10978000000000E+02 +-.98267000000000E+01 +-.86753000000000E+01 +-.75242000000000E+01 +-.63732000000000E+01 +-.52227000000000E+01 +-.40736000000000E+01 +-.29277000000000E+01 +-.17861000000000E+01 +-.16944000000000E+02 +-.15793000000000E+02 +-.14642000000000E+02 +-.13490000000000E+02 +-.12339000000000E+02 +-.11188000000000E+02 +-.10037000000000E+02 +-.88853000000000E+01 +-.77341000000000E+01 +-.65831000000000E+01 +-.54324000000000E+01 +-.42830000000000E+01 +-.31363000000000E+01 +-.19937000000000E+01 +-.17172000000000E+02 +-.16021000000000E+02 +-.14869000000000E+02 +-.13718000000000E+02 +-.12567000000000E+02 +-.11416000000000E+02 +-.10264000000000E+02 +-.91130000000000E+01 +-.79618000000000E+01 +-.68107000000000E+01 +-.56598000000000E+01 +-.45100000000000E+01 +-.33626000000000E+01 +-.22191000000000E+01 +-.17408000000000E+02 +-.16256000000000E+02 +-.15105000000000E+02 +-.13954000000000E+02 +-.12803000000000E+02 +-.11651000000000E+02 +-.10500000000000E+02 +-.93489000000000E+01 +-.81975000000000E+01 +-.70465000000000E+01 +-.58956000000000E+01 +-.47455000000000E+01 +-.35974000000000E+01 +-.24529000000000E+01 +-.13118000000000E+02 +-.11968000000000E+02 +-.10821000000000E+02 +-.96780000000000E+01 +-.85505000000000E+01 +-.74586000000000E+01 +-.64221000000000E+01 +-.54066000000000E+01 +-.43470000000000E+01 +-.32513000000000E+01 +-.21926000000000E+01 +-.12491000000000E+01 +-.42049000000000E+00 +0.36190000000000E+00 +-.13348000000000E+02 +-.12198000000000E+02 +-.11050000000000E+02 +-.99050000000000E+01 +-.87722000000000E+01 +-.76674000000000E+01 +-.66060000000000E+01 +-.55613000000000E+01 +-.44838000000000E+01 +-.33809000000000E+01 +-.23086000000000E+01 +-.13369000000000E+01 +-.48776000000000E+00 +0.30024000000000E+00 +-.13566000000000E+02 +-.12415000000000E+02 +-.11266000000000E+02 +-.10120000000000E+02 +-.89832000000000E+01 +-.78683000000000E+01 +-.67876000000000E+01 +-.57200000000000E+01 +-.46274000000000E+01 +-.35164000000000E+01 +-.24306000000000E+01 +-.14308000000000E+01 +-.55563000000000E+00 +0.24124000000000E+00 +-.13677000000000E+02 +-.12527000000000E+02 +-.11377000000000E+02 +-.10229000000000E+02 +-.90889000000000E+01 +-.79653000000000E+01 +-.68673000000000E+01 +-.57788000000000E+01 +-.46718000000000E+01 +-.35516000000000E+01 +-.24518000000000E+01 +-.14233000000000E+01 +-.51579000000000E+00 +0.29537000000000E+00 +-.13797000000000E+02 +-.12646000000000E+02 +-.11495000000000E+02 +-.10347000000000E+02 +-.92036000000000E+01 +-.80728000000000E+01 +-.69608000000000E+01 +-.58556000000000E+01 +-.47371000000000E+01 +-.36100000000000E+01 +-.25001000000000E+01 +-.14489000000000E+01 +-.50887000000000E+00 +0.32131000000000E+00 +-.13944000000000E+02 +-.12793000000000E+02 +-.11643000000000E+02 +-.10493000000000E+02 +-.93479000000000E+01 +-.82122000000000E+01 +-.70905000000000E+01 +-.59739000000000E+01 +-.48474000000000E+01 +-.37153000000000E+01 +-.25971000000000E+01 +-.15265000000000E+01 +-.55391000000000E+00 +0.30113000000000E+00 +-.14071000000000E+02 +-.12920000000000E+02 +-.11769000000000E+02 +-.10619000000000E+02 +-.94724000000000E+01 +-.83325000000000E+01 +-.72034000000000E+01 +-.60778000000000E+01 +-.49452000000000E+01 +-.38089000000000E+01 +-.26841000000000E+01 +-.15975000000000E+01 +-.59401000000000E+00 +0.29120000000000E+00 +-.14180000000000E+02 +-.13029000000000E+02 +-.11878000000000E+02 +-.10728000000000E+02 +-.95796000000000E+01 +-.84368000000000E+01 +-.73018000000000E+01 +-.61694000000000E+01 +-.50321000000000E+01 +-.38926000000000E+01 +-.27628000000000E+01 +-.16632000000000E+01 +-.63158000000000E+00 +0.28766000000000E+00 +-.14287000000000E+02 +-.13136000000000E+02 +-.11985000000000E+02 +-.10834000000000E+02 +-.96858000000000E+01 +-.85408000000000E+01 +-.74015000000000E+01 +-.62644000000000E+01 +-.51237000000000E+01 +-.39818000000000E+01 +-.28478000000000E+01 +-.17379000000000E+01 +-.68193000000000E+00 +0.27280000000000E+00 +-.14366000000000E+02 +-.13215000000000E+02 +-.12064000000000E+02 +-.10913000000000E+02 +-.97637000000000E+01 +-.86169000000000E+01 +-.74745000000000E+01 +-.63336000000000E+01 +-.51902000000000E+01 +-.40464000000000E+01 +-.29095000000000E+01 +-.17914000000000E+01 +-.71530000000000E+00 +0.27390000000000E+00 +-.14438000000000E+02 +-.13287000000000E+02 +-.12136000000000E+02 +-.10985000000000E+02 +-.98352000000000E+01 +-.86873000000000E+01 +-.75426000000000E+01 +-.63989000000000E+01 +-.52537000000000E+01 +-.41084000000000E+01 +-.29691000000000E+01 +-.18448000000000E+01 +-.75262000000000E+00 +0.26770000000000E+00 +-.14499000000000E+02 +-.13348000000000E+02 +-.12197000000000E+02 +-.11046000000000E+02 +-.98955000000000E+01 +-.87466000000000E+01 +-.76001000000000E+01 +-.64545000000000E+01 +-.53076000000000E+01 +-.41614000000000E+01 +-.30203000000000E+01 +-.18914000000000E+01 +-.78677000000000E+00 +0.25968000000000E+00 +-.14567000000000E+02 +-.13416000000000E+02 +-.12265000000000E+02 +-.11114000000000E+02 +-.99631000000000E+01 +-.88137000000000E+01 +-.76659000000000E+01 +-.65187000000000E+01 +-.53708000000000E+01 +-.42236000000000E+01 +-.30811000000000E+01 +-.19487000000000E+01 +-.83501000000000E+00 +0.23195000000000E+00 +-.14658000000000E+02 +-.13507000000000E+02 +-.12356000000000E+02 +-.11205000000000E+02 +-.10054000000000E+02 +-.89041000000000E+01 +-.77554000000000E+01 +-.66072000000000E+01 +-.54586000000000E+01 +-.43108000000000E+01 +-.31669000000000E+01 +-.20316000000000E+01 +-.91148000000000E+00 +0.17083000000000E+00 +-.14733000000000E+02 +-.13582000000000E+02 +-.12431000000000E+02 +-.11279000000000E+02 +-.10128000000000E+02 +-.89783000000000E+01 +-.78289000000000E+01 +-.66798000000000E+01 +-.55306000000000E+01 +-.43821000000000E+01 +-.32372000000000E+01 +-.20999000000000E+01 +-.97491000000000E+00 +0.11890000000000E+00 +-.14846000000000E+02 +-.13695000000000E+02 +-.12544000000000E+02 +-.11393000000000E+02 +-.10242000000000E+02 +-.90911000000000E+01 +-.79413000000000E+01 +-.67916000000000E+01 +-.56420000000000E+01 +-.44930000000000E+01 +-.33471000000000E+01 +-.22078000000000E+01 +-.10793000000000E+01 +0.23331000000000E-01 +-.14937000000000E+02 +-.13786000000000E+02 +-.12635000000000E+02 +-.11484000000000E+02 +-.10333000000000E+02 +-.91819000000000E+01 +-.80315000000000E+01 +-.68816000000000E+01 +-.57316000000000E+01 +-.45822000000000E+01 +-.34355000000000E+01 +-.22946000000000E+01 +-.11631000000000E+01 +-.53208000000000E-01 +-.15072000000000E+02 +-.13921000000000E+02 +-.12770000000000E+02 +-.11618000000000E+02 +-.10467000000000E+02 +-.93162000000000E+01 +-.81655000000000E+01 +-.70153000000000E+01 +-.58649000000000E+01 +-.47151000000000E+01 +-.35677000000000E+01 +-.24254000000000E+01 +-.12913000000000E+01 +-.17521000000000E+00 +-.15252000000000E+02 +-.14101000000000E+02 +-.12949000000000E+02 +-.11798000000000E+02 +-.10647000000000E+02 +-.94961000000000E+01 +-.83452000000000E+01 +-.71947000000000E+01 +-.60442000000000E+01 +-.48942000000000E+01 +-.37460000000000E+01 +-.26022000000000E+01 +-.14658000000000E+01 +-.34437000000000E+00 +-.15386000000000E+02 +-.14235000000000E+02 +-.13083000000000E+02 +-.11932000000000E+02 +-.10781000000000E+02 +-.96299000000000E+01 +-.84790000000000E+01 +-.73282000000000E+01 +-.61775000000000E+01 +-.50271000000000E+01 +-.38784000000000E+01 +-.27335000000000E+01 +-.15951000000000E+01 +-.46886000000000E+00 +-.15548000000000E+02 +-.14397000000000E+02 +-.13246000000000E+02 +-.12094000000000E+02 +-.10943000000000E+02 +-.97920000000000E+01 +-.86409000000000E+01 +-.74901000000000E+01 +-.63392000000000E+01 +-.51887000000000E+01 +-.40394000000000E+01 +-.28936000000000E+01 +-.17533000000000E+01 +-.62296000000000E+00 +-.15752000000000E+02 +-.14600000000000E+02 +-.13449000000000E+02 +-.12298000000000E+02 +-.11146000000000E+02 +-.99954000000000E+01 +-.88442000000000E+01 +-.76932000000000E+01 +-.65422000000000E+01 +-.53916000000000E+01 +-.42419000000000E+01 +-.30950000000000E+01 +-.19531000000000E+01 +-.81938000000000E+00 +-.15985000000000E+02 +-.14833000000000E+02 +-.13682000000000E+02 +-.12531000000000E+02 +-.11380000000000E+02 +-.10229000000000E+02 +-.90774000000000E+01 +-.79263000000000E+01 +-.67753000000000E+01 +-.56244000000000E+01 +-.44744000000000E+01 +-.33266000000000E+01 +-.21832000000000E+01 +-.10467000000000E+01 +-.16240000000000E+02 +-.15089000000000E+02 +-.13937000000000E+02 +-.12786000000000E+02 +-.11635000000000E+02 +-.10484000000000E+02 +-.93325000000000E+01 +-.81814000000000E+01 +-.70303000000000E+01 +-.58794000000000E+01 +-.47290000000000E+01 +-.35805000000000E+01 +-.24357000000000E+01 +-.12968000000000E+01 +-.16453000000000E+02 +-.15302000000000E+02 +-.14151000000000E+02 +-.13000000000000E+02 +-.11848000000000E+02 +-.10697000000000E+02 +-.95457000000000E+01 +-.83945000000000E+01 +-.72435000000000E+01 +-.60924000000000E+01 +-.49419000000000E+01 +-.37928000000000E+01 +-.26469000000000E+01 +-.15061000000000E+01 +-.16655000000000E+02 +-.15503000000000E+02 +-.14352000000000E+02 +-.13201000000000E+02 +-.12050000000000E+02 +-.10898000000000E+02 +-.97471000000000E+01 +-.85959000000000E+01 +-.74447000000000E+01 +-.62937000000000E+01 +-.51429000000000E+01 +-.39935000000000E+01 +-.28466000000000E+01 +-.17042000000000E+01 +-.16885000000000E+02 +-.15734000000000E+02 +-.14582000000000E+02 +-.13431000000000E+02 +-.12280000000000E+02 +-.11128000000000E+02 +-.99771000000000E+01 +-.88259000000000E+01 +-.76748000000000E+01 +-.65237000000000E+01 +-.53728000000000E+01 +-.42229000000000E+01 +-.30753000000000E+01 +-.19315000000000E+01 +-.17133000000000E+02 +-.15982000000000E+02 +-.14831000000000E+02 +-.13679000000000E+02 +-.12528000000000E+02 +-.11377000000000E+02 +-.10226000000000E+02 +-.90742000000000E+01 +-.79232000000000E+01 +-.67720000000000E+01 +-.56211000000000E+01 +-.44708000000000E+01 +-.33224000000000E+01 +-.21776000000000E+01 +-.17393000000000E+02 +-.16242000000000E+02 +-.15090000000000E+02 +-.13939000000000E+02 +-.12788000000000E+02 +-.11636000000000E+02 +-.10485000000000E+02 +-.93340000000000E+01 +-.81826000000000E+01 +-.70315000000000E+01 +-.58805000000000E+01 +-.47301000000000E+01 +-.35811000000000E+01 +-.24351000000000E+01 +-.17581000000000E+02 +-.16430000000000E+02 +-.15279000000000E+02 +-.14127000000000E+02 +-.12976000000000E+02 +-.11825000000000E+02 +-.10674000000000E+02 +-.95225000000000E+01 +-.83711000000000E+01 +-.72200000000000E+01 +-.60688000000000E+01 +-.49182000000000E+01 +-.37689000000000E+01 +-.26221000000000E+01 +-.17777000000000E+02 +-.16626000000000E+02 +-.15475000000000E+02 +-.14324000000000E+02 +-.13172000000000E+02 +-.12021000000000E+02 +-.10870000000000E+02 +-.97187000000000E+01 +-.85674000000000E+01 +-.74161000000000E+01 +-.62650000000000E+01 +-.51143000000000E+01 +-.39646000000000E+01 +-.28171000000000E+01 +-.17991000000000E+02 +-.16840000000000E+02 +-.15689000000000E+02 +-.14538000000000E+02 +-.13386000000000E+02 +-.12235000000000E+02 +-.11084000000000E+02 +-.99326000000000E+01 +-.87812000000000E+01 +-.76301000000000E+01 +-.64790000000000E+01 +-.53281000000000E+01 +-.41781000000000E+01 +-.30300000000000E+01 +-.13836000000000E+02 +-.12686000000000E+02 +-.11538000000000E+02 +-.10395000000000E+02 +-.92666000000000E+01 +-.81719000000000E+01 +-.71295000000000E+01 +-.61063000000000E+01 +-.50409000000000E+01 +-.39423000000000E+01 +-.28825000000000E+01 +-.19386000000000E+01 +-.11099000000000E+01 +-.32744000000000E+00 +-.14059000000000E+02 +-.12909000000000E+02 +-.11760000000000E+02 +-.10615000000000E+02 +-.94812000000000E+01 +-.83740000000000E+01 +-.73075000000000E+01 +-.62562000000000E+01 +-.51740000000000E+01 +-.40686000000000E+01 +-.29952000000000E+01 +-.20229000000000E+01 +-.11735000000000E+01 +-.38546000000000E+00 +-.14269000000000E+02 +-.13118000000000E+02 +-.11969000000000E+02 +-.10823000000000E+02 +-.96848000000000E+01 +-.85679000000000E+01 +-.74829000000000E+01 +-.64097000000000E+01 +-.53131000000000E+01 +-.42001000000000E+01 +-.31130000000000E+01 +-.21122000000000E+01 +-.12366000000000E+01 +-.43965000000000E+00 +-.14496000000000E+02 +-.13345000000000E+02 +-.12195000000000E+02 +-.11048000000000E+02 +-.99080000000000E+01 +-.87849000000000E+01 +-.76882000000000E+01 +-.66012000000000E+01 +-.54950000000000E+01 +-.43748000000000E+01 +-.32740000000000E+01 +-.22445000000000E+01 +-.13366000000000E+01 +-.52542000000000E+00 +-.14604000000000E+02 +-.13453000000000E+02 +-.12303000000000E+02 +-.11155000000000E+02 +-.10011000000000E+02 +-.88809000000000E+01 +-.77695000000000E+01 +-.66652000000000E+01 +-.55470000000000E+01 +-.44194000000000E+01 +-.33079000000000E+01 +-.22549000000000E+01 +-.13141000000000E+01 +-.48396000000000E+00 +-.14708000000000E+02 +-.13557000000000E+02 +-.12406000000000E+02 +-.11257000000000E+02 +-.10112000000000E+02 +-.89756000000000E+01 +-.78536000000000E+01 +-.67366000000000E+01 +-.56096000000000E+01 +-.44762000000000E+01 +-.33559000000000E+01 +-.22827000000000E+01 +-.13091000000000E+01 +-.45408000000000E+00 +-.14840000000000E+02 +-.13689000000000E+02 +-.12539000000000E+02 +-.11389000000000E+02 +-.10242000000000E+02 +-.91021000000000E+01 +-.79729000000000E+01 +-.68473000000000E+01 +-.57141000000000E+01 +-.45767000000000E+01 +-.34493000000000E+01 +-.23595000000000E+01 +-.13547000000000E+01 +-.46978000000000E+00 +-.14947000000000E+02 +-.13795000000000E+02 +-.12645000000000E+02 +-.11494000000000E+02 +-.10346000000000E+02 +-.92036000000000E+01 +-.80684000000000E+01 +-.69360000000000E+01 +-.57982000000000E+01 +-.46573000000000E+01 +-.35247000000000E+01 +-.24216000000000E+01 +-.13888000000000E+01 +-.47034000000000E+00 +-.15038000000000E+02 +-.13887000000000E+02 +-.12736000000000E+02 +-.11586000000000E+02 +-.10437000000000E+02 +-.92917000000000E+01 +-.81523000000000E+01 +-.70149000000000E+01 +-.58735000000000E+01 +-.47301000000000E+01 +-.35933000000000E+01 +-.24797000000000E+01 +-.14229000000000E+01 +-.46925000000000E+00 +-.15133000000000E+02 +-.13982000000000E+02 +-.12831000000000E+02 +-.11680000000000E+02 +-.10531000000000E+02 +-.93838000000000E+01 +-.82412000000000E+01 +-.71002000000000E+01 +-.59563000000000E+01 +-.48110000000000E+01 +-.36711000000000E+01 +-.25494000000000E+01 +-.14724000000000E+01 +-.48454000000000E+00 +-.15199000000000E+02 +-.14048000000000E+02 +-.12897000000000E+02 +-.11746000000000E+02 +-.10596000000000E+02 +-.94478000000000E+01 +-.83030000000000E+01 +-.71591000000000E+01 +-.60133000000000E+01 +-.48667000000000E+01 +-.37244000000000E+01 +-.25966000000000E+01 +-.15035000000000E+01 +-.48411000000000E+00 +-.15262000000000E+02 +-.14110000000000E+02 +-.12959000000000E+02 +-.11808000000000E+02 +-.10658000000000E+02 +-.95090000000000E+01 +-.83623000000000E+01 +-.72164000000000E+01 +-.60692000000000E+01 +-.49216000000000E+01 +-.37776000000000E+01 +-.26451000000000E+01 +-.15395000000000E+01 +-.49303000000000E+00 +-.15316000000000E+02 +-.14164000000000E+02 +-.13013000000000E+02 +-.11862000000000E+02 +-.10711000000000E+02 +-.95620000000000E+01 +-.84141000000000E+01 +-.72667000000000E+01 +-.61184000000000E+01 +-.49701000000000E+01 +-.38248000000000E+01 +-.26888000000000E+01 +-.15738000000000E+01 +-.50543000000000E+00 +-.15394000000000E+02 +-.14243000000000E+02 +-.13092000000000E+02 +-.11941000000000E+02 +-.10790000000000E+02 +-.96399000000000E+01 +-.84910000000000E+01 +-.73428000000000E+01 +-.61937000000000E+01 +-.50448000000000E+01 +-.38985000000000E+01 +-.27598000000000E+01 +-.16378000000000E+01 +-.55278000000000E+00 +-.15483000000000E+02 +-.14332000000000E+02 +-.13181000000000E+02 +-.12029000000000E+02 +-.10878000000000E+02 +-.97280000000000E+01 +-.85786000000000E+01 +-.74297000000000E+01 +-.62802000000000E+01 +-.51307000000000E+01 +-.39836000000000E+01 +-.28428000000000E+01 +-.17158000000000E+01 +-.61847000000000E+00 +-.15550000000000E+02 +-.14398000000000E+02 +-.13247000000000E+02 +-.12096000000000E+02 +-.10945000000000E+02 +-.97942000000000E+01 +-.86440000000000E+01 +-.74945000000000E+01 +-.63445000000000E+01 +-.51947000000000E+01 +-.40469000000000E+01 +-.29047000000000E+01 +-.17739000000000E+01 +-.66754000000000E+00 +-.15657000000000E+02 +-.14506000000000E+02 +-.13354000000000E+02 +-.12203000000000E+02 +-.11052000000000E+02 +-.99014000000000E+01 +-.87510000000000E+01 +-.76010000000000E+01 +-.64507000000000E+01 +-.53005000000000E+01 +-.41522000000000E+01 +-.30085000000000E+01 +-.18748000000000E+01 +-.76163000000000E+00 +-.15744000000000E+02 +-.14593000000000E+02 +-.13441000000000E+02 +-.12290000000000E+02 +-.11139000000000E+02 +-.99883000000000E+01 +-.88376000000000E+01 +-.76873000000000E+01 +-.65366000000000E+01 +-.53864000000000E+01 +-.42375000000000E+01 +-.30928000000000E+01 +-.19566000000000E+01 +-.83786000000000E+00 +-.15875000000000E+02 +-.14724000000000E+02 +-.13573000000000E+02 +-.12422000000000E+02 +-.11270000000000E+02 +-.10119000000000E+02 +-.89685000000000E+01 +-.78179000000000E+01 +-.66672000000000E+01 +-.55167000000000E+01 +-.43674000000000E+01 +-.32217000000000E+01 +-.20833000000000E+01 +-.95978000000000E+00 +-.16052000000000E+02 +-.14901000000000E+02 +-.13750000000000E+02 +-.12598000000000E+02 +-.11447000000000E+02 +-.10296000000000E+02 +-.91450000000000E+01 +-.79944000000000E+01 +-.68435000000000E+01 +-.56927000000000E+01 +-.45431000000000E+01 +-.33964000000000E+01 +-.22559000000000E+01 +-.11283000000000E+01 +-.16182000000000E+02 +-.15031000000000E+02 +-.13880000000000E+02 +-.12728000000000E+02 +-.11577000000000E+02 +-.10426000000000E+02 +-.92749000000000E+01 +-.81240000000000E+01 +-.69730000000000E+01 +-.58223000000000E+01 +-.46722000000000E+01 +-.35247000000000E+01 +-.23826000000000E+01 +-.12513000000000E+01 +-.16342000000000E+02 +-.15191000000000E+02 +-.14040000000000E+02 +-.12888000000000E+02 +-.11737000000000E+02 +-.10586000000000E+02 +-.94351000000000E+01 +-.82839000000000E+01 +-.71329000000000E+01 +-.59821000000000E+01 +-.48318000000000E+01 +-.36835000000000E+01 +-.25399000000000E+01 +-.14053000000000E+01 +-.16544000000000E+02 +-.15393000000000E+02 +-.14241000000000E+02 +-.13090000000000E+02 +-.11939000000000E+02 +-.10788000000000E+02 +-.96365000000000E+01 +-.84854000000000E+01 +-.73342000000000E+01 +-.61832000000000E+01 +-.50328000000000E+01 +-.38839000000000E+01 +-.27389000000000E+01 +-.16015000000000E+01 +-.16775000000000E+02 +-.15624000000000E+02 +-.14472000000000E+02 +-.13321000000000E+02 +-.12170000000000E+02 +-.11019000000000E+02 +-.98674000000000E+01 +-.87163000000000E+01 +-.75651000000000E+01 +-.64141000000000E+01 +-.52634000000000E+01 +-.41140000000000E+01 +-.29677000000000E+01 +-.18279000000000E+01 +-.17023000000000E+02 +-.15872000000000E+02 +-.14721000000000E+02 +-.13569000000000E+02 +-.12418000000000E+02 +-.11267000000000E+02 +-.10115000000000E+02 +-.89644000000000E+01 +-.78132000000000E+01 +-.66621000000000E+01 +-.55114000000000E+01 +-.43615000000000E+01 +-.32142000000000E+01 +-.20722000000000E+01 +-.17230000000000E+02 +-.16079000000000E+02 +-.14928000000000E+02 +-.13777000000000E+02 +-.12625000000000E+02 +-.11474000000000E+02 +-.10323000000000E+02 +-.91719000000000E+01 +-.80208000000000E+01 +-.68695000000000E+01 +-.57186000000000E+01 +-.45685000000000E+01 +-.34204000000000E+01 +-.22767000000000E+01 +-.17428000000000E+02 +-.16276000000000E+02 +-.15125000000000E+02 +-.13974000000000E+02 +-.12823000000000E+02 +-.11672000000000E+02 +-.10520000000000E+02 +-.93691000000000E+01 +-.82178000000000E+01 +-.70668000000000E+01 +-.59158000000000E+01 +-.47654000000000E+01 +-.36166000000000E+01 +-.24716000000000E+01 +-.17653000000000E+02 +-.16502000000000E+02 +-.15351000000000E+02 +-.14199000000000E+02 +-.13048000000000E+02 +-.11897000000000E+02 +-.10746000000000E+02 +-.95942000000000E+01 +-.84431000000000E+01 +-.72919000000000E+01 +-.61409000000000E+01 +-.49902000000000E+01 +-.38410000000000E+01 +-.26948000000000E+01 +-.17896000000000E+02 +-.16745000000000E+02 +-.15593000000000E+02 +-.14442000000000E+02 +-.13291000000000E+02 +-.12139000000000E+02 +-.10988000000000E+02 +-.98369000000000E+01 +-.86855000000000E+01 +-.75344000000000E+01 +-.63833000000000E+01 +-.52325000000000E+01 +-.40829000000000E+01 +-.29357000000000E+01 +-.18148000000000E+02 +-.16997000000000E+02 +-.15846000000000E+02 +-.14695000000000E+02 +-.13543000000000E+02 +-.12392000000000E+02 +-.11241000000000E+02 +-.10090000000000E+02 +-.89382000000000E+01 +-.77871000000000E+01 +-.66360000000000E+01 +-.54850000000000E+01 +-.43350000000000E+01 +-.31870000000000E+01 +-.18328000000000E+02 +-.17176000000000E+02 +-.16025000000000E+02 +-.14874000000000E+02 +-.13723000000000E+02 +-.12571000000000E+02 +-.11420000000000E+02 +-.10269000000000E+02 +-.91174000000000E+01 +-.79663000000000E+01 +-.68151000000000E+01 +-.56642000000000E+01 +-.45138000000000E+01 +-.33652000000000E+01 +-.18420000000000E+02 +-.17363000000000E+02 +-.16212000000000E+02 +-.15061000000000E+02 +-.13909000000000E+02 +-.12758000000000E+02 +-.11607000000000E+02 +-.10455000000000E+02 +-.93042000000000E+01 +-.81528000000000E+01 +-.70017000000000E+01 +-.58507000000000E+01 +-.47002000000000E+01 +-.35511000000000E+01 +-.14520000000000E+02 +-.13370000000000E+02 +-.12222000000000E+02 +-.11079000000000E+02 +-.99490000000000E+01 +-.88518000000000E+01 +-.78047000000000E+01 +-.67748000000000E+01 +-.57046000000000E+01 +-.46038000000000E+01 +-.35433000000000E+01 +-.25990000000000E+01 +-.17701000000000E+01 +-.98766000000000E+00 +-.14737000000000E+02 +-.13587000000000E+02 +-.12438000000000E+02 +-.11293000000000E+02 +-.10158000000000E+02 +-.90488000000000E+01 +-.79780000000000E+01 +-.69213000000000E+01 +-.58350000000000E+01 +-.47279000000000E+01 +-.36537000000000E+01 +-.26810000000000E+01 +-.18314000000000E+01 +-.10432000000000E+01 +-.14941000000000E+02 +-.13791000000000E+02 +-.12641000000000E+02 +-.11494000000000E+02 +-.10356000000000E+02 +-.92373000000000E+01 +-.81484000000000E+01 +-.70708000000000E+01 +-.59711000000000E+01 +-.48564000000000E+01 +-.37686000000000E+01 +-.27673000000000E+01 +-.18912000000000E+01 +-.10941000000000E+01 +-.15162000000000E+02 +-.14011000000000E+02 +-.12862000000000E+02 +-.11714000000000E+02 +-.10573000000000E+02 +-.94487000000000E+01 +-.83489000000000E+01 +-.72579000000000E+01 +-.61489000000000E+01 +-.50275000000000E+01 +-.39259000000000E+01 +-.28955000000000E+01 +-.19869000000000E+01 +-.11754000000000E+01 +-.15388000000000E+02 +-.14238000000000E+02 +-.13087000000000E+02 +-.11939000000000E+02 +-.10796000000000E+02 +-.96663000000000E+01 +-.85562000000000E+01 +-.74532000000000E+01 +-.63359000000000E+01 +-.52085000000000E+01 +-.40964000000000E+01 +-.30424000000000E+01 +-.21007000000000E+01 +-.12701000000000E+01 +-.15463000000000E+02 +-.14312000000000E+02 +-.13162000000000E+02 +-.12012000000000E+02 +-.10867000000000E+02 +-.97312000000000E+01 +-.86096000000000E+01 +-.74932000000000E+01 +-.63662000000000E+01 +-.52327000000000E+01 +-.41113000000000E+01 +-.30364000000000E+01 +-.20612000000000E+01 +-.12055000000000E+01 +-.15556000000000E+02 +-.14405000000000E+02 +-.13255000000000E+02 +-.12105000000000E+02 +-.10958000000000E+02 +-.98179000000000E+01 +-.86882000000000E+01 +-.75624000000000E+01 +-.64290000000000E+01 +-.52909000000000E+01 +-.41621000000000E+01 +-.30701000000000E+01 +-.20629000000000E+01 +-.11769000000000E+01 +-.15675000000000E+02 +-.14524000000000E+02 +-.13373000000000E+02 +-.12223000000000E+02 +-.11075000000000E+02 +-.99324000000000E+01 +-.87974000000000E+01 +-.76650000000000E+01 +-.65271000000000E+01 +-.53856000000000E+01 +-.42513000000000E+01 +-.31453000000000E+01 +-.21094000000000E+01 +-.11895000000000E+01 +-.15754000000000E+02 +-.14603000000000E+02 +-.13452000000000E+02 +-.12302000000000E+02 +-.11153000000000E+02 +-.10008000000000E+02 +-.88682000000000E+01 +-.77306000000000E+01 +-.65890000000000E+01 +-.54449000000000E+01 +-.43064000000000E+01 +-.31895000000000E+01 +-.21290000000000E+01 +-.11737000000000E+01 +-.15826000000000E+02 +-.14675000000000E+02 +-.13524000000000E+02 +-.12373000000000E+02 +-.11223000000000E+02 +-.10076000000000E+02 +-.89338000000000E+01 +-.77926000000000E+01 +-.66483000000000E+01 +-.55024000000000E+01 +-.43607000000000E+01 +-.32354000000000E+01 +-.21544000000000E+01 +-.11647000000000E+01 +-.15906000000000E+02 +-.14755000000000E+02 +-.13604000000000E+02 +-.12453000000000E+02 +-.11303000000000E+02 +-.10155000000000E+02 +-.90100000000000E+01 +-.78661000000000E+01 +-.67200000000000E+01 +-.55726000000000E+01 +-.44286000000000E+01 +-.32969000000000E+01 +-.21995000000000E+01 +-.11781000000000E+01 +-.15952000000000E+02 +-.14801000000000E+02 +-.13650000000000E+02 +-.12499000000000E+02 +-.11349000000000E+02 +-.10200000000000E+02 +-.90530000000000E+01 +-.79071000000000E+01 +-.67595000000000E+01 +-.56112000000000E+01 +-.44653000000000E+01 +-.33290000000000E+01 +-.22190000000000E+01 +-.11701000000000E+01 +-.16000000000000E+02 +-.14849000000000E+02 +-.13698000000000E+02 +-.12547000000000E+02 +-.11396000000000E+02 +-.10247000000000E+02 +-.90989000000000E+01 +-.79515000000000E+01 +-.68030000000000E+01 +-.56539000000000E+01 +-.45067000000000E+01 +-.33670000000000E+01 +-.22473000000000E+01 +-.11759000000000E+01 +-.16067000000000E+02 +-.14916000000000E+02 +-.13764000000000E+02 +-.12613000000000E+02 +-.11462000000000E+02 +-.10312000000000E+02 +-.91636000000000E+01 +-.80151000000000E+01 +-.68661000000000E+01 +-.57164000000000E+01 +-.45685000000000E+01 +-.34261000000000E+01 +-.22993000000000E+01 +-.12103000000000E+01 +-.16141000000000E+02 +-.14990000000000E+02 +-.13838000000000E+02 +-.12687000000000E+02 +-.11536000000000E+02 +-.10386000000000E+02 +-.92363000000000E+01 +-.80872000000000E+01 +-.69375000000000E+01 +-.57876000000000E+01 +-.46388000000000E+01 +-.34947000000000E+01 +-.23627000000000E+01 +-.12606000000000E+01 +-.16213000000000E+02 +-.15062000000000E+02 +-.13911000000000E+02 +-.12760000000000E+02 +-.11609000000000E+02 +-.10458000000000E+02 +-.93083000000000E+01 +-.81587000000000E+01 +-.70085000000000E+01 +-.58583000000000E+01 +-.47091000000000E+01 +-.35636000000000E+01 +-.24280000000000E+01 +-.13163000000000E+01 +-.16277000000000E+02 +-.15126000000000E+02 +-.13975000000000E+02 +-.12824000000000E+02 +-.11673000000000E+02 +-.10522000000000E+02 +-.93713000000000E+01 +-.82212000000000E+01 +-.70708000000000E+01 +-.59203000000000E+01 +-.47708000000000E+01 +-.36243000000000E+01 +-.24860000000000E+01 +-.13676000000000E+01 +-.16384000000000E+02 +-.15233000000000E+02 +-.14081000000000E+02 +-.12930000000000E+02 +-.11779000000000E+02 +-.10628000000000E+02 +-.94773000000000E+01 +-.83269000000000E+01 +-.71764000000000E+01 +-.60256000000000E+01 +-.48759000000000E+01 +-.37285000000000E+01 +-.25881000000000E+01 +-.14644000000000E+01 +-.16464000000000E+02 +-.15313000000000E+02 +-.14162000000000E+02 +-.13010000000000E+02 +-.11859000000000E+02 +-.10708000000000E+02 +-.95576000000000E+01 +-.84067000000000E+01 +-.72561000000000E+01 +-.61052000000000E+01 +-.49552000000000E+01 +-.38073000000000E+01 +-.26652000000000E+01 +-.15373000000000E+01 +-.16599000000000E+02 +-.15448000000000E+02 +-.14297000000000E+02 +-.13146000000000E+02 +-.11994000000000E+02 +-.10843000000000E+02 +-.96924000000000E+01 +-.85415000000000E+01 +-.73906000000000E+01 +-.62397000000000E+01 +-.50894000000000E+01 +-.39409000000000E+01 +-.27973000000000E+01 +-.16657000000000E+01 +-.16777000000000E+02 +-.15626000000000E+02 +-.14475000000000E+02 +-.13323000000000E+02 +-.12172000000000E+02 +-.11021000000000E+02 +-.98699000000000E+01 +-.87190000000000E+01 +-.75680000000000E+01 +-.64170000000000E+01 +-.52665000000000E+01 +-.41174000000000E+01 +-.29725000000000E+01 +-.18377000000000E+01 +-.16897000000000E+02 +-.15746000000000E+02 +-.14595000000000E+02 +-.13444000000000E+02 +-.12292000000000E+02 +-.11141000000000E+02 +-.99900000000000E+01 +-.88391000000000E+01 +-.76880000000000E+01 +-.65370000000000E+01 +-.53862000000000E+01 +-.42368000000000E+01 +-.30908000000000E+01 +-.19531000000000E+01 +-.17061000000000E+02 +-.15910000000000E+02 +-.14759000000000E+02 +-.13607000000000E+02 +-.12456000000000E+02 +-.11305000000000E+02 +-.10154000000000E+02 +-.90027000000000E+01 +-.78516000000000E+01 +-.67004000000000E+01 +-.55497000000000E+01 +-.43999000000000E+01 +-.32528000000000E+01 +-.21127000000000E+01 +-.17263000000000E+02 +-.16112000000000E+02 +-.14961000000000E+02 +-.13810000000000E+02 +-.12658000000000E+02 +-.11507000000000E+02 +-.10356000000000E+02 +-.92046000000000E+01 +-.80535000000000E+01 +-.69023000000000E+01 +-.57515000000000E+01 +-.46013000000000E+01 +-.34534000000000E+01 +-.23110000000000E+01 +-.17491000000000E+02 +-.16339000000000E+02 +-.15188000000000E+02 +-.14037000000000E+02 +-.12885000000000E+02 +-.11734000000000E+02 +-.10583000000000E+02 +-.94319000000000E+01 +-.82805000000000E+01 +-.71295000000000E+01 +-.59785000000000E+01 +-.48281000000000E+01 +-.36794000000000E+01 +-.25353000000000E+01 +-.17737000000000E+02 +-.16586000000000E+02 +-.15435000000000E+02 +-.14284000000000E+02 +-.13133000000000E+02 +-.11981000000000E+02 +-.10830000000000E+02 +-.96787000000000E+01 +-.85276000000000E+01 +-.73763000000000E+01 +-.62253000000000E+01 +-.50747000000000E+01 +-.39254000000000E+01 +-.27797000000000E+01 +-.17932000000000E+02 +-.16780000000000E+02 +-.15629000000000E+02 +-.14478000000000E+02 +-.13327000000000E+02 +-.12175000000000E+02 +-.11024000000000E+02 +-.98728000000000E+01 +-.87217000000000E+01 +-.75704000000000E+01 +-.64193000000000E+01 +-.52686000000000E+01 +-.41188000000000E+01 +-.29719000000000E+01 +-.18128000000000E+02 +-.16977000000000E+02 +-.15826000000000E+02 +-.14675000000000E+02 +-.13523000000000E+02 +-.12372000000000E+02 +-.11221000000000E+02 +-.10070000000000E+02 +-.89182000000000E+01 +-.77671000000000E+01 +-.66160000000000E+01 +-.54651000000000E+01 +-.43149000000000E+01 +-.31672000000000E+01 +-.18351000000000E+02 +-.17200000000000E+02 +-.16048000000000E+02 +-.14897000000000E+02 +-.13746000000000E+02 +-.12594000000000E+02 +-.11443000000000E+02 +-.10292000000000E+02 +-.91406000000000E+01 +-.79895000000000E+01 +-.68384000000000E+01 +-.56874000000000E+01 +-.45370000000000E+01 +-.33884000000000E+01 +-.18420000000000E+02 +-.17437000000000E+02 +-.16286000000000E+02 +-.15135000000000E+02 +-.13984000000000E+02 +-.12833000000000E+02 +-.11681000000000E+02 +-.10530000000000E+02 +-.93787000000000E+01 +-.82273000000000E+01 +-.70762000000000E+01 +-.59250000000000E+01 +-.47745000000000E+01 +-.36253000000000E+01 +-.18420000000000E+02 +-.17684000000000E+02 +-.16532000000000E+02 +-.15381000000000E+02 +-.14230000000000E+02 +-.13078000000000E+02 +-.11927000000000E+02 +-.10776000000000E+02 +-.96245000000000E+01 +-.84734000000000E+01 +-.73221000000000E+01 +-.61710000000000E+01 +-.50203000000000E+01 +-.38705000000000E+01 +-.18420000000000E+02 +-.17844000000000E+02 +-.16693000000000E+02 +-.15542000000000E+02 +-.14390000000000E+02 +-.13239000000000E+02 +-.12088000000000E+02 +-.10937000000000E+02 +-.97852000000000E+01 +-.86338000000000E+01 +-.74827000000000E+01 +-.63315000000000E+01 +-.51807000000000E+01 +-.40306000000000E+01 +-.15091000000000E+02 +-.13941000000000E+02 +-.12793000000000E+02 +-.11649000000000E+02 +-.10519000000000E+02 +-.94189000000000E+01 +-.83662000000000E+01 +-.73292000000000E+01 +-.62538000000000E+01 +-.51508000000000E+01 +-.40895000000000E+01 +-.31450000000000E+01 +-.23160000000000E+01 +-.15334000000000E+01 +-.15302000000000E+02 +-.14152000000000E+02 +-.13003000000000E+02 +-.11857000000000E+02 +-.10722000000000E+02 +-.96101000000000E+01 +-.85344000000000E+01 +-.74718000000000E+01 +-.63813000000000E+01 +-.52725000000000E+01 +-.41976000000000E+01 +-.32246000000000E+01 +-.23748000000000E+01 +-.15865000000000E+01 +-.15500000000000E+02 +-.14350000000000E+02 +-.13200000000000E+02 +-.12053000000000E+02 +-.10914000000000E+02 +-.97930000000000E+01 +-.87002000000000E+01 +-.76176000000000E+01 +-.65144000000000E+01 +-.53982000000000E+01 +-.43097000000000E+01 +-.33082000000000E+01 +-.24318000000000E+01 +-.16345000000000E+01 +-.15716000000000E+02 +-.14565000000000E+02 +-.13415000000000E+02 +-.12267000000000E+02 +-.11125000000000E+02 +-.99993000000000E+01 +-.88960000000000E+01 +-.78009000000000E+01 +-.66891000000000E+01 +-.55662000000000E+01 +-.44641000000000E+01 +-.34333000000000E+01 +-.25242000000000E+01 +-.17124000000000E+01 +-.15936000000000E+02 +-.14786000000000E+02 +-.13635000000000E+02 +-.12487000000000E+02 +-.11343000000000E+02 +-.10212000000000E+02 +-.90986000000000E+01 +-.79923000000000E+01 +-.68726000000000E+01 +-.57440000000000E+01 +-.46313000000000E+01 +-.35768000000000E+01 +-.26345000000000E+01 +-.18034000000000E+01 +-.16147000000000E+02 +-.14997000000000E+02 +-.13846000000000E+02 +-.12697000000000E+02 +-.11552000000000E+02 +-.10417000000000E+02 +-.92957000000000E+01 +-.81802000000000E+01 +-.70540000000000E+01 +-.59207000000000E+01 +-.47991000000000E+01 +-.37237000000000E+01 +-.27476000000000E+01 +-.18914000000000E+01 +-.16214000000000E+02 +-.15063000000000E+02 +-.13912000000000E+02 +-.12762000000000E+02 +-.11615000000000E+02 +-.10476000000000E+02 +-.93462000000000E+01 +-.82205000000000E+01 +-.70873000000000E+01 +-.59491000000000E+01 +-.48201000000000E+01 +-.37272000000000E+01 +-.27190000000000E+01 +-.18326000000000E+01 +-.16300000000000E+02 +-.15149000000000E+02 +-.13998000000000E+02 +-.12848000000000E+02 +-.11700000000000E+02 +-.10557000000000E+02 +-.94216000000000E+01 +-.82888000000000E+01 +-.71506000000000E+01 +-.60090000000000E+01 +-.48744000000000E+01 +-.37675000000000E+01 +-.27308000000000E+01 +-.18110000000000E+01 +-.16418000000000E+02 +-.15267000000000E+02 +-.14116000000000E+02 +-.12966000000000E+02 +-.11817000000000E+02 +-.10672000000000E+02 +-.95325000000000E+01 +-.83950000000000E+01 +-.72534000000000E+01 +-.61094000000000E+01 +-.49705000000000E+01 +-.38530000000000E+01 +-.27921000000000E+01 +-.18380000000000E+01 +-.16499000000000E+02 +-.15348000000000E+02 +-.14197000000000E+02 +-.13046000000000E+02 +-.11897000000000E+02 +-.10750000000000E+02 +-.96072000000000E+01 +-.84661000000000E+01 +-.73218000000000E+01 +-.61758000000000E+01 +-.50338000000000E+01 +-.39083000000000E+01 +-.28278000000000E+01 +-.18409000000000E+01 +-.16580000000000E+02 +-.15429000000000E+02 +-.14278000000000E+02 +-.13127000000000E+02 +-.11977000000000E+02 +-.10829000000000E+02 +-.96841000000000E+01 +-.85398000000000E+01 +-.73938000000000E+01 +-.62465000000000E+01 +-.51023000000000E+01 +-.39708000000000E+01 +-.28749000000000E+01 +-.18581000000000E+01 +-.16674000000000E+02 +-.15523000000000E+02 +-.14372000000000E+02 +-.13221000000000E+02 +-.12071000000000E+02 +-.10922000000000E+02 +-.97749000000000E+01 +-.86289000000000E+01 +-.74814000000000E+01 +-.63331000000000E+01 +-.51873000000000E+01 +-.40513000000000E+01 +-.29434000000000E+01 +-.19004000000000E+01 +-.16734000000000E+02 +-.15583000000000E+02 +-.14432000000000E+02 +-.13281000000000E+02 +-.12131000000000E+02 +-.10981000000000E+02 +-.98328000000000E+01 +-.86853000000000E+01 +-.75369000000000E+01 +-.63878000000000E+01 +-.52408000000000E+01 +-.41016000000000E+01 +-.29846000000000E+01 +-.19197000000000E+01 +-.16819000000000E+02 +-.15668000000000E+02 +-.14517000000000E+02 +-.13365000000000E+02 +-.12215000000000E+02 +-.11065000000000E+02 +-.99158000000000E+01 +-.87673000000000E+01 +-.76182000000000E+01 +-.64686000000000E+01 +-.53207000000000E+01 +-.41790000000000E+01 +-.30548000000000E+01 +-.19722000000000E+01 +-.16897000000000E+02 +-.15746000000000E+02 +-.14595000000000E+02 +-.13444000000000E+02 +-.12293000000000E+02 +-.11142000000000E+02 +-.99927000000000E+01 +-.88435000000000E+01 +-.76938000000000E+01 +-.65439000000000E+01 +-.53953000000000E+01 +-.42517000000000E+01 +-.31223000000000E+01 +-.20259000000000E+01 +-.16974000000000E+02 +-.15823000000000E+02 +-.14671000000000E+02 +-.13520000000000E+02 +-.12369000000000E+02 +-.11219000000000E+02 +-.10069000000000E+02 +-.89187000000000E+01 +-.77687000000000E+01 +-.66184000000000E+01 +-.54694000000000E+01 +-.43243000000000E+01 +-.31909000000000E+01 +-.20842000000000E+01 +-.17049000000000E+02 +-.15898000000000E+02 +-.14747000000000E+02 +-.13596000000000E+02 +-.12445000000000E+02 +-.11294000000000E+02 +-.10143000000000E+02 +-.89932000000000E+01 +-.78429000000000E+01 +-.66924000000000E+01 +-.55430000000000E+01 +-.43969000000000E+01 +-.32604000000000E+01 +-.21461000000000E+01 +-.17113000000000E+02 +-.15962000000000E+02 +-.14810000000000E+02 +-.13659000000000E+02 +-.12508000000000E+02 +-.11357000000000E+02 +-.10206000000000E+02 +-.90559000000000E+01 +-.79053000000000E+01 +-.67546000000000E+01 +-.56049000000000E+01 +-.44580000000000E+01 +-.33192000000000E+01 +-.21992000000000E+01 +-.17218000000000E+02 +-.16067000000000E+02 +-.14916000000000E+02 +-.13765000000000E+02 +-.12614000000000E+02 +-.11463000000000E+02 +-.10312000000000E+02 +-.91611000000000E+01 +-.80103000000000E+01 +-.68595000000000E+01 +-.57095000000000E+01 +-.45619000000000E+01 +-.34211000000000E+01 +-.22964000000000E+01 +-.17299000000000E+02 +-.16148000000000E+02 +-.14997000000000E+02 +-.13846000000000E+02 +-.12694000000000E+02 +-.11543000000000E+02 +-.10392000000000E+02 +-.92415000000000E+01 +-.80906000000000E+01 +-.69398000000000E+01 +-.57896000000000E+01 +-.46414000000000E+01 +-.34990000000000E+01 +-.23705000000000E+01 +-.17432000000000E+02 +-.16280000000000E+02 +-.15129000000000E+02 +-.13978000000000E+02 +-.12827000000000E+02 +-.11676000000000E+02 +-.10525000000000E+02 +-.93735000000000E+01 +-.82227000000000E+01 +-.70717000000000E+01 +-.59213000000000E+01 +-.47725000000000E+01 +-.36287000000000E+01 +-.24966000000000E+01 +-.17607000000000E+02 +-.16456000000000E+02 +-.15304000000000E+02 +-.14153000000000E+02 +-.13002000000000E+02 +-.11851000000000E+02 +-.10699000000000E+02 +-.95483000000000E+01 +-.83972000000000E+01 +-.72463000000000E+01 +-.60957000000000E+01 +-.49464000000000E+01 +-.38012000000000E+01 +-.26659000000000E+01 +-.17726000000000E+02 +-.16574000000000E+02 +-.15423000000000E+02 +-.14272000000000E+02 +-.13120000000000E+02 +-.11969000000000E+02 +-.10818000000000E+02 +-.96667000000000E+01 +-.85156000000000E+01 +-.73647000000000E+01 +-.62140000000000E+01 +-.50643000000000E+01 +-.39181000000000E+01 +-.27802000000000E+01 +-.17882000000000E+02 +-.16731000000000E+02 +-.15580000000000E+02 +-.14429000000000E+02 +-.13277000000000E+02 +-.12126000000000E+02 +-.10975000000000E+02 +-.98237000000000E+01 +-.86726000000000E+01 +-.75216000000000E+01 +-.63707000000000E+01 +-.52208000000000E+01 +-.40735000000000E+01 +-.29332000000000E+01 +-.18078000000000E+02 +-.16927000000000E+02 +-.15776000000000E+02 +-.14624000000000E+02 +-.13473000000000E+02 +-.12322000000000E+02 +-.11170000000000E+02 +-.10019000000000E+02 +-.88682000000000E+01 +-.77169000000000E+01 +-.65660000000000E+01 +-.54158000000000E+01 +-.42677000000000E+01 +-.31252000000000E+01 +-.18301000000000E+02 +-.17149000000000E+02 +-.15998000000000E+02 +-.14847000000000E+02 +-.13696000000000E+02 +-.12544000000000E+02 +-.11393000000000E+02 +-.10242000000000E+02 +-.90908000000000E+01 +-.79397000000000E+01 +-.67887000000000E+01 +-.56382000000000E+01 +-.44894000000000E+01 +-.33451000000000E+01 +-.18420000000000E+02 +-.17392000000000E+02 +-.16240000000000E+02 +-.15089000000000E+02 +-.13938000000000E+02 +-.12786000000000E+02 +-.11635000000000E+02 +-.10484000000000E+02 +-.93328000000000E+01 +-.81816000000000E+01 +-.70305000000000E+01 +-.58799000000000E+01 +-.47305000000000E+01 +-.35847000000000E+01 +-.18420000000000E+02 +-.17582000000000E+02 +-.16430000000000E+02 +-.15279000000000E+02 +-.14128000000000E+02 +-.12976000000000E+02 +-.11825000000000E+02 +-.10674000000000E+02 +-.95225000000000E+01 +-.83713000000000E+01 +-.72202000000000E+01 +-.60695000000000E+01 +-.49196000000000E+01 +-.37727000000000E+01 +-.18420000000000E+02 +-.17771000000000E+02 +-.16620000000000E+02 +-.15469000000000E+02 +-.14317000000000E+02 +-.13166000000000E+02 +-.12015000000000E+02 +-.10864000000000E+02 +-.97122000000000E+01 +-.85610000000000E+01 +-.74099000000000E+01 +-.62589000000000E+01 +-.51089000000000E+01 +-.39610000000000E+01 +-.18420000000000E+02 +-.17986000000000E+02 +-.16834000000000E+02 +-.15683000000000E+02 +-.14532000000000E+02 +-.13381000000000E+02 +-.12229000000000E+02 +-.11078000000000E+02 +-.99268000000000E+01 +-.87756000000000E+01 +-.76245000000000E+01 +-.64735000000000E+01 +-.53231000000000E+01 +-.41744000000000E+01 +-.18420000000000E+02 +-.18215000000000E+02 +-.17063000000000E+02 +-.15912000000000E+02 +-.14761000000000E+02 +-.13610000000000E+02 +-.12458000000000E+02 +-.11307000000000E+02 +-.10156000000000E+02 +-.90044000000000E+01 +-.78534000000000E+01 +-.67023000000000E+01 +-.55516000000000E+01 +-.44025000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.17299000000000E+02 +-.16148000000000E+02 +-.14997000000000E+02 +-.13845000000000E+02 +-.12694000000000E+02 +-.11543000000000E+02 +-.10391000000000E+02 +-.92402000000000E+01 +-.80889000000000E+01 +-.69379000000000E+01 +-.57871000000000E+01 +-.46375000000000E+01 +-.16008000000000E+02 +-.14858000000000E+02 +-.13710000000000E+02 +-.12565000000000E+02 +-.11433000000000E+02 +-.10329000000000E+02 +-.92676000000000E+01 +-.82197000000000E+01 +-.71364000000000E+01 +-.60299000000000E+01 +-.49675000000000E+01 +-.40227000000000E+01 +-.31937000000000E+01 +-.24110000000000E+01 +-.16208000000000E+02 +-.15058000000000E+02 +-.13909000000000E+02 +-.12763000000000E+02 +-.11626000000000E+02 +-.10510000000000E+02 +-.94275000000000E+01 +-.83557000000000E+01 +-.72588000000000E+01 +-.61471000000000E+01 +-.50713000000000E+01 +-.40979000000000E+01 +-.32480000000000E+01 +-.24595000000000E+01 +-.16396000000000E+02 +-.15245000000000E+02 +-.14095000000000E+02 +-.12948000000000E+02 +-.11808000000000E+02 +-.10684000000000E+02 +-.95847000000000E+01 +-.84944000000000E+01 +-.73861000000000E+01 +-.62677000000000E+01 +-.51783000000000E+01 +-.41764000000000E+01 +-.32999000000000E+01 +-.25023000000000E+01 +-.16602000000000E+02 +-.15451000000000E+02 +-.14301000000000E+02 +-.13152000000000E+02 +-.12010000000000E+02 +-.10881000000000E+02 +-.97722000000000E+01 +-.86707000000000E+01 +-.75547000000000E+01 +-.64298000000000E+01 +-.53270000000000E+01 +-.42958000000000E+01 +-.33864000000000E+01 +-.25742000000000E+01 +-.16812000000000E+02 +-.15662000000000E+02 +-.14511000000000E+02 +-.13363000000000E+02 +-.12218000000000E+02 +-.11084000000000E+02 +-.99668000000000E+01 +-.88547000000000E+01 +-.77314000000000E+01 +-.66013000000000E+01 +-.54880000000000E+01 +-.44330000000000E+01 +-.34901000000000E+01 +-.26584000000000E+01 +-.17014000000000E+02 +-.15863000000000E+02 +-.14712000000000E+02 +-.13563000000000E+02 +-.12417000000000E+02 +-.11280000000000E+02 +-.10155000000000E+02 +-.90347000000000E+01 +-.79055000000000E+01 +-.67708000000000E+01 +-.56487000000000E+01 +-.45726000000000E+01 +-.35958000000000E+01 +-.27386000000000E+01 +-.17207000000000E+02 +-.16056000000000E+02 +-.14905000000000E+02 +-.13755000000000E+02 +-.12608000000000E+02 +-.11468000000000E+02 +-.10338000000000E+02 +-.92109000000000E+01 +-.80771000000000E+01 +-.69387000000000E+01 +-.58093000000000E+01 +-.47157000000000E+01 +-.37064000000000E+01 +-.28183000000000E+01 +-.17374000000000E+02 +-.16223000000000E+02 +-.15072000000000E+02 +-.13922000000000E+02 +-.12774000000000E+02 +-.11631000000000E+02 +-.10496000000000E+02 +-.93643000000000E+01 +-.82263000000000E+01 +-.70848000000000E+01 +-.59498000000000E+01 +-.48420000000000E+01 +-.38033000000000E+01 +-.28810000000000E+01 +-.17409000000000E+02 +-.16258000000000E+02 +-.15107000000000E+02 +-.13957000000000E+02 +-.12808000000000E+02 +-.11662000000000E+02 +-.10523000000000E+02 +-.93848000000000E+01 +-.82429000000000E+01 +-.70988000000000E+01 +-.59594000000000E+01 +-.48403000000000E+01 +-.37767000000000E+01 +-.28190000000000E+01 +-.17494000000000E+02 +-.16343000000000E+02 +-.15192000000000E+02 +-.14041000000000E+02 +-.12892000000000E+02 +-.11745000000000E+02 +-.10602000000000E+02 +-.94607000000000E+01 +-.83162000000000E+01 +-.71700000000000E+01 +-.60275000000000E+01 +-.49001000000000E+01 +-.38162000000000E+01 +-.28246000000000E+01 +-.17604000000000E+02 +-.16454000000000E+02 +-.15302000000000E+02 +-.14152000000000E+02 +-.13001000000000E+02 +-.11854000000000E+02 +-.10708000000000E+02 +-.95645000000000E+01 +-.84182000000000E+01 +-.72708000000000E+01 +-.61259000000000E+01 +-.49924000000000E+01 +-.38926000000000E+01 +-.28710000000000E+01 +-.17679000000000E+02 +-.16528000000000E+02 +-.15377000000000E+02 +-.14226000000000E+02 +-.13075000000000E+02 +-.11927000000000E+02 +-.10780000000000E+02 +-.96335000000000E+01 +-.84858000000000E+01 +-.73373000000000E+01 +-.61908000000000E+01 +-.50531000000000E+01 +-.39416000000000E+01 +-.28951000000000E+01 +-.17779000000000E+02 +-.16627000000000E+02 +-.15477000000000E+02 +-.14325000000000E+02 +-.13175000000000E+02 +-.12025000000000E+02 +-.10877000000000E+02 +-.97295000000000E+01 +-.85808000000000E+01 +-.74316000000000E+01 +-.62841000000000E+01 +-.51433000000000E+01 +-.40234000000000E+01 +-.29575000000000E+01 +-.17921000000000E+02 +-.16770000000000E+02 +-.15619000000000E+02 +-.14468000000000E+02 +-.13317000000000E+02 +-.12167000000000E+02 +-.11018000000000E+02 +-.98696000000000E+01 +-.87202000000000E+01 +-.75707000000000E+01 +-.64224000000000E+01 +-.52795000000000E+01 +-.41536000000000E+01 +-.30724000000000E+01 +-.18055000000000E+02 +-.16904000000000E+02 +-.15753000000000E+02 +-.14602000000000E+02 +-.13451000000000E+02 +-.12300000000000E+02 +-.11151000000000E+02 +-.10001000000000E+02 +-.88518000000000E+01 +-.77018000000000E+01 +-.65529000000000E+01 +-.54086000000000E+01 +-.42782000000000E+01 +-.31852000000000E+01 +-.18178000000000E+02 +-.17027000000000E+02 +-.15875000000000E+02 +-.14724000000000E+02 +-.13573000000000E+02 +-.12423000000000E+02 +-.11273000000000E+02 +-.10123000000000E+02 +-.89727000000000E+01 +-.78224000000000E+01 +-.66731000000000E+01 +-.55276000000000E+01 +-.43938000000000E+01 +-.32914000000000E+01 +-.18286000000000E+02 +-.17134000000000E+02 +-.15983000000000E+02 +-.14832000000000E+02 +-.13681000000000E+02 +-.12530000000000E+02 +-.11380000000000E+02 +-.10229000000000E+02 +-.90791000000000E+01 +-.79286000000000E+01 +-.67789000000000E+01 +-.56326000000000E+01 +-.44961000000000E+01 +-.33860000000000E+01 +-.18392000000000E+02 +-.17241000000000E+02 +-.16090000000000E+02 +-.14939000000000E+02 +-.13788000000000E+02 +-.12636000000000E+02 +-.11486000000000E+02 +-.10335000000000E+02 +-.91848000000000E+01 +-.80342000000000E+01 +-.68843000000000E+01 +-.57371000000000E+01 +-.45983000000000E+01 +-.34818000000000E+01 +-.18420000000000E+02 +-.17325000000000E+02 +-.16174000000000E+02 +-.15023000000000E+02 +-.13872000000000E+02 +-.12720000000000E+02 +-.11570000000000E+02 +-.10419000000000E+02 +-.92681000000000E+01 +-.81172000000000E+01 +-.69672000000000E+01 +-.58195000000000E+01 +-.46788000000000E+01 +-.35573000000000E+01 +-.18420000000000E+02 +-.17414000000000E+02 +-.16263000000000E+02 +-.15111000000000E+02 +-.13960000000000E+02 +-.12809000000000E+02 +-.11658000000000E+02 +-.10507000000000E+02 +-.93562000000000E+01 +-.82053000000000E+01 +-.70552000000000E+01 +-.59069000000000E+01 +-.47646000000000E+01 +-.36389000000000E+01 +-.18420000000000E+02 +-.17526000000000E+02 +-.16375000000000E+02 +-.15224000000000E+02 +-.14073000000000E+02 +-.12921000000000E+02 +-.11771000000000E+02 +-.10619000000000E+02 +-.94685000000000E+01 +-.83174000000000E+01 +-.71670000000000E+01 +-.60182000000000E+01 +-.48745000000000E+01 +-.37448000000000E+01 +-.18420000000000E+02 +-.17616000000000E+02 +-.16465000000000E+02 +-.15314000000000E+02 +-.14163000000000E+02 +-.13011000000000E+02 +-.11860000000000E+02 +-.10709000000000E+02 +-.95581000000000E+01 +-.84072000000000E+01 +-.72566000000000E+01 +-.61074000000000E+01 +-.49625000000000E+01 +-.38296000000000E+01 +-.18420000000000E+02 +-.17760000000000E+02 +-.16608000000000E+02 +-.15457000000000E+02 +-.14306000000000E+02 +-.13155000000000E+02 +-.12004000000000E+02 +-.10853000000000E+02 +-.97014000000000E+01 +-.85503000000000E+01 +-.73995000000000E+01 +-.62500000000000E+01 +-.51039000000000E+01 +-.39678000000000E+01 +-.18420000000000E+02 +-.17921000000000E+02 +-.16770000000000E+02 +-.15619000000000E+02 +-.14467000000000E+02 +-.13316000000000E+02 +-.12165000000000E+02 +-.11014000000000E+02 +-.98625000000000E+01 +-.87114000000000E+01 +-.75605000000000E+01 +-.64106000000000E+01 +-.52635000000000E+01 +-.41246000000000E+01 +-.18420000000000E+02 +-.18033000000000E+02 +-.16881000000000E+02 +-.15730000000000E+02 +-.14579000000000E+02 +-.13428000000000E+02 +-.12277000000000E+02 +-.11125000000000E+02 +-.99741000000000E+01 +-.88230000000000E+01 +-.76722000000000E+01 +-.65221000000000E+01 +-.53743000000000E+01 +-.42332000000000E+01 +-.18420000000000E+02 +-.18195000000000E+02 +-.17043000000000E+02 +-.15893000000000E+02 +-.14741000000000E+02 +-.13590000000000E+02 +-.12439000000000E+02 +-.11287000000000E+02 +-.10136000000000E+02 +-.89851000000000E+01 +-.78341000000000E+01 +-.66837000000000E+01 +-.55352000000000E+01 +-.43922000000000E+01 +-.18420000000000E+02 +-.18391000000000E+02 +-.17240000000000E+02 +-.16088000000000E+02 +-.14937000000000E+02 +-.13786000000000E+02 +-.12635000000000E+02 +-.11484000000000E+02 +-.10332000000000E+02 +-.91812000000000E+01 +-.80300000000000E+01 +-.68795000000000E+01 +-.57303000000000E+01 +-.45857000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.17459000000000E+02 +-.16308000000000E+02 +-.15157000000000E+02 +-.14006000000000E+02 +-.12854000000000E+02 +-.11703000000000E+02 +-.10552000000000E+02 +-.94006000000000E+01 +-.82495000000000E+01 +-.70989000000000E+01 +-.59492000000000E+01 +-.48031000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.17695000000000E+02 +-.16543000000000E+02 +-.15393000000000E+02 +-.14241000000000E+02 +-.13090000000000E+02 +-.11939000000000E+02 +-.10787000000000E+02 +-.96362000000000E+01 +-.84849000000000E+01 +-.73341000000000E+01 +-.61841000000000E+01 +-.50367000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.17852000000000E+02 +-.16701000000000E+02 +-.15550000000000E+02 +-.14398000000000E+02 +-.13247000000000E+02 +-.12096000000000E+02 +-.10945000000000E+02 +-.97935000000000E+01 +-.86423000000000E+01 +-.74913000000000E+01 +-.63411000000000E+01 +-.51930000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18036000000000E+02 +-.16884000000000E+02 +-.15733000000000E+02 +-.14582000000000E+02 +-.13431000000000E+02 +-.12279000000000E+02 +-.11128000000000E+02 +-.99768000000000E+01 +-.88257000000000E+01 +-.76747000000000E+01 +-.65242000000000E+01 +-.53754000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18238000000000E+02 +-.17087000000000E+02 +-.15936000000000E+02 +-.14785000000000E+02 +-.13633000000000E+02 +-.12482000000000E+02 +-.11331000000000E+02 +-.10179000000000E+02 +-.90283000000000E+01 +-.78773000000000E+01 +-.67267000000000E+01 +-.55774000000000E+01 +-.17764000000000E+02 +-.16614000000000E+02 +-.15465000000000E+02 +-.14319000000000E+02 +-.13183000000000E+02 +-.12071000000000E+02 +-.10993000000000E+02 +-.99236000000000E+01 +-.88259000000000E+01 +-.77134000000000E+01 +-.66492000000000E+01 +-.57039000000000E+01 +-.48746000000000E+01 +-.40920000000000E+01 +-.17950000000000E+02 +-.16799000000000E+02 +-.15650000000000E+02 +-.14503000000000E+02 +-.13363000000000E+02 +-.12240000000000E+02 +-.11143000000000E+02 +-.10054000000000E+02 +-.89456000000000E+01 +-.78289000000000E+01 +-.67515000000000E+01 +-.57777000000000E+01 +-.49276000000000E+01 +-.41390000000000E+01 +-.18124000000000E+02 +-.16973000000000E+02 +-.15823000000000E+02 +-.14674000000000E+02 +-.13531000000000E+02 +-.12402000000000E+02 +-.11291000000000E+02 +-.10187000000000E+02 +-.90686000000000E+01 +-.79463000000000E+01 +-.68557000000000E+01 +-.58533000000000E+01 +-.49766000000000E+01 +-.41788000000000E+01 +-.18316000000000E+02 +-.17166000000000E+02 +-.16015000000000E+02 +-.14866000000000E+02 +-.13722000000000E+02 +-.12587000000000E+02 +-.11469000000000E+02 +-.10356000000000E+02 +-.92314000000000E+01 +-.81033000000000E+01 +-.69994000000000E+01 +-.59678000000000E+01 +-.50582000000000E+01 +-.42458000000000E+01 +-.18420000000000E+02 +-.17362000000000E+02 +-.16212000000000E+02 +-.15062000000000E+02 +-.13917000000000E+02 +-.12778000000000E+02 +-.11652000000000E+02 +-.10530000000000E+02 +-.94001000000000E+01 +-.82671000000000E+01 +-.71528000000000E+01 +-.60974000000000E+01 +-.51543000000000E+01 +-.43223000000000E+01 +-.18420000000000E+02 +-.17547000000000E+02 +-.16396000000000E+02 +-.15246000000000E+02 +-.14099000000000E+02 +-.12958000000000E+02 +-.11826000000000E+02 +-.10698000000000E+02 +-.95627000000000E+01 +-.84255000000000E+01 +-.73025000000000E+01 +-.62262000000000E+01 +-.52489000000000E+01 +-.43912000000000E+01 +-.18420000000000E+02 +-.17720000000000E+02 +-.16569000000000E+02 +-.15419000000000E+02 +-.14270000000000E+02 +-.13127000000000E+02 +-.11991000000000E+02 +-.10857000000000E+02 +-.97185000000000E+01 +-.85781000000000E+01 +-.74480000000000E+01 +-.63540000000000E+01 +-.53442000000000E+01 +-.44553000000000E+01 +-.18420000000000E+02 +-.17882000000000E+02 +-.16731000000000E+02 +-.15581000000000E+02 +-.14432000000000E+02 +-.13287000000000E+02 +-.12147000000000E+02 +-.11010000000000E+02 +-.98679000000000E+01 +-.87249000000000E+01 +-.75894000000000E+01 +-.64811000000000E+01 +-.54417000000000E+01 +-.45181000000000E+01 +-.18420000000000E+02 +-.18036000000000E+02 +-.16885000000000E+02 +-.15734000000000E+02 +-.14585000000000E+02 +-.13438000000000E+02 +-.12296000000000E+02 +-.11156000000000E+02 +-.10012000000000E+02 +-.88667000000000E+01 +-.77269000000000E+01 +-.66075000000000E+01 +-.55427000000000E+01 +-.45829000000000E+01 +-.18420000000000E+02 +-.18184000000000E+02 +-.17033000000000E+02 +-.15882000000000E+02 +-.14732000000000E+02 +-.13584000000000E+02 +-.12440000000000E+02 +-.11297000000000E+02 +-.10152000000000E+02 +-.90051000000000E+01 +-.78623000000000E+01 +-.67344000000000E+01 +-.56486000000000E+01 +-.46536000000000E+01 +-.18420000000000E+02 +-.18329000000000E+02 +-.17178000000000E+02 +-.16027000000000E+02 +-.14877000000000E+02 +-.13728000000000E+02 +-.12583000000000E+02 +-.11438000000000E+02 +-.10291000000000E+02 +-.91431000000000E+01 +-.79979000000000E+01 +-.68636000000000E+01 +-.57612000000000E+01 +-.47341000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.17324000000000E+02 +-.16173000000000E+02 +-.15023000000000E+02 +-.13874000000000E+02 +-.12727000000000E+02 +-.11580000000000E+02 +-.10433000000000E+02 +-.92839000000000E+01 +-.81370000000000E+01 +-.69979000000000E+01 +-.58827000000000E+01 +-.48278000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.17332000000000E+02 +-.16181000000000E+02 +-.15030000000000E+02 +-.13881000000000E+02 +-.12732000000000E+02 +-.11584000000000E+02 +-.10436000000000E+02 +-.92861000000000E+01 +-.81379000000000E+01 +-.69956000000000E+01 +-.58706000000000E+01 +-.47930000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.17415000000000E+02 +-.16264000000000E+02 +-.15113000000000E+02 +-.13963000000000E+02 +-.12813000000000E+02 +-.11665000000000E+02 +-.10515000000000E+02 +-.93652000000000E+01 +-.82163000000000E+01 +-.70714000000000E+01 +-.59393000000000E+01 +-.48436000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.17542000000000E+02 +-.16392000000000E+02 +-.15241000000000E+02 +-.14090000000000E+02 +-.12940000000000E+02 +-.11791000000000E+02 +-.10641000000000E+02 +-.94907000000000E+01 +-.83411000000000E+01 +-.71946000000000E+01 +-.60575000000000E+01 +-.49480000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.17650000000000E+02 +-.16499000000000E+02 +-.15348000000000E+02 +-.14197000000000E+02 +-.13047000000000E+02 +-.11897000000000E+02 +-.10747000000000E+02 +-.95959000000000E+01 +-.84460000000000E+01 +-.72982000000000E+01 +-.61575000000000E+01 +-.50382000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.17791000000000E+02 +-.16640000000000E+02 +-.15489000000000E+02 +-.14338000000000E+02 +-.13188000000000E+02 +-.12037000000000E+02 +-.10887000000000E+02 +-.97361000000000E+01 +-.85857000000000E+01 +-.74370000000000E+01 +-.62939000000000E+01 +-.51677000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.17989000000000E+02 +-.16837000000000E+02 +-.15686000000000E+02 +-.14535000000000E+02 +-.13385000000000E+02 +-.12234000000000E+02 +-.11083000000000E+02 +-.99324000000000E+01 +-.87817000000000E+01 +-.76328000000000E+01 +-.64882000000000E+01 +-.53572000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18235000000000E+02 +-.17083000000000E+02 +-.15933000000000E+02 +-.14781000000000E+02 +-.13631000000000E+02 +-.12480000000000E+02 +-.11329000000000E+02 +-.10178000000000E+02 +-.90273000000000E+01 +-.78779000000000E+01 +-.67323000000000E+01 +-.55983000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17362000000000E+02 +-.16210000000000E+02 +-.15060000000000E+02 +-.13908000000000E+02 +-.12758000000000E+02 +-.11607000000000E+02 +-.10456000000000E+02 +-.93049000000000E+01 +-.81550000000000E+01 +-.70088000000000E+01 +-.58726000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17662000000000E+02 +-.16511000000000E+02 +-.15360000000000E+02 +-.14208000000000E+02 +-.13058000000000E+02 +-.11906000000000E+02 +-.10755000000000E+02 +-.96045000000000E+01 +-.84546000000000E+01 +-.73077000000000E+01 +-.61699000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17987000000000E+02 +-.16836000000000E+02 +-.15685000000000E+02 +-.14533000000000E+02 +-.13382000000000E+02 +-.12231000000000E+02 +-.11080000000000E+02 +-.99292000000000E+01 +-.87791000000000E+01 +-.76317000000000E+01 +-.64921000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18280000000000E+02 +-.17129000000000E+02 +-.15978000000000E+02 +-.14826000000000E+02 +-.13675000000000E+02 +-.12524000000000E+02 +-.11373000000000E+02 +-.10222000000000E+02 +-.90718000000000E+01 +-.79236000000000E+01 +-.67822000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17375000000000E+02 +-.16224000000000E+02 +-.15073000000000E+02 +-.13922000000000E+02 +-.12770000000000E+02 +-.11619000000000E+02 +-.10468000000000E+02 +-.93176000000000E+01 +-.81692000000000E+01 +-.70261000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17605000000000E+02 +-.16454000000000E+02 +-.15303000000000E+02 +-.14151000000000E+02 +-.13000000000000E+02 +-.11849000000000E+02 +-.10698000000000E+02 +-.95474000000000E+01 +-.83982000000000E+01 +-.72535000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17758000000000E+02 +-.16607000000000E+02 +-.15456000000000E+02 +-.14305000000000E+02 +-.13154000000000E+02 +-.12002000000000E+02 +-.10851000000000E+02 +-.97004000000000E+01 +-.85510000000000E+01 +-.74053000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17931000000000E+02 +-.16780000000000E+02 +-.15628000000000E+02 +-.14477000000000E+02 +-.13326000000000E+02 +-.12175000000000E+02 +-.11024000000000E+02 +-.98728000000000E+01 +-.87229000000000E+01 +-.75760000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18111000000000E+02 +-.16959000000000E+02 +-.15808000000000E+02 +-.14657000000000E+02 +-.13506000000000E+02 +-.12354000000000E+02 +-.11203000000000E+02 +-.10052000000000E+02 +-.89021000000000E+01 +-.77543000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18208000000000E+02 +-.17057000000000E+02 +-.15906000000000E+02 +-.14754000000000E+02 +-.13603000000000E+02 +-.12452000000000E+02 +-.11301000000000E+02 +-.10150000000000E+02 +-.89993000000000E+01 +-.78508000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18347000000000E+02 +-.17195000000000E+02 +-.16044000000000E+02 +-.14893000000000E+02 +-.13741000000000E+02 +-.12590000000000E+02 +-.11439000000000E+02 +-.10288000000000E+02 +-.91375000000000E+01 +-.79885000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17361000000000E+02 +-.16209000000000E+02 +-.15058000000000E+02 +-.13907000000000E+02 +-.12756000000000E+02 +-.11604000000000E+02 +-.10453000000000E+02 +-.93025000000000E+01 +-.81531000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17543000000000E+02 +-.16392000000000E+02 +-.15241000000000E+02 +-.14090000000000E+02 +-.12938000000000E+02 +-.11787000000000E+02 +-.10636000000000E+02 +-.94854000000000E+01 +-.83354000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18354000000000E+02 +-.17216000000000E+02 +-.16096000000000E+02 +-.15004000000000E+02 +-.13917000000000E+02 +-.12808000000000E+02 +-.11691000000000E+02 +-.10625000000000E+02 +-.96794000000000E+01 +-.88501000000000E+01 +-.80674000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17385000000000E+02 +-.16256000000000E+02 +-.15148000000000E+02 +-.14044000000000E+02 +-.12927000000000E+02 +-.11806000000000E+02 +-.10727000000000E+02 +-.97532000000000E+01 +-.89031000000000E+01 +-.81147000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17545000000000E+02 +-.16410000000000E+02 +-.15290000000000E+02 +-.14174000000000E+02 +-.13049000000000E+02 +-.11923000000000E+02 +-.10832000000000E+02 +-.98289000000000E+01 +-.89521000000000E+01 +-.81545000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17729000000000E+02 +-.16591000000000E+02 +-.15464000000000E+02 +-.14342000000000E+02 +-.13211000000000E+02 +-.12080000000000E+02 +-.10975000000000E+02 +-.99436000000000E+01 +-.90339000000000E+01 +-.82217000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17919000000000E+02 +-.16777000000000E+02 +-.15645000000000E+02 +-.14515000000000E+02 +-.13379000000000E+02 +-.12244000000000E+02 +-.11129000000000E+02 +-.10073000000000E+02 +-.91301000000000E+01 +-.82981000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18098000000000E+02 +-.16954000000000E+02 +-.15816000000000E+02 +-.14681000000000E+02 +-.13542000000000E+02 +-.12403000000000E+02 +-.11279000000000E+02 +-.10202000000000E+02 +-.92249000000000E+01 +-.83672000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18265000000000E+02 +-.17119000000000E+02 +-.15979000000000E+02 +-.14839000000000E+02 +-.13697000000000E+02 +-.12555000000000E+02 +-.11425000000000E+02 +-.10330000000000E+02 +-.93203000000000E+01 +-.84316000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17276000000000E+02 +-.16132000000000E+02 +-.14990000000000E+02 +-.13846000000000E+02 +-.12702000000000E+02 +-.11566000000000E+02 +-.10457000000000E+02 +-.94180000000000E+01 +-.84941000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17424000000000E+02 +-.16279000000000E+02 +-.15135000000000E+02 +-.13989000000000E+02 +-.12843000000000E+02 +-.11702000000000E+02 +-.10583000000000E+02 +-.95178000000000E+01 +-.85579000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17565000000000E+02 +-.16418000000000E+02 +-.15272000000000E+02 +-.14125000000000E+02 +-.12977000000000E+02 +-.11834000000000E+02 +-.10706000000000E+02 +-.96204000000000E+01 +-.86252000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17699000000000E+02 +-.16551000000000E+02 +-.15404000000000E+02 +-.14256000000000E+02 +-.13107000000000E+02 +-.11961000000000E+02 +-.10827000000000E+02 +-.97246000000000E+01 +-.86973000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17827000000000E+02 +-.16678000000000E+02 +-.15530000000000E+02 +-.14381000000000E+02 +-.13232000000000E+02 +-.12085000000000E+02 +-.10946000000000E+02 +-.98301000000000E+01 +-.87749000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17950000000000E+02 +-.16801000000000E+02 +-.15652000000000E+02 +-.14502000000000E+02 +-.13353000000000E+02 +-.12204000000000E+02 +-.11062000000000E+02 +-.99365000000000E+01 +-.88579000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18094000000000E+02 +-.16944000000000E+02 +-.15795000000000E+02 +-.14645000000000E+02 +-.13495000000000E+02 +-.12346000000000E+02 +-.11201000000000E+02 +-.10068000000000E+02 +-.89712000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18243000000000E+02 +-.17093000000000E+02 +-.15943000000000E+02 +-.14793000000000E+02 +-.13643000000000E+02 +-.12493000000000E+02 +-.11346000000000E+02 +-.10208000000000E+02 +-.90969000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18386000000000E+02 +-.17236000000000E+02 +-.16085000000000E+02 +-.14935000000000E+02 +-.13785000000000E+02 +-.12635000000000E+02 +-.11486000000000E+02 +-.10345000000000E+02 +-.92224000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17372000000000E+02 +-.16221000000000E+02 +-.15071000000000E+02 +-.13920000000000E+02 +-.12769000000000E+02 +-.11620000000000E+02 +-.10476000000000E+02 +-.93455000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17355000000000E+02 +-.16205000000000E+02 +-.15054000000000E+02 +-.13903000000000E+02 +-.12752000000000E+02 +-.11603000000000E+02 +-.10456000000000E+02 +-.93201000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17396000000000E+02 +-.16245000000000E+02 +-.15094000000000E+02 +-.13943000000000E+02 +-.12792000000000E+02 +-.11642000000000E+02 +-.10494000000000E+02 +-.93535000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17478000000000E+02 +-.16327000000000E+02 +-.15176000000000E+02 +-.14024000000000E+02 +-.12874000000000E+02 +-.11723000000000E+02 +-.10574000000000E+02 +-.94307000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17561000000000E+02 +-.16410000000000E+02 +-.15259000000000E+02 +-.14108000000000E+02 +-.12957000000000E+02 +-.11806000000000E+02 +-.10656000000000E+02 +-.95107000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17647000000000E+02 +-.16496000000000E+02 +-.15345000000000E+02 +-.14194000000000E+02 +-.13042000000000E+02 +-.11892000000000E+02 +-.10741000000000E+02 +-.95942000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17780000000000E+02 +-.16629000000000E+02 +-.15478000000000E+02 +-.14327000000000E+02 +-.13176000000000E+02 +-.12025000000000E+02 +-.10874000000000E+02 +-.97258000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17961000000000E+02 +-.16810000000000E+02 +-.15659000000000E+02 +-.14508000000000E+02 +-.13356000000000E+02 +-.12205000000000E+02 +-.11055000000000E+02 +-.99055000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18134000000000E+02 +-.16982000000000E+02 +-.15831000000000E+02 +-.14680000000000E+02 +-.13529000000000E+02 +-.12378000000000E+02 +-.11227000000000E+02 +-.10077000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18293000000000E+02 +-.17142000000000E+02 +-.15991000000000E+02 +-.14840000000000E+02 +-.13689000000000E+02 +-.12537000000000E+02 +-.11386000000000E+02 +-.10236000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17308000000000E+02 +-.16157000000000E+02 +-.15006000000000E+02 +-.13854000000000E+02 +-.12703000000000E+02 +-.11552000000000E+02 +-.10402000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17441000000000E+02 +-.16290000000000E+02 +-.15138000000000E+02 +-.13987000000000E+02 +-.12836000000000E+02 +-.11685000000000E+02 +-.10534000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17547000000000E+02 +-.16396000000000E+02 +-.15245000000000E+02 +-.14094000000000E+02 +-.12942000000000E+02 +-.11791000000000E+02 +-.10640000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17662000000000E+02 +-.16511000000000E+02 +-.15360000000000E+02 +-.14208000000000E+02 +-.13057000000000E+02 +-.11906000000000E+02 +-.10755000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17727000000000E+02 +-.16575000000000E+02 +-.15424000000000E+02 +-.14273000000000E+02 +-.13122000000000E+02 +-.11970000000000E+02 +-.10820000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17827000000000E+02 +-.16675000000000E+02 +-.15524000000000E+02 +-.14373000000000E+02 +-.13221000000000E+02 +-.12070000000000E+02 +-.10919000000000E+02 +-.32123000000000E+01 +-.24135000000000E+01 +-.16445000000000E+01 +-.89139000000000E+00 +-.11166000000000E+00 +0.74065000000000E+00 +0.16499000000000E+01 +0.26064000000000E+01 +0.36346000000000E+01 +0.46964000000000E+01 +0.56748000000000E+01 +0.64109000000000E+01 +0.68398000000000E+01 +0.69116000000000E+01 +-.38093000000000E+01 +-.30001000000000E+01 +-.22491000000000E+01 +-.15411000000000E+01 +-.81697000000000E+00 +-.12542000000000E-01 +0.87141000000000E+00 +0.18254000000000E+01 +0.28591000000000E+01 +0.39374000000000E+01 +0.49778000000000E+01 +0.58689000000000E+01 +0.65031000000000E+01 +0.66700000000000E+01 +-.44155000000000E+01 +-.35817000000000E+01 +-.28231000000000E+01 +-.21225000000000E+01 +-.14144000000000E+01 +-.63327000000000E+00 +0.22562000000000E+00 +0.11606000000000E+01 +0.21817000000000E+01 +0.32587000000000E+01 +0.43243000000000E+01 +0.52916000000000E+01 +0.60544000000000E+01 +0.63645000000000E+01 +-.50289000000000E+01 +-.41628000000000E+01 +-.33814000000000E+01 +-.26694000000000E+01 +-.19627000000000E+01 +-.12013000000000E+01 +-.38148000000000E+00 +0.50528000000000E+00 +0.14836000000000E+01 +0.25370000000000E+01 +0.36073000000000E+01 +0.46158000000000E+01 +0.54628000000000E+01 +0.59406000000000E+01 +-.56479000000000E+01 +-.47469000000000E+01 +-.39346000000000E+01 +-.32004000000000E+01 +-.24862000000000E+01 +-.17388000000000E+01 +-.95795000000000E+00 +-.12858000000000E+00 +0.78818000000000E+00 +0.17947000000000E+01 +0.28472000000000E+01 +0.38724000000000E+01 +0.47755000000000E+01 +0.54004000000000E+01 +-.62378000000000E+01 +-.53062000000000E+01 +-.44633000000000E+01 +-.37037000000000E+01 +-.29760000000000E+01 +-.22352000000000E+01 +-.14861000000000E+01 +-.71088000000000E+00 +0.13690000000000E+00 +0.10757000000000E+01 +0.20849000000000E+01 +0.31054000000000E+01 +0.40454000000000E+01 +0.47810000000000E+01 +-.68320000000000E+01 +-.58751000000000E+01 +-.50056000000000E+01 +-.42238000000000E+01 +-.34835000000000E+01 +-.27443000000000E+01 +-.20157000000000E+01 +-.12828000000000E+01 +-.50070000000000E+00 +0.35836000000000E+00 +0.12988000000000E+01 +0.22867000000000E+01 +0.32408000000000E+01 +0.40513000000000E+01 +-.74762000000000E+01 +-.64926000000000E+01 +-.55916000000000E+01 +-.47791000000000E+01 +-.40182000000000E+01 +-.32723000000000E+01 +-.25535000000000E+01 +-.18507000000000E+01 +-.11245000000000E+01 +-.34462000000000E+00 +0.51141000000000E+00 +0.14396000000000E+01 +0.23819000000000E+01 +0.32372000000000E+01 +-.81782000000000E+01 +-.71681000000000E+01 +-.62332000000000E+01 +-.53840000000000E+01 +-.45942000000000E+01 +-.38309000000000E+01 +-.31060000000000E+01 +-.24153000000000E+01 +-.17271000000000E+01 +-.10107000000000E+01 +-.23111000000000E+00 +0.63004000000000E+00 +0.15419000000000E+01 +0.24163000000000E+01 +-.89509000000000E+01 +-.79172000000000E+01 +-.69506000000000E+01 +-.60651000000000E+01 +-.52440000000000E+01 +-.44561000000000E+01 +-.37109000000000E+01 +-.30126000000000E+01 +-.23361000000000E+01 +-.16502000000000E+01 +-.91649000000000E+00 +-.10674000000000E+00 +0.76959000000000E+00 +0.16455000000000E+01 +-.97607000000000E+01 +-.87048000000000E+01 +-.77062000000000E+01 +-.67814000000000E+01 +-.59229000000000E+01 +-.51044000000000E+01 +-.43314000000000E+01 +-.36120000000000E+01 +-.29255000000000E+01 +-.22411000000000E+01 +-.15226000000000E+01 +-.74252000000000E+00 +0.10222000000000E+00 +0.96973000000000E+00 +-.10576000000000E+02 +-.95007000000000E+01 +-.84729000000000E+01 +-.75094000000000E+01 +-.66110000000000E+01 +-.57578000000000E+01 +-.49510000000000E+01 +-.41986000000000E+01 +-.34833000000000E+01 +-.27780000000000E+01 +-.20521000000000E+01 +-.12830000000000E+01 +-.46034000000000E+00 +0.39584000000000E+00 +-.11379000000000E+02 +-.10288000000000E+02 +-.92358000000000E+01 +-.82390000000000E+01 +-.73038000000000E+01 +-.64163000000000E+01 +-.55720000000000E+01 +-.47778000000000E+01 +-.40199000000000E+01 +-.32764000000000E+01 +-.25250000000000E+01 +-.17495000000000E+01 +-.93669000000000E+00 +-.90240000000000E-01 +-.12133000000000E+02 +-.11028000000000E+02 +-.99556000000000E+01 +-.89290000000000E+01 +-.79580000000000E+01 +-.70337000000000E+01 +-.61483000000000E+01 +-.53086000000000E+01 +-.45066000000000E+01 +-.37252000000000E+01 +-.29482000000000E+01 +-.21631000000000E+01 +-.13567000000000E+01 +-.52367000000000E+00 +-.12827000000000E+02 +-.11712000000000E+02 +-.10623000000000E+02 +-.95708000000000E+01 +-.85676000000000E+01 +-.76093000000000E+01 +-.66866000000000E+01 +-.58055000000000E+01 +-.49639000000000E+01 +-.41460000000000E+01 +-.33387000000000E+01 +-.25360000000000E+01 +-.17301000000000E+01 +-.91200000000000E+00 +-.13439000000000E+02 +-.12317000000000E+02 +-.11216000000000E+02 +-.10147000000000E+02 +-.91201000000000E+01 +-.81360000000000E+01 +-.71842000000000E+01 +-.62677000000000E+01 +-.53878000000000E+01 +-.45325000000000E+01 +-.36936000000000E+01 +-.28724000000000E+01 +-.20653000000000E+01 +-.12633000000000E+01 +-.13977000000000E+02 +-.12850000000000E+02 +-.11740000000000E+02 +-.10656000000000E+02 +-.96106000000000E+01 +-.86052000000000E+01 +-.76311000000000E+01 +-.66868000000000E+01 +-.57748000000000E+01 +-.48887000000000E+01 +-.40244000000000E+01 +-.31863000000000E+01 +-.23759000000000E+01 +-.15867000000000E+01 +-.14485000000000E+02 +-.13354000000000E+02 +-.12236000000000E+02 +-.11141000000000E+02 +-.10078000000000E+02 +-.90530000000000E+01 +-.80583000000000E+01 +-.70897000000000E+01 +-.61499000000000E+01 +-.52358000000000E+01 +-.43472000000000E+01 +-.34896000000000E+01 +-.26710000000000E+01 +-.18895000000000E+01 +-.14967000000000E+02 +-.13832000000000E+02 +-.12707000000000E+02 +-.11601000000000E+02 +-.10523000000000E+02 +-.94790000000000E+01 +-.84648000000000E+01 +-.74745000000000E+01 +-.65103000000000E+01 +-.55720000000000E+01 +-.46616000000000E+01 +-.37880000000000E+01 +-.29617000000000E+01 +-.21865000000000E+01 +-.15442000000000E+02 +-.14304000000000E+02 +-.13174000000000E+02 +-.12059000000000E+02 +-.10967000000000E+02 +-.99058000000000E+01 +-.88735000000000E+01 +-.78641000000000E+01 +-.68799000000000E+01 +-.59229000000000E+01 +-.49941000000000E+01 +-.41049000000000E+01 +-.32712000000000E+01 +-.25016000000000E+01 +-.15943000000000E+02 +-.14802000000000E+02 +-.13668000000000E+02 +-.12546000000000E+02 +-.11443000000000E+02 +-.10366000000000E+02 +-.93186000000000E+01 +-.82954000000000E+01 +-.72965000000000E+01 +-.63236000000000E+01 +-.53778000000000E+01 +-.44733000000000E+01 +-.36335000000000E+01 +-.28739000000000E+01 +-.16493000000000E+02 +-.15350000000000E+02 +-.14212000000000E+02 +-.13084000000000E+02 +-.11971000000000E+02 +-.10881000000000E+02 +-.98191000000000E+01 +-.87832000000000E+01 +-.77717000000000E+01 +-.67853000000000E+01 +-.58253000000000E+01 +-.49064000000000E+01 +-.40568000000000E+01 +-.33020000000000E+01 +-.17108000000000E+02 +-.15963000000000E+02 +-.14823000000000E+02 +-.13690000000000E+02 +-.12570000000000E+02 +-.11469000000000E+02 +-.10393000000000E+02 +-.93442000000000E+01 +-.83201000000000E+01 +-.73207000000000E+01 +-.63475000000000E+01 +-.54141000000000E+01 +-.45497000000000E+01 +-.37893000000000E+01 +-.17770000000000E+02 +-.16624000000000E+02 +-.15482000000000E+02 +-.14345000000000E+02 +-.13219000000000E+02 +-.12108000000000E+02 +-.11020000000000E+02 +-.99585000000000E+01 +-.89221000000000E+01 +-.79116000000000E+01 +-.69281000000000E+01 +-.59824000000000E+01 +-.51028000000000E+01 +-.43278000000000E+01 +-.18420000000000E+02 +-.17317000000000E+02 +-.16172000000000E+02 +-.15033000000000E+02 +-.13901000000000E+02 +-.12783000000000E+02 +-.11684000000000E+02 +-.10610000000000E+02 +-.95608000000000E+01 +-.85388000000000E+01 +-.75448000000000E+01 +-.65863000000000E+01 +-.56891000000000E+01 +-.48925000000000E+01 +-.18420000000000E+02 +-.18012000000000E+02 +-.16867000000000E+02 +-.15726000000000E+02 +-.14591000000000E+02 +-.13468000000000E+02 +-.12361000000000E+02 +-.11277000000000E+02 +-.10218000000000E+02 +-.91838000000000E+01 +-.81782000000000E+01 +-.72059000000000E+01 +-.62898000000000E+01 +-.54691000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.17525000000000E+02 +-.16382000000000E+02 +-.15245000000000E+02 +-.14118000000000E+02 +-.13006000000000E+02 +-.11914000000000E+02 +-.10844000000000E+02 +-.97991000000000E+01 +-.87815000000000E+01 +-.77974000000000E+01 +-.68645000000000E+01 +-.60199000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18126000000000E+02 +-.16982000000000E+02 +-.15843000000000E+02 +-.14712000000000E+02 +-.13594000000000E+02 +-.12495000000000E+02 +-.11417000000000E+02 +-.10361000000000E+02 +-.93311000000000E+01 +-.83337000000000E+01 +-.73832000000000E+01 +-.65123000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17500000000000E+02 +-.16359000000000E+02 +-.15226000000000E+02 +-.14103000000000E+02 +-.12997000000000E+02 +-.11910000000000E+02 +-.10844000000000E+02 +-.98015000000000E+01 +-.87908000000000E+01 +-.78242000000000E+01 +-.69296000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17941000000000E+02 +-.16798000000000E+02 +-.15662000000000E+02 +-.14535000000000E+02 +-.13422000000000E+02 +-.12328000000000E+02 +-.11252000000000E+02 +-.10198000000000E+02 +-.91733000000000E+01 +-.81899000000000E+01 +-.72729000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18313000000000E+02 +-.17169000000000E+02 +-.16030000000000E+02 +-.14899000000000E+02 +-.13781000000000E+02 +-.12679000000000E+02 +-.11597000000000E+02 +-.10534000000000E+02 +-.94978000000000E+01 +-.84990000000000E+01 +-.75610000000000E+01 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.18420000000000E+02 +-.17488000000000E+02 +-.16347000000000E+02 +-.15213000000000E+02 +-.14090000000000E+02 +-.12982000000000E+02 +-.11893000000000E+02 +-.10824000000000E+02 +-.97778000000000E+01 +-.87651000000000E+01 +-.78074000000000E+01 +0.44296000000000E+01 +0.54792000000000E+01 +0.64447000000000E+01 +0.72579000000000E+01 +0.78667000000000E+01 +0.83457000000000E+01 +0.86248000000000E+01 +0.88271000000000E+01 +0.91875000000000E+01 +0.99858000000000E+01 +0.10309000000000E+02 +0.10431000000000E+02 +0.10640000000000E+02 +0.10871000000000E+02 +0.29191000000000E+01 +0.39877000000000E+01 +0.50403000000000E+01 +0.59996000000000E+01 +0.68003000000000E+01 +0.74020000000000E+01 +0.78754000000000E+01 +0.81770000000000E+01 +0.86106000000000E+01 +0.95017000000000E+01 +0.98684000000000E+01 +0.99060000000000E+01 +0.10102000000000E+02 +0.10334000000000E+02 +0.18213000000000E+01 +0.27822000000000E+01 +0.38122000000000E+01 +0.48510000000000E+01 +0.57832000000000E+01 +0.65446000000000E+01 +0.71635000000000E+01 +0.76353000000000E+01 +0.81567000000000E+01 +0.91929000000000E+01 +0.96023000000000E+01 +0.94731000000000E+01 +0.96021000000000E+01 +0.98286000000000E+01 +0.15739000000000E+01 +0.23090000000000E+01 +0.31550000000000E+01 +0.40071000000000E+01 +0.49697000000000E+01 +0.58384000000000E+01 +0.65767000000000E+01 +0.71375000000000E+01 +0.78712000000000E+01 +0.90679000000000E+01 +0.95149000000000E+01 +0.91909000000000E+01 +0.91702000000000E+01 +0.93794000000000E+01 +0.16307000000000E+01 +0.23680000000000E+01 +0.29696000000000E+01 +0.38635000000000E+01 +0.46632000000000E+01 +0.54062000000000E+01 +0.61655000000000E+01 +0.68562000000000E+01 +0.77590000000000E+01 +0.90911000000000E+01 +0.95562000000000E+01 +0.91128000000000E+01 +0.88445000000000E+01 +0.90569000000000E+01 +0.12207000000000E+01 +0.22409000000000E+01 +0.29769000000000E+01 +0.38297000000000E+01 +0.47664000000000E+01 +0.54723000000000E+01 +0.61736000000000E+01 +0.67584000000000E+01 +0.75010000000000E+01 +0.91912000000000E+01 +0.96438000000000E+01 +0.91912000000000E+01 +0.86643000000000E+01 +0.88735000000000E+01 +0.64412000000000E+00 +0.16344000000000E+01 +0.26022000000000E+01 +0.37073000000000E+01 +0.46886000000000E+01 +0.57090000000000E+01 +0.63463000000000E+01 +0.72565000000000E+01 +0.82590000000000E+01 +0.93101000000000E+01 +0.97205000000000E+01 +0.93364000000000E+01 +0.86377000000000E+01 +0.88291000000000E+01 +0.15805000000000E+00 +0.11465000000000