From sabre at nondot.org Mon Apr 13 00:38:24 2009 From: sabre at nondot.org (Chris Lattner) Date: Mon, 13 Apr 2009 05:38:24 -0000 Subject: [llvm-commits] [llvm] r68939 - /llvm/trunk/lib/Transforms/IPO/GlobalDCE.cpp Message-ID: <200904130538.n3D5cOG4032734@zion.cs.uiuc.edu> Author: lattner Date: Mon Apr 13 00:38:23 2009 New Revision: 68939 URL: http://llvm.org/viewvc/llvm-project?rev=68939&view=rev Log: eliminate unneeded parens. Modified: llvm/trunk/lib/Transforms/IPO/GlobalDCE.cpp Modified: llvm/trunk/lib/Transforms/IPO/GlobalDCE.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/GlobalDCE.cpp?rev=68939&r1=68938&r2=68939&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/GlobalDCE.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/GlobalDCE.cpp Mon Apr 13 00:38:23 2009 @@ -63,7 +63,7 @@ for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { Changed |= RemoveUnusedGlobalValue(*I); // Functions with external linkage are needed if they have a body - if ((!I->hasLocalLinkage() && !I->hasLinkOnceLinkage()) && + if (!I->hasLocalLinkage() && !I->hasLinkOnceLinkage() && !I->isDeclaration()) GlobalIsNeeded(I); } @@ -73,7 +73,7 @@ Changed |= RemoveUnusedGlobalValue(*I); // Externally visible & appending globals are needed, if they have an // initializer. - if ((!I->hasLocalLinkage() && !I->hasLinkOnceLinkage()) && + if (!I->hasLocalLinkage() && !I->hasLinkOnceLinkage() && !I->isDeclaration()) GlobalIsNeeded(I); } From sabre at nondot.org Mon Apr 13 00:44:35 2009 From: sabre at nondot.org (Chris Lattner) Date: Mon, 13 Apr 2009 05:44:35 -0000 Subject: [llvm-commits] [llvm] r68940 - in /llvm/trunk: docs/ include/llvm/ include/llvm/CodeGen/ lib/AsmParser/ lib/Bitcode/Reader/ lib/Bitcode/Writer/ lib/CodeGen/ lib/CodeGen/AsmPrinter/ lib/Linker/ lib/Target/CppBackend/ lib/VMCore/ test/CodeGen/Generic/ test/Transforms/GlobalDCE/ test/Transforms/Inline/ test/Transforms/InstCombine/ tools/llvm-nm/ Message-ID: <200904130544.n3D5iate000497@zion.cs.uiuc.edu> Author: lattner Date: Mon Apr 13 00:44:34 2009 New Revision: 68940 URL: http://llvm.org/viewvc/llvm-project?rev=68940&view=rev Log: Add a new "available_externally" linkage type. This is intended to support C99 inline, GNU extern inline, etc. Related bugzilla's include PR3517, PR3100, & PR2933. Nothing uses this yet, but it appears to work. Added: llvm/trunk/test/CodeGen/Generic/externally_available.ll llvm/trunk/test/Transforms/GlobalDCE/externally_available.ll llvm/trunk/test/Transforms/Inline/externally_available.ll llvm/trunk/test/Transforms/InstCombine/odr-linkage.ll Modified: llvm/trunk/docs/LangRef.html llvm/trunk/include/llvm/CodeGen/MachineFunctionPass.h llvm/trunk/include/llvm/GlobalValue.h llvm/trunk/lib/AsmParser/LLLexer.cpp llvm/trunk/lib/AsmParser/LLParser.cpp llvm/trunk/lib/AsmParser/LLToken.h llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp llvm/trunk/lib/CodeGen/MachineFunction.cpp llvm/trunk/lib/Linker/LinkModules.cpp llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp llvm/trunk/lib/VMCore/AsmWriter.cpp llvm/trunk/tools/llvm-nm/llvm-nm.cpp Modified: llvm/trunk/docs/LangRef.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=68940&r1=68939&r2=68940&view=diff ============================================================================== --- llvm/trunk/docs/LangRef.html (original) +++ llvm/trunk/docs/LangRef.html Mon Apr 13 00:44:34 2009 @@ -509,6 +509,17 @@ 'static' keyword in C. +
available_externally: +
+ +
Globals with "available_externally" linkage are never emitted + into the object file corresponding to the LLVM module. They exist to + allow inlining and other optimizations to take place given knowledge of the + definition of the global, which is known to be somewhere outside the module. + Globals with available_externally linkage are allowed to be discarded + at will, and are otherwise the same as linkonce_odr. This linkage + type is only allowed on definitions, not declarations.
+
linkonce:
Globals with "linkonce" linkage are merged with other globals of @@ -554,10 +565,10 @@
linkonce_odr:
weak_odr:
-
Some languages allow inequivalent globals to be merged, such as two +
Some languages allow differing globals to be merged, such as two functions with different semantics. Other languages, such as C++, ensure that only equivalent globals are ever merged (the "one definition - rule" - odr). Such languages can use the linkonce_odr + rule" - "ODR"). Such languages can use the linkonce_odr and weak_odr linkage types to indicate that the global will only be merged with equivalent globals. These linkage types are otherwise the same as their non-odr versions. Modified: llvm/trunk/include/llvm/CodeGen/MachineFunctionPass.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineFunctionPass.h?rev=68940&r1=68939&r2=68940&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/MachineFunctionPass.h (original) +++ llvm/trunk/include/llvm/CodeGen/MachineFunctionPass.h Mon Apr 13 00:44:34 2009 @@ -24,8 +24,9 @@ namespace llvm { + // FIXME: This pass should declare that the pass does not invalidate any LLVM + // passes. struct MachineFunctionPass : public FunctionPass { - explicit MachineFunctionPass(intptr_t ID) : FunctionPass(ID) {} explicit MachineFunctionPass(void *ID) : FunctionPass(ID) {} @@ -36,14 +37,7 @@ virtual bool runOnMachineFunction(MachineFunction &MF) = 0; public: - // FIXME: This pass should declare that the pass does not invalidate any LLVM - // passes. - bool runOnFunction(Function &F) { - return runOnMachineFunction(MachineFunction::get(&F)); - } - -private: - virtual void virtfn(); // out of line virtual fn to give class a home. + bool runOnFunction(Function &F); }; } // End llvm namespace Modified: llvm/trunk/include/llvm/GlobalValue.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/GlobalValue.h?rev=68940&r1=68939&r2=68940&view=diff ============================================================================== --- llvm/trunk/include/llvm/GlobalValue.h (original) +++ llvm/trunk/include/llvm/GlobalValue.h Mon Apr 13 00:44:34 2009 @@ -31,6 +31,7 @@ /// @brief An enumeration for the kinds of linkage for global values. enum LinkageTypes { ExternalLinkage = 0,///< Externally visible function + AvailableExternallyLinkage, ///< Available for inspection, not emission. LinkOnceAnyLinkage, ///< Keep one copy of function when linking (inline) LinkOnceODRLinkage, ///< Same, but only replaced by something equivalent. WeakAnyLinkage, ///< Keep one copy of named function when linking (weak) @@ -109,6 +110,9 @@ } bool hasExternalLinkage() const { return Linkage == ExternalLinkage; } + bool hasAvailableExternallyLinkage() const { + return Linkage == AvailableExternallyLinkage; + } bool hasLinkOnceLinkage() const { return Linkage == LinkOnceAnyLinkage || Linkage == LinkOnceODRLinkage; } @@ -119,7 +123,8 @@ bool hasInternalLinkage() const { return Linkage == InternalLinkage; } bool hasPrivateLinkage() const { return Linkage == PrivateLinkage; } bool hasLocalLinkage() const { - return Linkage == InternalLinkage || Linkage == PrivateLinkage; + return Linkage == InternalLinkage || Linkage == PrivateLinkage || + Linkage == AvailableExternallyLinkage; } bool hasDLLImportLinkage() const { return Linkage == DLLImportLinkage; } bool hasDLLExportLinkage() const { return Linkage == DLLExportLinkage; } @@ -141,9 +146,10 @@ } /// isWeakForLinker - Whether the definition of this global may be replaced at - /// link time, whether the replacement is equivalent to the original or not. + /// link time. bool isWeakForLinker() const { - return (Linkage == WeakAnyLinkage || + return (Linkage == AvailableExternallyLinkage || + Linkage == WeakAnyLinkage || Linkage == WeakODRLinkage || Linkage == LinkOnceAnyLinkage || Linkage == LinkOnceODRLinkage || Modified: llvm/trunk/lib/AsmParser/LLLexer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLLexer.cpp?rev=68940&r1=68939&r2=68940&view=diff ============================================================================== --- llvm/trunk/lib/AsmParser/LLLexer.cpp (original) +++ llvm/trunk/lib/AsmParser/LLLexer.cpp Mon Apr 13 00:44:34 2009 @@ -487,6 +487,7 @@ KEYWORD(private); KEYWORD(internal); + KEYWORD(available_externally); KEYWORD(linkonce); KEYWORD(linkonce_odr); KEYWORD(weak); Modified: llvm/trunk/lib/AsmParser/LLParser.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.cpp?rev=68940&r1=68939&r2=68940&view=diff ============================================================================== --- llvm/trunk/lib/AsmParser/LLParser.cpp (original) +++ llvm/trunk/lib/AsmParser/LLParser.cpp Mon Apr 13 00:44:34 2009 @@ -764,6 +764,9 @@ case lltok::kw_weak_odr: Res = GlobalValue::WeakODRLinkage; break; case lltok::kw_linkonce: Res = GlobalValue::LinkOnceAnyLinkage; break; case lltok::kw_linkonce_odr: Res = GlobalValue::LinkOnceODRLinkage; break; + case lltok::kw_available_externally: + Res = GlobalValue::AvailableExternallyLinkage; + break; case lltok::kw_appending: Res = GlobalValue::AppendingLinkage; break; case lltok::kw_dllexport: Res = GlobalValue::DLLExportLinkage; break; case lltok::kw_common: Res = GlobalValue::CommonLinkage; break; Modified: llvm/trunk/lib/AsmParser/LLToken.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLToken.h?rev=68940&r1=68939&r2=68940&view=diff ============================================================================== --- llvm/trunk/lib/AsmParser/LLToken.h (original) +++ llvm/trunk/lib/AsmParser/LLToken.h Mon Apr 13 00:44:34 2009 @@ -37,7 +37,7 @@ kw_global, kw_constant, kw_private, kw_internal, kw_linkonce, kw_linkonce_odr, kw_weak, kw_weak_odr, - kw_appending, kw_dllimport, kw_dllexport, kw_common, + kw_appending, kw_dllimport, kw_dllexport, kw_common,kw_available_externally, kw_default, kw_hidden, kw_protected, kw_extern_weak, kw_external, kw_thread_local, Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=68940&r1=68939&r2=68940&view=diff ============================================================================== --- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original) +++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Mon Apr 13 00:44:34 2009 @@ -70,6 +70,7 @@ case 9: return GlobalValue::PrivateLinkage; case 10: return GlobalValue::WeakODRLinkage; case 11: return GlobalValue::LinkOnceODRLinkage; + case 12: return GlobalValue::AvailableExternallyLinkage; } } Modified: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp?rev=68940&r1=68939&r2=68940&view=diff ============================================================================== --- llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp (original) +++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Mon Apr 13 00:44:34 2009 @@ -287,6 +287,7 @@ case GlobalValue::PrivateLinkage: return 9; case GlobalValue::WeakODRLinkage: return 10; case GlobalValue::LinkOnceODRLinkage: return 11; + case GlobalValue::AvailableExternallyLinkage: return 12; } } Modified: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp?rev=68940&r1=68939&r2=68940&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Mon Apr 13 00:44:34 2009 @@ -443,7 +443,9 @@ } // Ignore debug and non-emitted data. - if (GV->getSection() == "llvm.metadata") return true; + if (GV->getSection() == "llvm.metadata" || + GV->hasAvailableExternallyLinkage()) + return true; if (!GV->hasAppendingLinkage()) return false; Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp?rev=68940&r1=68939&r2=68940&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp Mon Apr 13 00:44:34 2009 @@ -3519,6 +3519,9 @@ /// void EmitEHFrame(const FunctionEHFrameInfo &EHFrameInfo) { Function::LinkageTypes linkage = EHFrameInfo.function->getLinkage(); + + assert(!EHFrameInfo.function->hasAvailableExternallyLinkage() && + "Should not emit 'available externally' functions at all"); Asm->SwitchToTextSection(TAI->getDwarfEHFrameSection()); Modified: llvm/trunk/lib/CodeGen/MachineFunction.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineFunction.cpp?rev=68940&r1=68939&r2=68940&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineFunction.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineFunction.cpp Mon Apr 13 00:44:34 2009 @@ -38,8 +38,14 @@ static AnnotationID MF_AID( AnnotationManager::getID("CodeGen::MachineCodeForFunction")); -// Out of line virtual function to home classes. -void MachineFunctionPass::virtfn() {} +bool MachineFunctionPass::runOnFunction(Function &F) { + // Do not codegen any 'available_externally' functions at all, they have + // definitions outside the translation unit. + if (F.hasAvailableExternallyLinkage()) + return false; + + return runOnMachineFunction(MachineFunction::get(&F)); +} namespace { struct VISIBILITY_HIDDEN Printer : public MachineFunctionPass { Modified: llvm/trunk/lib/Linker/LinkModules.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Linker/LinkModules.cpp?rev=68940&r1=68939&r2=68940&view=diff ============================================================================== --- llvm/trunk/lib/Linker/LinkModules.cpp (original) +++ llvm/trunk/lib/Linker/LinkModules.cpp Mon Apr 13 00:44:34 2009 @@ -480,9 +480,10 @@ } else if (Src->isWeakForLinker()) { // At this point we know that Dest has LinkOnce, External*, Weak, Common, // or DLL* linkage. - if ((Dest->hasLinkOnceLinkage() && - (Src->hasWeakLinkage() || Src->hasCommonLinkage())) || - Dest->hasExternalWeakLinkage()) { + if (Dest->hasExternalWeakLinkage() || + Dest->hasAvailableExternallyLinkage() || + (Dest->hasLinkOnceLinkage() && + (Src->hasWeakLinkage() || Src->hasCommonLinkage()))) { LinkFromSrc = true; LT = Src->getLinkage(); } else { Modified: llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp?rev=68940&r1=68939&r2=68940&view=diff ============================================================================== --- llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp (original) +++ llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp Mon Apr 13 00:44:34 2009 @@ -294,6 +294,8 @@ Out << "GlobalValue::InternalLinkage"; break; case GlobalValue::PrivateLinkage: Out << "GlobalValue::PrivateLinkage"; break; + case GlobalValue::AvailableExternallyLinkage: + Out << "GlobalValue::AvailableExternallyLinkage "; break; case GlobalValue::LinkOnceAnyLinkage: Out << "GlobalValue::LinkOnceAnyLinkage "; break; case GlobalValue::LinkOnceODRLinkage: Modified: llvm/trunk/lib/VMCore/AsmWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/AsmWriter.cpp?rev=68940&r1=68939&r2=68940&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/AsmWriter.cpp (original) +++ llvm/trunk/lib/VMCore/AsmWriter.cpp Mon Apr 13 00:44:34 2009 @@ -1225,6 +1225,9 @@ switch (LT) { case GlobalValue::PrivateLinkage: Out << "private "; break; case GlobalValue::InternalLinkage: Out << "internal "; break; + case GlobalValue::AvailableExternallyLinkage: + Out << "available_externally "; + break; case GlobalValue::LinkOnceAnyLinkage: Out << "linkonce "; break; case GlobalValue::LinkOnceODRLinkage: Out << "linkonce_odr "; break; case GlobalValue::WeakAnyLinkage: Out << "weak "; break; Added: llvm/trunk/test/CodeGen/Generic/externally_available.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Generic/externally_available.ll?rev=68940&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/Generic/externally_available.ll (added) +++ llvm/trunk/test/CodeGen/Generic/externally_available.ll Mon Apr 13 00:44:34 2009 @@ -0,0 +1,10 @@ +; RUN: llvm-as < %s | llc | not grep test_ + +; test_function should not be emitted to the .s file. +define available_externally i32 @test_function() { + ret i32 4 +} + +; test_global should not be emitted to the .s file. + at test_global = available_externally global i32 4 + Added: llvm/trunk/test/Transforms/GlobalDCE/externally_available.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GlobalDCE/externally_available.ll?rev=68940&view=auto ============================================================================== --- llvm/trunk/test/Transforms/GlobalDCE/externally_available.ll (added) +++ llvm/trunk/test/Transforms/GlobalDCE/externally_available.ll Mon Apr 13 00:44:34 2009 @@ -0,0 +1,10 @@ +; RUN: llvm-as < %s | opt -globaldce | llvm-dis | not grep test_ + +; test_function should not be emitted to the .s file. +define available_externally i32 @test_function() { + ret i32 4 +} + +; test_global should not be emitted to the .s file. + at test_global = available_externally global i32 4 + Added: llvm/trunk/test/Transforms/Inline/externally_available.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/Inline/externally_available.ll?rev=68940&view=auto ============================================================================== --- llvm/trunk/test/Transforms/Inline/externally_available.ll (added) +++ llvm/trunk/test/Transforms/Inline/externally_available.ll Mon Apr 13 00:44:34 2009 @@ -0,0 +1,16 @@ +; RUN: llvm-as < %s | opt -inline -constprop | llvm-dis > %t +; RUN: not grep test_function %t +; RUN: grep {ret i32 5} %t + + +; test_function should not be emitted to the .s file. +define available_externally i32 @test_function() { + ret i32 4 +} + + +define i32 @result() { + %A = call i32 @test_function() + %B = add i32 %A, 1 + ret i32 %B +} \ No newline at end of file Added: llvm/trunk/test/Transforms/InstCombine/odr-linkage.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/odr-linkage.ll?rev=68940&view=auto ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/odr-linkage.ll (added) +++ llvm/trunk/test/Transforms/InstCombine/odr-linkage.ll Mon Apr 13 00:44:34 2009 @@ -0,0 +1,19 @@ +; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep {ret i32 10} + + at g1 = available_externally constant i32 1 + at g2 = linkonce_odr constant i32 2 + at g3 = weak_odr constant i32 3 + at g4 = internal constant i32 4 + +define i32 @test() { + %A = load i32* @g1 + %B = load i32* @g2 + %C = load i32* @g3 + %D = load i32* @g4 + + %a = add i32 %A, %B + %b = add i32 %a, %C + %c = add i32 %b, %D + ret i32 %c +} + \ No newline at end of file Modified: llvm/trunk/tools/llvm-nm/llvm-nm.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-nm/llvm-nm.cpp?rev=68940&r1=68939&r2=68940&view=diff ============================================================================== --- llvm/trunk/tools/llvm-nm/llvm-nm.cpp (original) +++ llvm/trunk/tools/llvm-nm/llvm-nm.cpp Mon Apr 13 00:44:34 2009 @@ -69,7 +69,6 @@ } static char TypeCharForSymbol(GlobalValue &GV) { - /* FIXME: what to do with private linkage? */ if (GV.isDeclaration()) return 'U'; if (GV.hasLinkOnceLinkage()) return 'C'; if (GV.hasCommonLinkage()) return 'C'; @@ -87,8 +86,11 @@ } static void DumpSymbolNameForGlobalValue(GlobalValue &GV) { + // Private linkage and available_externally linkage don't exist in symtab. + if (GV.hasPrivateLinkage() || GV.hasAvailableExternallyLinkage()) return; + const std::string SymbolAddrStr = " "; // Not used yet... - char TypeChar = TypeCharForSymbol (GV); + char TypeChar = TypeCharForSymbol(GV); if ((TypeChar != 'U') && UndefinedOnly) return; if ((TypeChar == 'U') && DefinedOnly) @@ -96,17 +98,17 @@ if (GV.hasLocalLinkage () && ExternalOnly) return; if (OutputFormat == posix) { - std::cout << GV.getName () << " " << TypeCharForSymbol (GV) << " " + std::cout << GV.getName () << " " << TypeCharForSymbol(GV) << " " << SymbolAddrStr << "\n"; } else if (OutputFormat == bsd) { - std::cout << SymbolAddrStr << " " << TypeCharForSymbol (GV) << " " + std::cout << SymbolAddrStr << " " << TypeCharForSymbol(GV) << " " << GV.getName () << "\n"; } else if (OutputFormat == sysv) { std::string PaddedName (GV.getName ()); while (PaddedName.length () < 20) PaddedName += " "; std::cout << PaddedName << "|" << SymbolAddrStr << "| " - << TypeCharForSymbol (GV) + << TypeCharForSymbol(GV) << " | | | |\n"; } } @@ -122,10 +124,10 @@ << "Name Value Class Type" << " Size Line Section\n"; } - std::for_each (M->begin (), M->end (), DumpSymbolNameForGlobalValue); - std::for_each (M->global_begin (), M->global_end (), + std::for_each (M->begin(), M->end(), DumpSymbolNameForGlobalValue); + std::for_each (M->global_begin(), M->global_end(), DumpSymbolNameForGlobalValue); - std::for_each (M->alias_begin (), M->alias_end (), + std::for_each (M->alias_begin(), M->alias_end(), DumpSymbolNameForGlobalValue); } From sabre at nondot.org Mon Apr 13 01:25:37 2009 From: sabre at nondot.org (Chris Lattner) Date: Mon, 13 Apr 2009 06:25:37 -0000 Subject: [llvm-commits] [llvm] r68942 - /llvm/trunk/include/llvm-c/Core.h Message-ID: <200904130625.n3D6PbjK002201@zion.cs.uiuc.edu> Author: lattner Date: Mon Apr 13 01:25:37 2009 New Revision: 68942 URL: http://llvm.org/viewvc/llvm-project?rev=68942&view=rev Log: add AvailableExternally linkage to C bindings. Modified: llvm/trunk/include/llvm-c/Core.h Modified: llvm/trunk/include/llvm-c/Core.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm-c/Core.h?rev=68942&r1=68941&r2=68942&view=diff ============================================================================== --- llvm/trunk/include/llvm-c/Core.h (original) +++ llvm/trunk/include/llvm-c/Core.h Mon Apr 13 01:25:37 2009 @@ -115,6 +115,7 @@ typedef enum { LLVMExternalLinkage, /**< Externally visible function */ + LLVMAvailableExternallyLinkage, LLVMLinkOnceAnyLinkage, /**< Keep one copy of function when linking (inline)*/ LLVMLinkOnceODRLinkage, /**< Same, but only replaced by something equivalent. */ From nicholas at mxc.ca Mon Apr 13 02:02:04 2009 From: nicholas at mxc.ca (Nick Lewycky) Date: Mon, 13 Apr 2009 07:02:04 -0000 Subject: [llvm-commits] [llvm] r68944 - /llvm/trunk/lib/AsmParser/LLParser.cpp Message-ID: <200904130702.n3D724Ji003466@zion.cs.uiuc.edu> Author: nicholas Date: Mon Apr 13 02:02:02 2009 New Revision: 68944 URL: http://llvm.org/viewvc/llvm-project?rev=68944&view=rev Log: Fix warning in .ll parser, detect and reject available_externally on function declarations. Modified: llvm/trunk/lib/AsmParser/LLParser.cpp Modified: llvm/trunk/lib/AsmParser/LLParser.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.cpp?rev=68944&r1=68943&r2=68944&view=diff ============================================================================== --- llvm/trunk/lib/AsmParser/LLParser.cpp (original) +++ llvm/trunk/lib/AsmParser/LLParser.cpp Mon Apr 13 02:02:02 2009 @@ -2131,6 +2131,7 @@ break; case GlobalValue::PrivateLinkage: case GlobalValue::InternalLinkage: + case GlobalValue::AvailableExternallyLinkage: case GlobalValue::LinkOnceAnyLinkage: case GlobalValue::LinkOnceODRLinkage: case GlobalValue::WeakAnyLinkage: From nicholas at mxc.ca Mon Apr 13 02:02:33 2009 From: nicholas at mxc.ca (Nick Lewycky) Date: Mon, 13 Apr 2009 07:02:33 -0000 Subject: [llvm-commits] [llvm] r68945 - in /llvm/trunk/bindings/ocaml/llvm: llvm.ml llvm.mli Message-ID: <200904130702.n3D72Xfa003493@zion.cs.uiuc.edu> Author: nicholas Date: Mon Apr 13 02:02:32 2009 New Revision: 68945 URL: http://llvm.org/viewvc/llvm-project?rev=68945&view=rev Log: Fix ocaml bindings; add "available_externally" linkage type. Modified: llvm/trunk/bindings/ocaml/llvm/llvm.ml llvm/trunk/bindings/ocaml/llvm/llvm.mli Modified: llvm/trunk/bindings/ocaml/llvm/llvm.ml URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/bindings/ocaml/llvm/llvm.ml?rev=68945&r1=68944&r2=68945&view=diff ============================================================================== --- llvm/trunk/bindings/ocaml/llvm/llvm.ml (original) +++ llvm/trunk/bindings/ocaml/llvm/llvm.ml Mon Apr 13 02:02:32 2009 @@ -38,6 +38,7 @@ module Linkage = struct type t = | External + | Available_externally | Link_once | Weak | Appending Modified: llvm/trunk/bindings/ocaml/llvm/llvm.mli URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/bindings/ocaml/llvm/llvm.mli?rev=68945&r1=68944&r2=68945&view=diff ============================================================================== --- llvm/trunk/bindings/ocaml/llvm/llvm.mli (original) +++ llvm/trunk/bindings/ocaml/llvm/llvm.mli Mon Apr 13 02:02:32 2009 @@ -75,6 +75,7 @@ module Linkage : sig type t = External + | Available_externally | Link_once | Weak | Appending From eli.friedman at gmail.com Mon Apr 13 02:38:23 2009 From: eli.friedman at gmail.com (Eli Friedman) Date: Mon, 13 Apr 2009 00:38:23 -0700 Subject: [llvm-commits] [llvm] r68940 - in /llvm/trunk: docs/ include/llvm/ include/llvm/CodeGen/ lib/AsmParser/ lib/Bitcode/Reader/ lib/Bitcode/Writer/ lib/CodeGen/ lib/CodeGen/AsmPrinter/ lib/Linker/ lib/Target/CppBackend/ lib/VMCore/ test/CodeGen/Gener Message-ID: On Sun, Apr 12, 2009 at 10:44 PM, Chris Lattner wrote: > Author: lattner > Date: Mon Apr 13 00:44:34 2009 > New Revision: 68940 > > URL: http://llvm.org/viewvc/llvm-project?rev=68940&view=rev > Log: > Add a new "available_externally" linkage type. ?This is intended > to support C99 inline, GNU extern inline, etc. ?Related bugzilla's > include PR3517, PR3100, & PR2933. ?Nothing uses this yet, but it > appears to work. Interesting. One serious issue from looking over it: the C99 rules require that only calls from within the same translation unit are allowed to use an inline definition. -Eli From sanjiv.gupta at microchip.com Mon Apr 13 04:38:41 2009 From: sanjiv.gupta at microchip.com (Sanjiv Gupta) Date: Mon, 13 Apr 2009 09:38:41 -0000 Subject: [llvm-commits] [llvm] r68946 - /llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp Message-ID: <200904130938.n3D9cf5S020463@zion.cs.uiuc.edu> Author: sgupta Date: Mon Apr 13 04:38:38 2009 New Revision: 68946 URL: http://llvm.org/viewvc/llvm-project?rev=68946&view=rev Log: While passing arg of types larger than char only one byte at lower end was getting passed. We couldn't catch this as we did not have tests that were passing an int value larger than 256. Modified: llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp Modified: llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp?rev=68946&r1=68945&r2=68946&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp Mon Apr 13 04:38:38 2009 @@ -939,7 +939,7 @@ Ops.clear(); Ops.push_back(Chain); - Ops.push_back(Arg.getValue(0)); + Ops.push_back(Arg); Ops.push_back(PtrLo); Ops.push_back(PtrHi); Ops.push_back(DAG.getConstant(StoreOffset, MVT::i8)); From rafael.espindola at gmail.com Mon Apr 13 08:02:51 2009 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Mon, 13 Apr 2009 13:02:51 -0000 Subject: [llvm-commits] [llvm] r68947 - in /llvm/trunk: lib/Target/X86/ lib/Target/X86/AsmPrinter/ test/CodeGen/X86/ Message-ID: <200904131302.n3DD2puA027276@zion.cs.uiuc.edu> Author: rafael Date: Mon Apr 13 08:02:49 2009 New Revision: 68947 URL: http://llvm.org/viewvc/llvm-project?rev=68947&view=rev Log: X86-64 TLS support for local exec and initial exec. Modified: llvm/trunk/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp llvm/trunk/lib/Target/X86/X86ISelLowering.cpp llvm/trunk/test/CodeGen/X86/tls1.ll llvm/trunk/test/CodeGen/X86/tls10.ll llvm/trunk/test/CodeGen/X86/tls11.ll llvm/trunk/test/CodeGen/X86/tls12.ll llvm/trunk/test/CodeGen/X86/tls13.ll llvm/trunk/test/CodeGen/X86/tls14.ll llvm/trunk/test/CodeGen/X86/tls15.ll llvm/trunk/test/CodeGen/X86/tls2.ll llvm/trunk/test/CodeGen/X86/tls3.ll llvm/trunk/test/CodeGen/X86/tls4.ll llvm/trunk/test/CodeGen/X86/tls5.ll llvm/trunk/test/CodeGen/X86/tls6.ll llvm/trunk/test/CodeGen/X86/tls7.ll llvm/trunk/test/CodeGen/X86/tls8.ll llvm/trunk/test/CodeGen/X86/tls9.ll Modified: llvm/trunk/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp?rev=68947&r1=68946&r2=68947&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp Mon Apr 13 08:02:49 2009 @@ -454,14 +454,16 @@ O << "@TLSGD"; break; case TLSModel::InitialExec: - if (Subtarget->is64Bit()) - O << "@TLSGD"; // 64 bit intial exec not implemented - else + if (Subtarget->is64Bit()) { + assert (!NotRIPRel); + O << "@GOTTPOFF(%rip)"; + } else { O << "@INDNTPOFF"; + } break; case TLSModel::LocalExec: if (Subtarget->is64Bit()) - O << "@TLSGD"; // 64 bit local exec not implemented + O << "@TPOFF"; else O << "@NTPOFF"; break; Modified: llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp?rev=68947&r1=68946&r2=68947&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Mon Apr 13 08:02:49 2009 @@ -808,9 +808,16 @@ uint64_t Offset = G->getOffset(); if (!is64Bit || isInt32(AM.Disp + Offset)) { GlobalValue *GV = G->getGlobal(); + bool isRIPRel = TM.symbolicAddressesAreRIPRel(); + if (N0.getOpcode() == llvm::ISD::TargetGlobalTLSAddress) { + TLSModel::Model model = + getTLSModel (GV, TM.getRelocationModel()); + if (is64Bit && model == TLSModel::InitialExec) + isRIPRel = true; + } AM.GV = GV; AM.Disp += Offset; - AM.isRIPRel = TM.symbolicAddressesAreRIPRel(); + AM.isRIPRel = isRIPRel; return false; } } else if (ConstantPoolSDNode *CP = dyn_cast(N0)) { Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=68947&r1=68946&r2=68947&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Mon Apr 13 08:02:49 2009 @@ -4831,12 +4831,14 @@ // Lower ISD::GlobalTLSAddress using the "initial exec" (for no-pic) or // "local exec" model. static SDValue LowerToTLSExecModel(GlobalAddressSDNode *GA, SelectionDAG &DAG, - const MVT PtrVT, TLSModel::Model model) { + const MVT PtrVT, TLSModel::Model model, + bool is64Bit) { DebugLoc dl = GA->getDebugLoc(); // Get the Thread Pointer SDValue Base = DAG.getNode(X86ISD::SegmentBaseAddress, DebugLoc::getUnknownLoc(), PtrVT, - DAG.getRegister(X86::GS, MVT::i32)); + DAG.getRegister(is64Bit? X86::FS : X86::GS, + MVT::i32)); SDValue ThreadPointer = DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), Base, NULL, 0); @@ -4871,9 +4873,11 @@ switch (model) { case TLSModel::GeneralDynamic: case TLSModel::LocalDynamic: // not implemented - case TLSModel::InitialExec: // not implemented - case TLSModel::LocalExec: // not implemented return LowerToTLSGeneralDynamicModel64(GA, DAG, getPointerTy()); + + case TLSModel::InitialExec: + case TLSModel::LocalExec: + return LowerToTLSExecModel(GA, DAG, getPointerTy(), model, true); } } else { switch (model) { @@ -4883,7 +4887,7 @@ case TLSModel::InitialExec: case TLSModel::LocalExec: - return LowerToTLSExecModel(GA, DAG, getPointerTy(), model); + return LowerToTLSExecModel(GA, DAG, getPointerTy(), model, false); } } assert(0 && "Unreachable"); Modified: llvm/trunk/test/CodeGen/X86/tls1.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/tls1.ll?rev=68947&r1=68946&r2=68947&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/tls1.ll (original) +++ llvm/trunk/test/CodeGen/X86/tls1.ll Mon Apr 13 08:02:49 2009 @@ -1,5 +1,7 @@ ; RUN: llvm-as < %s | llc -march=x86 -mtriple=i386-linux-gnu > %t ; RUN: grep {movl %gs:i at NTPOFF, %eax} %t +; RUN: llvm-as < %s | llc -march=x86-64 -mtriple=x86_64-linux-gnu > %t2 +; RUN: grep {movl %fs:i at TPOFF, %eax} %t2 @i = thread_local global i32 15 Modified: llvm/trunk/test/CodeGen/X86/tls10.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/tls10.ll?rev=68947&r1=68946&r2=68947&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/tls10.ll (original) +++ llvm/trunk/test/CodeGen/X86/tls10.ll Mon Apr 13 08:02:49 2009 @@ -1,6 +1,9 @@ ; RUN: llvm-as < %s | llc -march=x86 -mtriple=i386-linux-gnu > %t ; RUN: grep {movl %gs:0, %eax} %t ; RUN: grep {leal i at NTPOFF(%eax), %eax} %t +; RUN: llvm-as < %s | llc -march=x86-64 -mtriple=x86_64-linux-gnu > %t2 +; RUN: grep {movq %fs:0, %rax} %t2 +; RUN: grep {leaq i at TPOFF(%rax), %rax} %t2 @i = external hidden thread_local global i32 Modified: llvm/trunk/test/CodeGen/X86/tls11.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/tls11.ll?rev=68947&r1=68946&r2=68947&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/tls11.ll (original) +++ llvm/trunk/test/CodeGen/X86/tls11.ll Mon Apr 13 08:02:49 2009 @@ -1,5 +1,7 @@ ; RUN: llvm-as < %s | llc -march=x86 -mtriple=i386-linux-gnu > %t ; RUN: grep {movw %gs:i at NTPOFF, %ax} %t +; RUN: llvm-as < %s | llc -march=x86-64 -mtriple=x86_64-linux-gnu > %t2 +; RUN: grep {movw %fs:i at TPOFF, %ax} %t2 @i = thread_local global i16 15 Modified: llvm/trunk/test/CodeGen/X86/tls12.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/tls12.ll?rev=68947&r1=68946&r2=68947&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/tls12.ll (original) +++ llvm/trunk/test/CodeGen/X86/tls12.ll Mon Apr 13 08:02:49 2009 @@ -1,5 +1,7 @@ ; RUN: llvm-as < %s | llc -march=x86 -mtriple=i386-linux-gnu > %t ; RUN: grep {movb %gs:i at NTPOFF, %al} %t +; RUN: llvm-as < %s | llc -march=x86-64 -mtriple=x86_64-linux-gnu > %t2 +; RUN: grep {movb %fs:i at TPOFF, %al} %t2 @i = thread_local global i8 15 Modified: llvm/trunk/test/CodeGen/X86/tls13.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/tls13.ll?rev=68947&r1=68946&r2=68947&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/tls13.ll (original) +++ llvm/trunk/test/CodeGen/X86/tls13.ll Mon Apr 13 08:02:49 2009 @@ -1,6 +1,9 @@ ; RUN: llvm-as < %s | llc -march=x86 -mtriple=i386-linux-gnu > %t ; RUN: grep {movswl %gs:i at NTPOFF, %eax} %t ; RUN: grep {movzwl %gs:j at NTPOFF, %eax} %t +; RUN: llvm-as < %s | llc -march=x86-64 -mtriple=x86_64-linux-gnu > %t2 +; RUN: grep {movswl %fs:i at TPOFF, %edi} %t2 +; RUN: grep {movzwl %fs:j at TPOFF, %edi} %t2 @i = thread_local global i16 0 @j = thread_local global i16 0 Modified: llvm/trunk/test/CodeGen/X86/tls14.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/tls14.ll?rev=68947&r1=68946&r2=68947&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/tls14.ll (original) +++ llvm/trunk/test/CodeGen/X86/tls14.ll Mon Apr 13 08:02:49 2009 @@ -1,6 +1,9 @@ ; RUN: llvm-as < %s | llc -march=x86 -mtriple=i386-linux-gnu > %t ; RUN: grep {movsbl %gs:i at NTPOFF, %eax} %t ; RUN: grep {movzbl %gs:j at NTPOFF, %eax} %t +; RUN: llvm-as < %s | llc -march=x86-64 -mtriple=x86_64-linux-gnu > %t2 +; RUN: grep {movsbl %fs:i at TPOFF, %edi} %t2 +; RUN: grep {movzbl %fs:j at TPOFF, %edi} %t2 @i = thread_local global i8 0 @j = thread_local global i8 0 Modified: llvm/trunk/test/CodeGen/X86/tls15.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/tls15.ll?rev=68947&r1=68946&r2=68947&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/tls15.ll (original) +++ llvm/trunk/test/CodeGen/X86/tls15.ll Mon Apr 13 08:02:49 2009 @@ -2,6 +2,10 @@ ; RUN: grep {movl %gs:0, %eax} %t | count 1 ; RUN: grep {leal i at NTPOFF(%eax), %ecx} %t ; RUN: grep {leal j at NTPOFF(%eax), %eax} %t +; RUN: llvm-as < %s | llc -march=x86-64 -mtriple=x86_64-linux-gnu > %t2 +; RUN: grep {movq %fs:0, %rax} %t2 | count 1 +; RUN: grep {leaq i at TPOFF(%rax), %rcx} %t2 +; RUN: grep {leaq j at TPOFF(%rax), %rax} %t2 @i = thread_local global i32 0 @j = thread_local global i32 0 Modified: llvm/trunk/test/CodeGen/X86/tls2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/tls2.ll?rev=68947&r1=68946&r2=68947&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/tls2.ll (original) +++ llvm/trunk/test/CodeGen/X86/tls2.ll Mon Apr 13 08:02:49 2009 @@ -1,6 +1,9 @@ ; RUN: llvm-as < %s | llc -march=x86 -mtriple=i386-linux-gnu > %t ; RUN: grep {movl %gs:0, %eax} %t ; RUN: grep {leal i at NTPOFF(%eax), %eax} %t +; RUN: llvm-as < %s | llc -march=x86-64 -mtriple=x86_64-linux-gnu > %t2 +; RUN: grep {movq %fs:0, %rax} %t2 +; RUN: grep {leaq i at TPOFF(%rax), %rax} %t2 @i = thread_local global i32 15 Modified: llvm/trunk/test/CodeGen/X86/tls3.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/tls3.ll?rev=68947&r1=68946&r2=68947&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/tls3.ll (original) +++ llvm/trunk/test/CodeGen/X86/tls3.ll Mon Apr 13 08:02:49 2009 @@ -1,6 +1,9 @@ ; RUN: llvm-as < %s | llc -march=x86 -mtriple=i386-linux-gnu > %t ; RUN: grep {movl i at INDNTPOFF, %eax} %t ; RUN: grep {movl %gs:(%eax), %eax} %t +; RUN: llvm-as < %s | llc -march=x86-64 -mtriple=x86_64-linux-gnu > %t2 +; RUN: grep {movq i at GOTTPOFF(%rip), %rax} %t2 +; RUN: grep {movl %fs:(%rax), %eax} %t2 @i = external thread_local global i32 ; [#uses=2] Modified: llvm/trunk/test/CodeGen/X86/tls4.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/tls4.ll?rev=68947&r1=68946&r2=68947&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/tls4.ll (original) +++ llvm/trunk/test/CodeGen/X86/tls4.ll Mon Apr 13 08:02:49 2009 @@ -1,6 +1,9 @@ ; RUN: llvm-as < %s | llc -march=x86 -mtriple=i386-linux-gnu > %t ; RUN: grep {movl %gs:0, %eax} %t ; RUN: grep {addl i at INDNTPOFF, %eax} %t +; RUN: llvm-as < %s | llc -march=x86-64 -mtriple=x86_64-linux-gnu > %t2 +; RUN: grep {movq %fs:0, %rax} %t2 +; RUN: grep {addq i at GOTTPOFF(%rip), %rax} %t2 @i = external thread_local global i32 ; [#uses=2] Modified: llvm/trunk/test/CodeGen/X86/tls5.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/tls5.ll?rev=68947&r1=68946&r2=68947&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/tls5.ll (original) +++ llvm/trunk/test/CodeGen/X86/tls5.ll Mon Apr 13 08:02:49 2009 @@ -1,5 +1,7 @@ ; RUN: llvm-as < %s | llc -march=x86 -mtriple=i386-linux-gnu > %t ; RUN: grep {movl %gs:i at NTPOFF, %eax} %t +; RUN: llvm-as < %s | llc -march=x86-64 -mtriple=x86_64-linux-gnu > %t2 +; RUN: grep {movl %fs:i at TPOFF, %eax} %t2 @i = internal thread_local global i32 15 Modified: llvm/trunk/test/CodeGen/X86/tls6.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/tls6.ll?rev=68947&r1=68946&r2=68947&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/tls6.ll (original) +++ llvm/trunk/test/CodeGen/X86/tls6.ll Mon Apr 13 08:02:49 2009 @@ -1,6 +1,9 @@ ; RUN: llvm-as < %s | llc -march=x86 -mtriple=i386-linux-gnu > %t ; RUN: grep {movl %gs:0, %eax} %t ; RUN: grep {leal i at NTPOFF(%eax), %eax} %t +; RUN: llvm-as < %s | llc -march=x86-64 -mtriple=x86_64-linux-gnu > %t2 +; RUN: grep {movq %fs:0, %rax} %t2 +; RUN: grep {leaq i at TPOFF(%rax), %rax} %t2 @i = internal thread_local global i32 15 Modified: llvm/trunk/test/CodeGen/X86/tls7.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/tls7.ll?rev=68947&r1=68946&r2=68947&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/tls7.ll (original) +++ llvm/trunk/test/CodeGen/X86/tls7.ll Mon Apr 13 08:02:49 2009 @@ -1,5 +1,7 @@ ; RUN: llvm-as < %s | llc -march=x86 -mtriple=i386-linux-gnu > %t ; RUN: grep {movl %gs:i at NTPOFF, %eax} %t +; RUN: llvm-as < %s | llc -march=x86-64 -mtriple=x86_64-linux-gnu > %t2 +; RUN: grep {movl %fs:i at TPOFF, %eax} %t2 @i = hidden thread_local global i32 15 Modified: llvm/trunk/test/CodeGen/X86/tls8.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/tls8.ll?rev=68947&r1=68946&r2=68947&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/tls8.ll (original) +++ llvm/trunk/test/CodeGen/X86/tls8.ll Mon Apr 13 08:02:49 2009 @@ -1,6 +1,9 @@ ; RUN: llvm-as < %s | llc -march=x86 -mtriple=i386-linux-gnu > %t ; RUN: grep {movl %gs:0, %eax} %t ; RUN: grep {leal i at NTPOFF(%eax), %eax} %t +; RUN: llvm-as < %s | llc -march=x86-64 -mtriple=x86_64-linux-gnu > %t2 +; RUN: grep {movq %fs:0, %rax} %t2 +; RUN: grep {leaq i at TPOFF(%rax), %rax} %t2 @i = hidden thread_local global i32 15 Modified: llvm/trunk/test/CodeGen/X86/tls9.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/tls9.ll?rev=68947&r1=68946&r2=68947&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/tls9.ll (original) +++ llvm/trunk/test/CodeGen/X86/tls9.ll Mon Apr 13 08:02:49 2009 @@ -1,5 +1,7 @@ ; RUN: llvm-as < %s | llc -march=x86 -mtriple=i386-linux-gnu > %t ; RUN: grep {movl %gs:i at NTPOFF, %eax} %t +; RUN: llvm-as < %s | llc -march=x86-64 -mtriple=x86_64-linux-gnu > %t2 +; RUN: grep {movl %fs:i at TPOFF, %eax} %t2 @i = external hidden thread_local global i32 From gohman at apple.com Mon Apr 13 10:04:32 2009 From: gohman at apple.com (Dan Gohman) Date: Mon, 13 Apr 2009 15:04:32 -0000 Subject: [llvm-commits] [llvm] r68948 - /llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Message-ID: <200904131504.n3DF4XZT031282@zion.cs.uiuc.edu> Author: djg Date: Mon Apr 13 10:04:25 2009 New Revision: 68948 URL: http://llvm.org/viewvc/llvm-project?rev=68948&view=rev Log: Fix another hard-coded constant to use X86AddrNumOperands. This unbreaks the JIT on x86-64. Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=68948&r1=68947&r2=68948&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Mon Apr 13 10:04:25 2009 @@ -2602,7 +2602,7 @@ case X86II::MRM4m: case X86II::MRM5m: case X86II::MRM6m: case X86II::MRM7m: case X86II::MRMDestMem: { - unsigned e = isTwoAddr ? 5 : 4; + unsigned e = (isTwoAddr ? X86AddrNumOperands+1 : X86AddrNumOperands); i = isTwoAddr ? 1 : 0; if (NumOps > e && isX86_64ExtendedReg(MI.getOperand(e))) REX |= 1 << 2; From gohman at apple.com Mon Apr 13 10:12:29 2009 From: gohman at apple.com (Dan Gohman) Date: Mon, 13 Apr 2009 15:12:29 -0000 Subject: [llvm-commits] [llvm] r68949 - /llvm/trunk/include/llvm/Target/TargetInstrInfo.h Message-ID: <200904131512.n3DFCTRW031555@zion.cs.uiuc.edu> Author: djg Date: Mon Apr 13 10:12:29 2009 New Revision: 68949 URL: http://llvm.org/viewvc/llvm-project?rev=68949&view=rev Log: Add comments to INSERT_SUBREG, EXTRACT_SURBEG, SUBREG_TO_REG, and IMPLICIT_DEF. Modified: llvm/trunk/include/llvm/Target/TargetInstrInfo.h Modified: llvm/trunk/include/llvm/Target/TargetInstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetInstrInfo.h?rev=68949&r1=68948&r2=68949&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetInstrInfo.h (original) +++ llvm/trunk/include/llvm/Target/TargetInstrInfo.h Mon Apr 13 10:12:29 2009 @@ -50,9 +50,29 @@ EH_LABEL = 3, GC_LABEL = 4, DECLARE = 5, + + /// EXTRACT_SUBREG - This instruction takes two operands: a register + /// that has subregisters, and a subregister index. It returns the + /// extracted subregister value. This is commonly used to implement + /// truncation operations on target architectures which support it. EXTRACT_SUBREG = 6, + + /// INSERT_SUBREG - This instruction takes three operands: a register + /// that has subregisters, a register providing an insert value, and a + /// subregister index. It returns the value of the first register with + /// the value of the second register inserted. The first register is + /// often defined by an IMPLICIT_DEF, as is commonly used to implement + /// anyext operations on target architectures which support it. INSERT_SUBREG = 7, + + /// IMPLICIT_DEF - This is the MachineInstr-level equivalent of undef. IMPLICIT_DEF = 8, + + /// SUBREG_TO_REG - This instruction is similar to INSERT_SUBREG except + /// that the first operand is an immediate integer constant. This constant + /// is often zero, as is commonly used to implement zext operations on + /// target architectures which support it, such as with x86-64 (with + /// zext from i32 to i64 via implicit zero-extension). SUBREG_TO_REG = 9 }; From gohman at apple.com Mon Apr 13 10:13:28 2009 From: gohman at apple.com (Dan Gohman) Date: Mon, 13 Apr 2009 15:13:28 -0000 Subject: [llvm-commits] [llvm] r68950 - /llvm/trunk/lib/Target/X86/X86Instr64bit.td Message-ID: <200904131513.n3DFDSiq031598@zion.cs.uiuc.edu> Author: djg Date: Mon Apr 13 10:13:28 2009 New Revision: 68950 URL: http://llvm.org/viewvc/llvm-project?rev=68950&view=rev Log: Add a comment about MOVSX64rr8. Modified: llvm/trunk/lib/Target/X86/X86Instr64bit.td Modified: llvm/trunk/lib/Target/X86/X86Instr64bit.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Instr64bit.td?rev=68950&r1=68949&r2=68950&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86Instr64bit.td (original) +++ llvm/trunk/lib/Target/X86/X86Instr64bit.td Mon Apr 13 10:13:28 2009 @@ -255,6 +255,10 @@ // Sign/Zero extenders +// MOVSX64rr8 always has a REX prefix and it has an 8-bit register +// operand, which makes it a rare instruction with an 8-bit register +// operand that can never access an h register. If support for h registers +// were generalized, this would require a special register class. def MOVSX64rr8 : RI<0xBE, MRMSrcReg, (outs GR64:$dst), (ins GR8 :$src), "movs{bq|x}\t{$src, $dst|$dst, $src}", [(set GR64:$dst, (sext GR8:$src))]>, TB; From gohman at apple.com Mon Apr 13 10:14:04 2009 From: gohman at apple.com (Dan Gohman) Date: Mon, 13 Apr 2009 15:14:04 -0000 Subject: [llvm-commits] [llvm] r68951 - /llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Message-ID: <200904131514.n3DFE4gP031625@zion.cs.uiuc.edu> Author: djg Date: Mon Apr 13 10:14:03 2009 New Revision: 68951 URL: http://llvm.org/viewvc/llvm-project?rev=68951&view=rev Log: Use X86::SUBREG_8BIT instead of hard-coding the equivalent constant. Modified: llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Modified: llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp?rev=68951&r1=68950&r2=68951&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Mon Apr 13 10:14:03 2009 @@ -1298,7 +1298,7 @@ SDNode *X86DAGToDAGISel::getTruncateTo8Bit(SDValue N0) { assert(!Subtarget->is64Bit() && "getTruncateTo8Bit is only needed on x86-32!"); - SDValue SRIdx = CurDAG->getTargetConstant(1, MVT::i32); // SubRegSet 1 + SDValue SRIdx = CurDAG->getTargetConstant(X86::SUBREG_8BIT, MVT::i32); DebugLoc dl = N0.getDebugLoc(); // Ensure that the source register has an 8-bit subreg on 32-bit targets @@ -1463,7 +1463,7 @@ Result, CurDAG->getTargetConstant(8, MVT::i8)), 0); // Then truncate it down to i8. - SDValue SRIdx = CurDAG->getTargetConstant(1, MVT::i32); // SubRegSet 1 + SDValue SRIdx = CurDAG->getTargetConstant(X86::SUBREG_8BIT, MVT::i32); Result = SDValue(CurDAG->getTargetNode(X86::EXTRACT_SUBREG, dl, MVT::i8, Result, SRIdx), 0); } else { @@ -1616,7 +1616,7 @@ CurDAG->getTargetConstant(8, MVT::i8)), 0); // Then truncate it down to i8. - SDValue SRIdx = CurDAG->getTargetConstant(1, MVT::i32); // SubRegSet 1 + SDValue SRIdx = CurDAG->getTargetConstant(X86::SUBREG_8BIT, MVT::i32); Result = SDValue(CurDAG->getTargetNode(X86::EXTRACT_SUBREG, dl, MVT::i8, Result, SRIdx), 0); } else { From gohman at apple.com Mon Apr 13 10:16:56 2009 From: gohman at apple.com (Dan Gohman) Date: Mon, 13 Apr 2009 15:16:56 -0000 Subject: [llvm-commits] [llvm] r68953 - /llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp Message-ID: <200904131516.n3DFGu0l031741@zion.cs.uiuc.edu> Author: djg Date: Mon Apr 13 10:16:56 2009 New Revision: 68953 URL: http://llvm.org/viewvc/llvm-project?rev=68953&view=rev Log: Add an assertion to verify that a copy was actually emitted. Modified: llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp Modified: llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp?rev=68953&r1=68952&r2=68953&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp (original) +++ llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp Mon Apr 13 10:16:56 2009 @@ -857,7 +857,8 @@ ReMatRegs.set(regB); ++NumReMats; } else { - TII->copyRegToReg(*mbbi, mi, regA, regB, rc, rc); + bool Emitted = TII->copyRegToReg(*mbbi, mi, regA, regB, rc, rc); + assert(Emitted && "Unable to issue a copy instruction!\n"); } MachineBasicBlock::iterator prevMI = prior(mi); From gohman at apple.com Mon Apr 13 10:18:42 2009 From: gohman at apple.com (Dan Gohman) Date: Mon, 13 Apr 2009 15:18:42 -0000 Subject: [llvm-commits] [llvm] r68954 - /llvm/trunk/lib/Target/X86/X86RegisterInfo.td Message-ID: <200904131518.n3DFIgv5031799@zion.cs.uiuc.edu> Author: djg Date: Mon Apr 13 10:18:42 2009 New Revision: 68954 URL: http://llvm.org/viewvc/llvm-project?rev=68954&view=rev Log: List the l registers before h registers, for consistency. 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=68954&r1=68953&r2=68954&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86RegisterInfo.td (original) +++ llvm/trunk/lib/Target/X86/X86RegisterInfo.td Mon Apr 13 10:18:42 2009 @@ -56,10 +56,10 @@ def BH : Register<"bh">, DwarfRegNum<[3, 3, 3]>; // 16-bit registers - def AX : RegisterWithSubRegs<"ax", [AH,AL]>, DwarfRegNum<[0, 0, 0]>; - def DX : RegisterWithSubRegs<"dx", [DH,DL]>, DwarfRegNum<[1, 2, 2]>; - def CX : RegisterWithSubRegs<"cx", [CH,CL]>, DwarfRegNum<[2, 1, 1]>; - def BX : RegisterWithSubRegs<"bx", [BH,BL]>, DwarfRegNum<[3, 3, 3]>; + def AX : RegisterWithSubRegs<"ax", [AL,AH]>, DwarfRegNum<[0, 0, 0]>; + def DX : RegisterWithSubRegs<"dx", [DL,DH]>, DwarfRegNum<[1, 2, 2]>; + def CX : RegisterWithSubRegs<"cx", [CL,CH]>, DwarfRegNum<[2, 1, 1]>; + def BX : RegisterWithSubRegs<"bx", [BL,BH]>, DwarfRegNum<[3, 3, 3]>; def SI : RegisterWithSubRegs<"si", [SIL]>, DwarfRegNum<[4, 6, 6]>; def DI : RegisterWithSubRegs<"di", [DIL]>, DwarfRegNum<[5, 7, 7]>; def BP : RegisterWithSubRegs<"bp", [BPL]>, DwarfRegNum<[6, 4, 5]>; From gohman at apple.com Mon Apr 13 10:21:32 2009 From: gohman at apple.com (Dan Gohman) Date: Mon, 13 Apr 2009 15:21:32 -0000 Subject: [llvm-commits] [llvm] r68955 - /llvm/trunk/lib/CodeGen/Spiller.cpp Message-ID: <200904131521.n3DFLWNR031927@zion.cs.uiuc.edu> Author: djg Date: Mon Apr 13 10:21:32 2009 New Revision: 68955 URL: http://llvm.org/viewvc/llvm-project?rev=68955&view=rev Log: When assigning a physical register to a MachineOperand, set the subreg field to 0, since the subreg field is only used for virtual register subregs. This doesn't change current functionality; it just eliminates bogus noise from debug output. Modified: llvm/trunk/lib/CodeGen/Spiller.cpp Modified: llvm/trunk/lib/CodeGen/Spiller.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/Spiller.cpp?rev=68955&r1=68954&r2=68955&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/Spiller.cpp (original) +++ llvm/trunk/lib/CodeGen/Spiller.cpp Mon Apr 13 10:21:32 2009 @@ -104,6 +104,7 @@ } MF.getRegInfo().setPhysRegUsed(RReg); MI.getOperand(i).setReg(RReg); + MI.getOperand(i).setSubReg(0); } else { MF.getRegInfo().setPhysRegUsed(MO.getReg()); } @@ -280,6 +281,7 @@ assert(Phys); unsigned RReg = SubIdx ? TRI->getSubReg(Phys, SubIdx) : Phys; MO.setReg(RReg); + MO.setSubReg(0); } ++NumReMats; } @@ -496,7 +498,8 @@ unsigned SubIdx = MI->getOperand(NewOp.Operand).getSubReg(); unsigned RReg = SubIdx ? TRI->getSubReg(NewPhysReg, SubIdx) : NewPhysReg; MI->getOperand(NewOp.Operand).setReg(RReg); - + MI->getOperand(NewOp.Operand).setSubReg(0); + Spills.addAvailable(NewOp.StackSlotOrReMat, NewPhysReg); --MII; UpdateKills(*MII, RegKills, KillOps, TRI); @@ -1122,6 +1125,7 @@ ReusedOperands.markClobbered(Phys); unsigned RReg = SubIdx ? TRI->getSubReg(Phys, SubIdx) : Phys; MI.getOperand(i).setReg(RReg); + MI.getOperand(i).setSubReg(0); if (VRM.isImplicitlyDefined(VirtReg)) BuildMI(MBB, &MI, MI.getDebugLoc(), TII->get(TargetInstrInfo::IMPLICIT_DEF), RReg); @@ -1185,6 +1189,7 @@ << TRI->getName(VRM.getPhys(VirtReg)) << "\n"; unsigned RReg = SubIdx ? TRI->getSubReg(PhysReg, SubIdx) : PhysReg; MI.getOperand(i).setReg(RReg); + MI.getOperand(i).setSubReg(0); // The only technical detail we have is that we don't know that // PhysReg won't be clobbered by a reloaded stack slot that occurs @@ -1264,6 +1269,7 @@ << " instead of reloading into same physreg.\n"; unsigned RReg = SubIdx ? TRI->getSubReg(PhysReg, SubIdx) : PhysReg; MI.getOperand(i).setReg(RReg); + MI.getOperand(i).setSubReg(0); ReusedOperands.markClobbered(RReg); ++NumReused; continue; @@ -1284,6 +1290,7 @@ unsigned RReg = SubIdx ? TRI->getSubReg(DesignatedReg, SubIdx) : DesignatedReg; MI.getOperand(i).setReg(RReg); + MI.getOperand(i).setSubReg(0); DOUT << '\t' << *prior(MII); ++NumReused; continue; @@ -1328,6 +1335,7 @@ } unsigned RReg = SubIdx ? TRI->getSubReg(PhysReg, SubIdx) : PhysReg; MI.getOperand(i).setReg(RReg); + MI.getOperand(i).setSubReg(0); UpdateKills(*prior(MII), RegKills, KillOps, TRI); DOUT << '\t' << *prior(MII); } @@ -1613,6 +1621,7 @@ unsigned RReg = SubIdx ? TRI->getSubReg(PhysReg, SubIdx) : PhysReg; ReusedOperands.markClobbered(RReg); MI.getOperand(i).setReg(RReg); + MI.getOperand(i).setSubReg(0); if (!MO.isDead()) { MachineInstr *&LastStore = MaybeDeadStores[StackSlot]; From gohman at apple.com Mon Apr 13 10:22:30 2009 From: gohman at apple.com (Dan Gohman) Date: Mon, 13 Apr 2009 15:22:30 -0000 Subject: [llvm-commits] [llvm] r68956 - /llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Message-ID: <200904131522.n3DFMUad032009@zion.cs.uiuc.edu> Author: djg Date: Mon Apr 13 10:22:29 2009 New Revision: 68956 URL: http://llvm.org/viewvc/llvm-project?rev=68956&view=rev Log: Don't abort on an aliasing physical register that does not have a live interval. This is needed for some upcoming subreg changes. Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=68956&r1=68955&r2=68956&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Mon Apr 13 10:22:29 2009 @@ -2235,7 +2235,7 @@ // If there are registers which alias PhysReg, but which are not a // sub-register of the chosen representative super register. Assert // since we can't handle it yet. - assert(*AS == SpillReg || !allocatableRegs_[*AS] || + assert(*AS == SpillReg || !allocatableRegs_[*AS] || !hasInterval(*AS) || tri_->isSuperRegister(*AS, SpillReg)); bool Cut = false; From gohman at apple.com Mon Apr 13 10:24:11 2009 From: gohman at apple.com (Dan Gohman) Date: Mon, 13 Apr 2009 15:24:11 -0000 Subject: [llvm-commits] [llvm] r68957 - /llvm/trunk/utils/TableGen/CodeGenTarget.h Message-ID: <200904131524.n3DFOB8K032067@zion.cs.uiuc.edu> Author: djg Date: Mon Apr 13 10:24:11 2009 New Revision: 68957 URL: http://llvm.org/viewvc/llvm-project?rev=68957&view=rev Log: Generalize getRegisterClassForRegister to handle registers in multiple classes in the case that the classes are all in subset/superset relations. This function is used by the fast-isel emitter, which always wants the super-most set. Modified: llvm/trunk/utils/TableGen/CodeGenTarget.h Modified: llvm/trunk/utils/TableGen/CodeGenTarget.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenTarget.h?rev=68957&r1=68956&r2=68957&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/CodeGenTarget.h (original) +++ llvm/trunk/utils/TableGen/CodeGenTarget.h Mon Apr 13 10:24:11 2009 @@ -19,6 +19,7 @@ #include "CodeGenRegisters.h" #include "CodeGenInstruction.h" +#include #include #include @@ -110,19 +111,54 @@ } /// getRegisterClassForRegister - Find the register class that contains the - /// specified physical register. If there register exists in multiple - /// register classes or is not in a register class, return null. + /// specified physical register. If the register is not in a register + /// class, return null. If the register is in multiple classes, and the + /// classes have a superset-subset relationship and the same set of + /// types, return the superclass. Otherwise return null. const CodeGenRegisterClass *getRegisterClassForRegister(Record *R) const { const std::vector &RCs = getRegisterClasses(); const CodeGenRegisterClass *FoundRC = 0; for (unsigned i = 0, e = RCs.size(); i != e; ++i) { const CodeGenRegisterClass &RC = RegisterClasses[i]; for (unsigned ei = 0, ee = RC.Elements.size(); ei != ee; ++ei) { - if (R == RC.Elements[ei]) { - if (FoundRC) return 0; // In multiple RC's + if (R != RC.Elements[ei]) + continue; + + // If a register's classes have different types, return null. + if (FoundRC && RC.getValueTypes() != FoundRC->getValueTypes()) + return 0; + + // If this is the first class that contains the register, + // make a note of it and go on to the next class. + if (!FoundRC) { + FoundRC = &RC; + break; + } + + std::vector Elements(RC.Elements); + std::vector FoundElements(FoundRC->Elements); + std::sort(Elements.begin(), Elements.end()); + std::sort(FoundElements.begin(), FoundElements.end()); + + // Check to see if the previously found class that contains + // the register is a subclass of the current class. If so, + // prefer the superclass. + if (std::includes(Elements.begin(), Elements.end(), + FoundElements.begin(), FoundElements.end())) { FoundRC = &RC; break; } + + // Check to see if the previously found class that contains + // the register is a superclass of the current class. If so, + // prefer the superclass. + if (std::includes(FoundElements.begin(), FoundElements.end(), + Elements.begin(), Elements.end())) + break; + + // Multiple classes, and neither is a superclass of the other. + // Return null. + return 0; } } return FoundRC; From gohman at apple.com Mon Apr 13 10:28:30 2009 From: gohman at apple.com (Dan Gohman) Date: Mon, 13 Apr 2009 15:28:30 -0000 Subject: [llvm-commits] [llvm] r68958 - /llvm/trunk/lib/Target/X86/X86RegisterInfo.td Message-ID: <200904131528.n3DFSUGN032223@zion.cs.uiuc.edu> Author: djg Date: Mon Apr 13 10:28:29 2009 New Revision: 68958 URL: http://llvm.org/viewvc/llvm-project?rev=68958&view=rev Log: Fix copy+pastos in comments. 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=68958&r1=68957&r2=68958&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86RegisterInfo.td (original) +++ llvm/trunk/lib/Target/X86/X86RegisterInfo.td Mon Apr 13 10:28:29 2009 @@ -311,7 +311,7 @@ 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. + // If not, just don't allocate SP. 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, @@ -379,7 +379,7 @@ 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. + // If not, just don't allocate ESP. 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, From gohman at apple.com Mon Apr 13 10:29:31 2009 From: gohman at apple.com (Dan Gohman) Date: Mon, 13 Apr 2009 15:29:31 -0000 Subject: [llvm-commits] [llvm] r68959 - /llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Message-ID: <200904131529.n3DFTWC4032294@zion.cs.uiuc.edu> Author: djg Date: Mon Apr 13 10:29:31 2009 New Revision: 68959 URL: http://llvm.org/viewvc/llvm-project?rev=68959&view=rev Log: Remove x86's special-case handling for ISD::TRUNCATE and ISD::SIGN_EXTEND_INREG. Tablegen-generated code can handle these cases, and the scheduling issues observed earlier appear to be resolved now. Modified: llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Modified: llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp?rev=68959&r1=68958&r2=68959&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Mon Apr 13 10:29:31 2009 @@ -243,12 +243,6 @@ /// SDNode *getGlobalBaseReg(); - /// getTruncateTo8Bit - return an SDNode that implements a subreg based - /// truncate of the specified operand to i8. This can be done with tablegen, - /// except that this code uses MVT::Flag in a tricky way that happens to - /// improve scheduling in some cases. - SDNode *getTruncateTo8Bit(SDValue N0); - #ifndef NDEBUG unsigned Indent; #endif @@ -1291,36 +1285,6 @@ return FindCallStartFromCall(Node->getOperand(0).getNode()); } -/// getTruncateTo8Bit - return an SDNode that implements a subreg based -/// truncate of the specified operand to i8. This can be done with tablegen, -/// except that this code uses MVT::Flag in a tricky way that happens to -/// improve scheduling in some cases. -SDNode *X86DAGToDAGISel::getTruncateTo8Bit(SDValue N0) { - assert(!Subtarget->is64Bit() && - "getTruncateTo8Bit is only needed on x86-32!"); - SDValue SRIdx = CurDAG->getTargetConstant(X86::SUBREG_8BIT, MVT::i32); - DebugLoc dl = N0.getDebugLoc(); - - // Ensure that the source register has an 8-bit subreg on 32-bit targets - unsigned Opc; - MVT N0VT = N0.getValueType(); - switch (N0VT.getSimpleVT()) { - default: assert(0 && "Unknown truncate!"); - case MVT::i16: - Opc = X86::MOV16to16_; - break; - case MVT::i32: - Opc = X86::MOV32to32_; - break; - } - - // The use of MVT::Flag here is not strictly accurate, but it helps - // scheduling in some cases. - N0 = SDValue(CurDAG->getTargetNode(Opc, dl, N0VT, MVT::Flag, N0), 0); - return CurDAG->getTargetNode(X86::EXTRACT_SUBREG, dl, - MVT::i8, N0, SRIdx, N0.getValue(1)); -} - SDNode *X86DAGToDAGISel::SelectAtomic64(SDNode *Node, unsigned Opc) { SDValue Chain = Node->getOperand(0); SDValue In1 = Node->getOperand(1); @@ -1639,55 +1603,6 @@ return NULL; } - case ISD::SIGN_EXTEND_INREG: { - MVT SVT = cast(Node->getOperand(1))->getVT(); - if (SVT == MVT::i8 && !Subtarget->is64Bit()) { - SDValue N0 = Node->getOperand(0); - - SDValue TruncOp = SDValue(getTruncateTo8Bit(N0), 0); - unsigned Opc = 0; - switch (NVT.getSimpleVT()) { - default: assert(0 && "Unknown sign_extend_inreg!"); - case MVT::i16: - Opc = X86::MOVSX16rr8; - break; - case MVT::i32: - Opc = X86::MOVSX32rr8; - break; - } - - SDNode *ResNode = CurDAG->getTargetNode(Opc, dl, NVT, TruncOp); - -#ifndef NDEBUG - DOUT << std::string(Indent-2, ' ') << "=> "; - DEBUG(TruncOp.getNode()->dump(CurDAG)); - DOUT << "\n"; - DOUT << std::string(Indent-2, ' ') << "=> "; - DEBUG(ResNode->dump(CurDAG)); - DOUT << "\n"; - Indent -= 2; -#endif - return ResNode; - } - break; - } - - case ISD::TRUNCATE: { - if (NVT == MVT::i8 && !Subtarget->is64Bit()) { - SDValue Input = Node->getOperand(0); - SDNode *ResNode = getTruncateTo8Bit(Input); - -#ifndef NDEBUG - DOUT << std::string(Indent-2, ' ') << "=> "; - DEBUG(ResNode->dump(CurDAG)); - DOUT << "\n"; - Indent -= 2; -#endif - return ResNode; - } - break; - } - case ISD::DECLARE: { // Handle DECLARE nodes here because the second operand may have been // wrapped in X86ISD::Wrapper. From gohman at apple.com Mon Apr 13 10:38:05 2009 From: gohman at apple.com (Dan Gohman) Date: Mon, 13 Apr 2009 15:38:05 -0000 Subject: [llvm-commits] [llvm] r68961 - in /llvm/trunk: include/llvm/Target/Target.td include/llvm/Target/TargetInstrInfo.h include/llvm/Target/TargetRegisterInfo.h lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.h lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp utils/TableGen/CodeEmitterGen.cpp utils/TableGen/CodeGenDAGPatterns.cpp utils/TableGen/CodeGenTarget.cpp utils/TableGen/DAGISelEmitter.cpp utils/TableGen/InstrInfoEmitter.cpp utils/TableGen/RegisterInfoEmitter.cpp Message-ID: <200904131538.n3DFc5h6032744@zion.cs.uiuc.edu> Author: djg Date: Mon Apr 13 10:38:05 2009 New Revision: 68961 URL: http://llvm.org/viewvc/llvm-project?rev=68961&view=rev Log: Add a new TargetInstrInfo MachineInstr opcode, COPY_TO_SUBCLASS. This will be used to replace things like X86's MOV32to32_. Enhance ScheduleDAGSDNodesEmit to be more flexible and robust in the presense of subregister superclasses and subclasses. It can now cope with the definition of a virtual register being in a subclass of a use. Re-introduce the code for recording register superreg classes and subreg classes. This is needed because when subreg extracts and inserts get coalesced away, the virtual registers are left in the correct subclass. Modified: llvm/trunk/include/llvm/Target/Target.td llvm/trunk/include/llvm/Target/TargetInstrInfo.h llvm/trunk/include/llvm/Target/TargetRegisterInfo.h llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.h llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp llvm/trunk/utils/TableGen/CodeEmitterGen.cpp llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp llvm/trunk/utils/TableGen/CodeGenTarget.cpp llvm/trunk/utils/TableGen/DAGISelEmitter.cpp llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp Modified: llvm/trunk/include/llvm/Target/Target.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/Target.td?rev=68961&r1=68960&r2=68961&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/Target.td (original) +++ llvm/trunk/include/llvm/Target/Target.td Mon Apr 13 10:38:05 2009 @@ -400,6 +400,14 @@ let Namespace = "TargetInstrInfo"; let neverHasSideEffects = 1; } +def COPY_TO_SUBCLASS : Instruction { + let OutOperandList = (ops unknown:$dst); + let InOperandList = (ops unknown:$src, i32imm:$regclass); + let AsmString = ""; + let Namespace = "TargetInstrInfo"; + let neverHasSideEffects = 1; + let isAsCheapAsAMove = 1; +} //===----------------------------------------------------------------------===// // AsmWriter - This class can be implemented by targets that need to customize Modified: llvm/trunk/include/llvm/Target/TargetInstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetInstrInfo.h?rev=68961&r1=68960&r2=68961&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetInstrInfo.h (original) +++ llvm/trunk/include/llvm/Target/TargetInstrInfo.h Mon Apr 13 10:38:05 2009 @@ -73,7 +73,14 @@ /// is often zero, as is commonly used to implement zext operations on /// target architectures which support it, such as with x86-64 (with /// zext from i32 to i64 via implicit zero-extension). - SUBREG_TO_REG = 9 + SUBREG_TO_REG = 9, + + /// COPY_TO_SUBCLASS - This instruction is a placeholder for a plain + /// register-to-register copy into a specific register class. This is only + /// used between instruction selection and MachineInstr creation, before + /// virtual registers have been created for all the instructions. As with + /// normal copies, these may be optimized away by the coalescer. + COPY_TO_SUBCLASS = 10 }; unsigned getNumOpcodes() const { return NumOpcodes; } Modified: llvm/trunk/include/llvm/Target/TargetRegisterInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetRegisterInfo.h?rev=68961&r1=68960&r2=68961&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetRegisterInfo.h (original) +++ llvm/trunk/include/llvm/Target/TargetRegisterInfo.h Mon Apr 13 10:38:05 2009 @@ -62,6 +62,8 @@ const vt_iterator VTs; const sc_iterator SubClasses; const sc_iterator SuperClasses; + const sc_iterator SubRegClasses; + const sc_iterator SuperRegClasses; const unsigned RegSize, Alignment; // Size & Alignment of register in bytes const int CopyCost; const iterator RegsBegin, RegsEnd; @@ -72,9 +74,12 @@ const MVT *vts, const TargetRegisterClass * const *subcs, const TargetRegisterClass * const *supcs, + const TargetRegisterClass * const *subregcs, + const TargetRegisterClass * const *superregcs, unsigned RS, unsigned Al, int CC, iterator RB, iterator RE) : ID(id), Name(name), VTs(vts), SubClasses(subcs), SuperClasses(supcs), + SubRegClasses(subregcs), SuperRegClasses(superregcs), RegSize(RS), Alignment(Al), CopyCost(CC), RegsBegin(RB), RegsEnd(RE) { for (iterator I = RegsBegin, E = RegsEnd; I != E; ++I) RegSet.insert(*I); @@ -132,8 +137,32 @@ return I; } - /// hasSubClass - return true if the specified TargetRegisterClass is a - /// sub-register class of this TargetRegisterClass. + /// subregclasses_begin / subregclasses_end - Loop over all of + /// the subreg register classes of this register class. + sc_iterator subregclasses_begin() const { + return SubRegClasses; + } + + sc_iterator subregclasses_end() const { + sc_iterator I = SubRegClasses; + while (*I != NULL) ++I; + return I; + } + + /// superregclasses_begin / superregclasses_end - Loop over all of + /// the superreg register classes of this register class. + sc_iterator superregclasses_begin() const { + return SuperRegClasses; + } + + sc_iterator superregclasses_end() const { + sc_iterator I = SuperRegClasses; + while (*I != NULL) ++I; + return I; + } + + /// hasSubClass - return true if the the specified TargetRegisterClass + /// is a proper subset of this TargetRegisterClass. bool hasSubClass(const TargetRegisterClass *cs) const { for (int i = 0; SubClasses[i] != NULL; ++i) if (SubClasses[i] == cs) @@ -141,8 +170,8 @@ return false; } - /// subclasses_begin / subclasses_end - Loop over all of the sub-classes of - /// this register class. + /// subclasses_begin / subclasses_end - Loop over all of the classes + /// that are proper subsets of this register class. sc_iterator subclasses_begin() const { return SubClasses; } @@ -154,7 +183,7 @@ } /// hasSuperClass - return true if the specified TargetRegisterClass is a - /// super-register class of this TargetRegisterClass. + /// proper superset of this TargetRegisterClass. bool hasSuperClass(const TargetRegisterClass *cs) const { for (int i = 0; SuperClasses[i] != NULL; ++i) if (SuperClasses[i] == cs) @@ -162,8 +191,8 @@ return false; } - /// superclasses_begin / superclasses_end - Loop over all of the super-classes - /// of this register class. + /// superclasses_begin / superclasses_end - Loop over all of the classes + /// that are proper supersets of this register class. sc_iterator superclasses_begin() const { return SuperClasses; } @@ -174,8 +203,8 @@ return I; } - /// isASubClass - return true if this TargetRegisterClass is a sub-class of at - /// least one other TargetRegisterClass. + /// isASubClass - return true if this TargetRegisterClass is a subset + /// class of at least one other TargetRegisterClass. bool isASubClass() const { return SuperClasses[0] != 0; } Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.h?rev=68961&r1=68960&r2=68961&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.h (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.h Mon Apr 13 10:38:05 2009 @@ -134,6 +134,12 @@ void EmitSubregNode(SDNode *Node, DenseMap &VRBaseMap); + /// EmitCopyToSubclassNode - Generate machine code for COPY_TO_SUBCLASS + /// nodes. + /// + void EmitCopyToSubclassNode(SDNode *Node, + DenseMap &VRBaseMap); + /// getVR - Return the virtual register corresponding to the specified result /// of the specified node. unsigned getVR(SDValue Op, DenseMap &VRBaseMap); @@ -146,6 +152,13 @@ const TargetInstrDesc *II, DenseMap &VRBaseMap); + /// AddRegisterOperand - Add the specified register as an operand to the + /// specified machine instr. Insert register copies if the register is + /// not in the required register class. + void AddRegisterOperand(MachineInstr *MI, SDValue Op, + unsigned IIOpNum, const TargetInstrDesc *II, + DenseMap &VRBaseMap); + /// EmitCopyFromReg - Generate machine code for an CopyFromReg node or an /// implicit physical register output. void EmitCopyFromReg(SDNode *Node, unsigned ResNo, bool IsClone, Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp?rev=68961&r1=68960&r2=68961&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp Mon Apr 13 10:38:05 2009 @@ -93,9 +93,13 @@ getInstrOperandRegClass(TRI, II, i+II.getNumDefs()); if (!UseRC) UseRC = RC; - else if (RC) - assert(UseRC == RC && - "Multiple uses expecting different register classes!"); + else if (RC) { + if (UseRC->hasSuperClass(RC)) + UseRC = RC; + else + assert((UseRC == RC || RC->hasSuperClass(UseRC)) && + "Multiple uses expecting different register classes!"); + } } } } @@ -127,10 +131,14 @@ VRBase = MRI.createVirtualRegister(DstRC); bool Emitted = TII->copyRegToReg(*BB, InsertPos, VRBase, SrcReg, DstRC, SrcRC); - if (!Emitted) { - cerr << "Unable to issue a copy instruction!\n"; - abort(); - } + // If the target didn't handle the copy with different register + // classes and the destination is a subset of the source, + // try a normal same-RC copy. + if (!Emitted && DstRC->hasSuperClass(SrcRC)) + Emitted = TII->copyRegToReg(*BB, InsertPos, VRBase, SrcReg, + SrcRC, SrcRC); + + assert(Emitted && "Unable to issue a copy instruction!\n"); } SDValue Op(Node, ResNo); @@ -168,9 +176,10 @@ 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. + // is a vreg in the same register class, use the CopyToReg'd destination + // register instead of creating a new vreg. unsigned VRBase = 0; + const TargetRegisterClass *RC = getInstrOperandRegClass(TRI, II, i); if (!IsClone && !IsCloned) for (SDNode::use_iterator UI = Node->use_begin(), E = Node->use_end(); @@ -181,9 +190,12 @@ 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; + const TargetRegisterClass *RegRC = MRI.getRegClass(Reg); + if (RegRC == RC) { + VRBase = Reg; + MI->addOperand(MachineOperand::CreateReg(Reg, true)); + break; + } } } } @@ -191,7 +203,6 @@ // Create the result registers for this node and add the result regs to // the machine instruction. if (VRBase == 0) { - const TargetRegisterClass *RC = getInstrOperandRegClass(TRI, II, i); assert(RC && "Isn't a register operand!"); VRBase = MRI.createVirtualRegister(RC); MI->addOperand(MachineOperand::CreateReg(VRBase, true)); @@ -230,6 +241,52 @@ } +/// AddRegisterOperand - Add the specified register as an operand to the +/// specified machine instr. Insert register copies if the register is +/// not in the required register class. +void +ScheduleDAGSDNodes::AddRegisterOperand(MachineInstr *MI, SDValue Op, + unsigned IIOpNum, + const TargetInstrDesc *II, + DenseMap &VRBaseMap) { + 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); + assert(TargetRegisterInfo::isVirtualRegister(VReg) && "Not a vreg?"); + + const TargetInstrDesc &TID = MI->getDesc(); + bool isOptDef = IIOpNum < TID.getNumOperands() && + TID.OpInfo[IIOpNum].isOptionalDef(); + + // If the instruction requires a register in a different class, create + // a new virtual register and copy the value into it. + if (II) { + const TargetRegisterClass *SrcRC = + MRI.getRegClass(VReg); + const TargetRegisterClass *DstRC = + getInstrOperandRegClass(TRI, *II, IIOpNum); + assert((DstRC || (TID.isVariadic() && IIOpNum >= TID.getNumOperands())) && + "Don't have operand info for this instruction!"); + if (DstRC && SrcRC != DstRC && !SrcRC->hasSuperClass(DstRC)) { + unsigned NewVReg = MRI.createVirtualRegister(DstRC); + bool Emitted = TII->copyRegToReg(*BB, InsertPos, NewVReg, VReg, + DstRC, SrcRC); + // If the target didn't handle the copy with different register + // classes and the destination is a subset of the source, + // try a normal same-RC copy. + if (!Emitted && DstRC->hasSuperClass(SrcRC)) + Emitted = TII->copyRegToReg(*BB, InsertPos, NewVReg, VReg, + SrcRC, SrcRC); + assert(Emitted && "Unable to issue a copy instruction!\n"); + VReg = NewVReg; + } + } + + MI->addOperand(MachineOperand::CreateReg(VReg, isOptDef)); +} + /// 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 @@ -239,46 +296,7 @@ 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, *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 " << VRC->getName() - << " size = " << VRC->getSize() - << ", align = " << VRC->getAlignment() << "\n"; - cerr << "Expected RegClass " << RC->getName() - << " size = " << RC->getSize() - << ", align = " << RC->getAlignment() << "\n"; - cerr << "Fatal error, aborting.\n"; - abort(); - } - } -#endif + AddRegisterOperand(MI, Op, IIOpNum, II, VRBaseMap); } else if (ConstantSDNode *C = dyn_cast(Op)) { MI->addOperand(MachineOperand::CreateImm(C->getZExtValue())); } else if (ConstantFPSDNode *F = dyn_cast(Op)) { @@ -288,8 +306,8 @@ 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 (BasicBlockSDNode *BBNode = dyn_cast(Op)) { + MI->addOperand(MachineOperand::CreateMBB(BBNode->getBasicBlock())); } else if (FrameIndexSDNode *FI = dyn_cast(Op)) { MI->addOperand(MachineOperand::CreateFI(FI->getIndex())); } else if (JumpTableSDNode *JT = dyn_cast(Op)) { @@ -319,19 +337,35 @@ 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, *II, IIOpNum) && - "Don't have operand info for this instruction!"); - } - } + AddRegisterOperand(MI, Op, IIOpNum, II, VRBaseMap); + } +} + +/// 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. @@ -364,13 +398,15 @@ TII->get(TargetInstrInfo::EXTRACT_SUBREG)); // Figure out the register class to create for the destreg. - const TargetRegisterClass *SRC = TLI->getRegClassFor(Node->getValueType(0)); + 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 && + assert(SRC && DRC && (SRC == DRC || DRC->hasSubClass(SRC)) && "Source subregister and destination must have the same class"); #endif } else { @@ -389,6 +425,7 @@ 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(); @@ -397,7 +434,8 @@ if (VRBase) { TRC = MRI.getRegClass(VRBase); } else { - TRC = TLI->getRegClassFor(Node->getValueType(0)); + 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 } @@ -426,6 +464,39 @@ assert(isNew && "Node emitted out of order - early"); } +/// EmitCopyToSubclassNode - Generate machine code for COPY_TO_SUBCLASS nodes. +/// COPY_TO_SUBCLASS is just a normal copy, except that the destination +/// register is constrained to be in a particular register class. +/// +void +ScheduleDAGSDNodes::EmitCopyToSubclassNode(SDNode *Node, + DenseMap &VRBaseMap) { + unsigned VReg = getVR(Node->getOperand(0), VRBaseMap); + const TargetRegisterClass *SrcRC = MRI.getRegClass(VReg); + + unsigned DstRCIdx = cast(Node->getOperand(1))->getZExtValue(); + const TargetRegisterClass *DstRC = TRI->getRegClass(DstRCIdx); + + assert(SrcRC->hasSubClass(DstRC) && + "COPY_TO_SUBCLASS destination class is not a proper subclass!"); + + // Create the new VReg in the destination class and emit a copy. + unsigned NewVReg = MRI.createVirtualRegister(DstRC); + bool Emitted = TII->copyRegToReg(*BB, InsertPos, NewVReg, VReg, + DstRC, SrcRC); + // If the target didn't handle that, emit a plain copy. + if (!Emitted) + Emitted = TII->copyRegToReg(*BB, InsertPos, NewVReg, VReg, + SrcRC, SrcRC); + assert(Emitted && + "Unable to issue a copy instruction for a COPY_TO_SUBCLASS node!\n"); + + SDValue Op(Node, 0); + bool isNew = VRBaseMap.insert(std::make_pair(Op, NewVReg)).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 ScheduleDAGSDNodes::EmitNode(SDNode *Node, bool IsClone, bool IsCloned, @@ -442,6 +513,12 @@ return; } + // Handle COPY_TO_SUBCLASS specially. + if (Opc == TargetInstrInfo::COPY_TO_SUBCLASS) { + EmitCopyToSubclassNode(Node, VRBaseMap); + return; + } + if (Opc == TargetInstrInfo::IMPLICIT_DEF) // We want a unique VR for each IMPLICIT_DEF use. return; @@ -532,12 +609,17 @@ else DstTRC = TRI->getPhysicalRegisterRegClass(DestReg, Node->getOperand(1).getValueType()); + bool Emitted = TII->copyRegToReg(*BB, InsertPos, DestReg, SrcReg, DstTRC, SrcTRC); - if (!Emitted) { - cerr << "Unable to issue a copy instruction!\n"; - abort(); - } + // If the target didn't handle the copy with different register + // classes and the destination is a subset of the source, + // try a normal same-RC copy. + if (!Emitted && DstTRC->hasSubClass(SrcTRC)) + Emitted = TII->copyRegToReg(*BB, InsertPos, DestReg, SrcReg, + DstTRC, DstTRC); + + assert(Emitted && "Unable to issue a copy instruction!\n"); break; } case ISD::CopyFromReg: { Modified: llvm/trunk/utils/TableGen/CodeEmitterGen.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeEmitterGen.cpp?rev=68961&r1=68960&r2=68961&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/CodeEmitterGen.cpp (original) +++ llvm/trunk/utils/TableGen/CodeEmitterGen.cpp Mon Apr 13 10:38:05 2009 @@ -33,8 +33,9 @@ R->getName() == "EXTRACT_SUBREG" || R->getName() == "INSERT_SUBREG" || R->getName() == "IMPLICIT_DEF" || - R->getName() == "SUBREG_TO_REG") continue; - + R->getName() == "SUBREG_TO_REG" || + R->getName() == "COPY_TO_SUBCLASS") continue; + BitsInit *BI = R->getValueAsBitsInit("Inst"); unsigned numBits = BI->getNumBits(); @@ -109,7 +110,8 @@ R->getName() == "EXTRACT_SUBREG" || R->getName() == "INSERT_SUBREG" || R->getName() == "IMPLICIT_DEF" || - R->getName() == "SUBREG_TO_REG") { + R->getName() == "SUBREG_TO_REG" || + R->getName() == "COPY_TO_SUBCLASS") { o << " 0U,\n"; continue; } @@ -146,8 +148,9 @@ InstName == "EXTRACT_SUBREG" || InstName == "INSERT_SUBREG" || InstName == "IMPLICIT_DEF" || - InstName == "SUBREG_TO_REG") continue; - + InstName == "SUBREG_TO_REG" || + InstName == "COPY_TO_SUBCLASS") continue; + BitsInit *BI = R->getValueAsBitsInit("Inst"); const std::vector &Vals = R->getValues(); CodeGenInstruction &CGI = Target.getInstruction(InstName); Modified: llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp?rev=68961&r1=68960&r2=68961&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp (original) +++ llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp Mon Apr 13 10:38:05 2009 @@ -884,6 +884,12 @@ MadeChange = getChild(i)->ApplyTypeConstraints(TP, NotRegisters); MadeChange |= UpdateNodeType(MVT::isVoid, TP); return MadeChange; + } else if (getOperator()->getName() == "COPY_TO_SUBCLASS") { + bool MadeChange = false; + MadeChange |= getChild(0)->ApplyTypeConstraints(TP, NotRegisters); + MadeChange |= getChild(1)->ApplyTypeConstraints(TP, NotRegisters); + MadeChange |= UpdateNodeType(getChild(1)->getTypeNum(0), TP); + return MadeChange; } else if (const CodeGenIntrinsic *Int = getIntrinsicInfo(CDP)) { bool MadeChange = false; Modified: llvm/trunk/utils/TableGen/CodeGenTarget.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenTarget.cpp?rev=68961&r1=68960&r2=68961&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/CodeGenTarget.cpp (original) +++ llvm/trunk/utils/TableGen/CodeGenTarget.cpp Mon Apr 13 10:38:05 2009 @@ -344,7 +344,12 @@ if (I == Instructions.end()) throw "Could not find 'SUBREG_TO_REG' instruction!"; const CodeGenInstruction *SUBREG_TO_REG = &I->second; - + + I = getInstructions().find("COPY_TO_SUBCLASS"); + if (I == Instructions.end()) + throw "Could not find 'COPY_TO_SUBCLASS' instruction!"; + const CodeGenInstruction *COPY_TO_SUBCLASS = &I->second; + // Print out the rest of the instructions now. NumberedInstructions.push_back(PHI); NumberedInstructions.push_back(INLINEASM); @@ -356,6 +361,7 @@ NumberedInstructions.push_back(INSERT_SUBREG); NumberedInstructions.push_back(IMPLICIT_DEF); NumberedInstructions.push_back(SUBREG_TO_REG); + NumberedInstructions.push_back(COPY_TO_SUBCLASS); for (inst_iterator II = inst_begin(), E = inst_end(); II != E; ++II) if (&II->second != PHI && &II->second != INLINEASM && @@ -366,7 +372,8 @@ &II->second != EXTRACT_SUBREG && &II->second != INSERT_SUBREG && &II->second != IMPLICIT_DEF && - &II->second != SUBREG_TO_REG) + &II->second != SUBREG_TO_REG && + &II->second != COPY_TO_SUBCLASS) NumberedInstructions.push_back(&II->second); } Modified: llvm/trunk/utils/TableGen/DAGISelEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/DAGISelEmitter.cpp?rev=68961&r1=68960&r2=68961&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/DAGISelEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/DAGISelEmitter.cpp Mon Apr 13 10:38:05 2009 @@ -918,6 +918,15 @@ getEnumName(N->getTypeNum(0)) + ");"); NodeOps.push_back("Tmp" + utostr(ResNo)); return NodeOps; + } else if (DI->getDef()->isSubClassOf("RegisterClass")) { + // Handle a reference to a register class. This is used + // in COPY_TO_SUBREG instructions. + emitCode("SDValue Tmp" + utostr(ResNo) + + " = CurDAG->getTargetConstant(" + + getQualifiedName(DI->getDef()) + "RegClassID, " + + "MVT::i32);"); + NodeOps.push_back("Tmp" + utostr(ResNo)); + return NodeOps; } } else if (IntInit *II = dynamic_cast(N->getLeafValue())) { unsigned ResNo = TmpNo++; Modified: llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp?rev=68961&r1=68960&r2=68961&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp Mon Apr 13 10:38:05 2009 @@ -340,7 +340,8 @@ R->getName() != "EXTRACT_SUBREG" && R->getName() != "INSERT_SUBREG" && R->getName() != "IMPLICIT_DEF" && - R->getName() != "SUBREG_TO_REG") + R->getName() != "SUBREG_TO_REG" && + R->getName() != "COPY_TO_SUBCLASS") throw R->getName() + " doesn't have a field named '" + Val->getValue() + "'!"; return; Modified: llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp?rev=68961&r1=68960&r2=68961&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp Mon Apr 13 10:38:05 2009 @@ -240,8 +240,85 @@ << RegisterClasses[i].getName() << "RegClass;\n"; std::map > SuperClassMap; + std::map > SuperRegClassMap; OS << "\n"; + // Emit the sub-register classes for each RegisterClass + for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) { + const CodeGenRegisterClass &RC = RegisterClasses[rc]; + + // Give the register class a legal C name if it's anonymous. + std::string Name = RC.TheDef->getName(); + + OS << " // " << Name + << " Sub-register Classes...\n" + << " static const TargetRegisterClass* const " + << Name << "SubRegClasses [] = {\n "; + + bool Empty = true; + + for (unsigned subrc = 0, subrcMax = RC.SubRegClasses.size(); + subrc != subrcMax; ++subrc) { + unsigned rc2 = 0, e2 = RegisterClasses.size(); + for (; rc2 != e2; ++rc2) { + const CodeGenRegisterClass &RC2 = RegisterClasses[rc2]; + if (RC.SubRegClasses[subrc]->getName() == RC2.getName()) { + if (!Empty) + OS << ", "; + OS << "&" << getQualifiedName(RC2.TheDef) << "RegClass"; + Empty = false; + + std::map >::iterator SCMI = + SuperRegClassMap.find(rc2); + if (SCMI == SuperRegClassMap.end()) { + SuperRegClassMap.insert(std::make_pair(rc2, + std::set())); + SCMI = SuperRegClassMap.find(rc2); + } + SCMI->second.insert(rc); + break; + } + } + if (rc2 == e2) + throw "Register Class member '" + + RC.SubRegClasses[subrc]->getName() + + "' is not a valid RegisterClass!"; + } + + OS << (!Empty ? ", " : "") << "NULL"; + OS << "\n };\n\n"; + } + + // Emit the super-register classes for each RegisterClass + for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) { + const CodeGenRegisterClass &RC = RegisterClasses[rc]; + + // Give the register class a legal C name if it's anonymous. + std::string Name = RC.TheDef->getName(); + + OS << " // " << Name + << " Super-register Classes...\n" + << " static const TargetRegisterClass* const " + << Name << "SuperRegClasses [] = {\n "; + + bool Empty = true; + std::map >::iterator I = + SuperRegClassMap.find(rc); + if (I != SuperRegClassMap.end()) { + for (std::set::iterator II = I->second.begin(), + EE = I->second.end(); II != EE; ++II) { + const CodeGenRegisterClass &RC2 = RegisterClasses[*II]; + if (!Empty) + OS << ", "; + OS << "&" << getQualifiedName(RC2.TheDef) << "RegClass"; + Empty = false; + } + } + + OS << (!Empty ? ", " : "") << "NULL"; + OS << "\n };\n\n"; + } + // Emit the sub-classes array for each RegisterClass for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) { const CodeGenRegisterClass &RC = RegisterClasses[rc]; @@ -323,6 +400,8 @@ << RC.getName() + "VTs" << ", " << RC.getName() + "Subclasses" << ", " << RC.getName() + "Superclasses" << ", " + << RC.getName() + "SubRegClasses" << ", " + << RC.getName() + "SuperRegClasses" << ", " << RC.SpillSize/8 << ", " << RC.SpillAlignment/8 << ", " << RC.CopyCost << ", " From gohman at apple.com Mon Apr 13 11:09:41 2009 From: gohman at apple.com (Dan Gohman) Date: Mon, 13 Apr 2009 16:09:41 -0000 Subject: [llvm-commits] [llvm] r68962 - in /llvm/trunk: lib/Target/X86/X86FastISel.cpp lib/Target/X86/X86ISelDAGToDAG.cpp lib/Target/X86/X86Instr64bit.td lib/Target/X86/X86InstrInfo.cpp lib/Target/X86/X86InstrInfo.td lib/Target/X86/X86RegisterInfo.h lib/Target/X86/X86RegisterInfo.td test/CodeGen/X86/h-register-addressing-32.ll test/CodeGen/X86/h-register-addressing-64.ll test/CodeGen/X86/h-register-store.ll test/CodeGen/X86/h-registers.ll test/CodeGen/X86/inline-asm-out-regs.ll Message-ID: <200904131609.n3DG9gZs001452@zion.cs.uiuc.edu> Author: djg Date: Mon Apr 13 11:09:41 2009 New Revision: 68962 URL: http://llvm.org/viewvc/llvm-project?rev=68962&view=rev Log: Implement x86 h-register extract support. - Add patterns for h-register extract, which avoids a shift and mask, and in some cases a temporary register. - Add address-mode matching for turning (X>>(8-n))&(255<>C1)) << C1" if safe and if this - // allows us to fold the shift into this addressing mode. + // Perform some heroic transforms on an and of a constant-count shift + // with a constant to enable use of the scaled offset field. + SDValue Shift = N.getOperand(0); - if (Shift.getOpcode() != ISD::SHL) break; + if (Shift.getNumOperands() != 2) break; // Scale must not be used already. if (AM.IndexReg.getNode() != 0 || AM.Scale != 1) break; // Not when RIP is used as the base. if (AM.isRIPRel) break; - + + SDValue X = Shift.getOperand(0); ConstantSDNode *C2 = dyn_cast(N.getOperand(1)); ConstantSDNode *C1 = dyn_cast(Shift.getOperand(1)); if (!C1 || !C2) break; + // Handle "(X >> (8-C1)) & C2" as "(X >> 8) & 0xff)" if safe. This + // allows us to convert the shift and and into an h-register extract and + // a scaled index. + if (Shift.getOpcode() == ISD::SRL && Shift.hasOneUse()) { + unsigned ScaleLog = 8 - C1->getZExtValue(); + if (ScaleLog > 0 && ScaleLog < 64 && + C2->getZExtValue() == (UINT64_C(0xff) << ScaleLog)) { + SDValue Eight = CurDAG->getConstant(8, MVT::i8); + SDValue Mask = CurDAG->getConstant(0xff, N.getValueType()); + SDValue Srl = CurDAG->getNode(ISD::SRL, dl, N.getValueType(), + X, Eight); + SDValue And = CurDAG->getNode(ISD::AND, dl, N.getValueType(), + Srl, Mask); + + // Insert the new nodes into the topological ordering. + if (Eight.getNode()->getNodeId() == -1 || + Eight.getNode()->getNodeId() > X.getNode()->getNodeId()) { + CurDAG->RepositionNode(X.getNode(), Eight.getNode()); + Eight.getNode()->setNodeId(X.getNode()->getNodeId()); + } + if (Mask.getNode()->getNodeId() == -1 || + Mask.getNode()->getNodeId() > X.getNode()->getNodeId()) { + CurDAG->RepositionNode(X.getNode(), Mask.getNode()); + Mask.getNode()->setNodeId(X.getNode()->getNodeId()); + } + if (Srl.getNode()->getNodeId() == -1 || + Srl.getNode()->getNodeId() > Shift.getNode()->getNodeId()) { + CurDAG->RepositionNode(Shift.getNode(), Srl.getNode()); + Srl.getNode()->setNodeId(Shift.getNode()->getNodeId()); + } + if (And.getNode()->getNodeId() == -1 || + And.getNode()->getNodeId() > N.getNode()->getNodeId()) { + CurDAG->RepositionNode(N.getNode(), And.getNode()); + And.getNode()->setNodeId(N.getNode()->getNodeId()); + } + CurDAG->ReplaceAllUsesWith(N, And); + AM.IndexReg = And; + AM.Scale = (1 << ScaleLog); + return false; + } + } + + // Handle "(X << C1) & C2" as "(X & (C2>>C1)) << C1" if safe and if this + // allows us to fold the shift into this addressing mode. + if (Shift.getOpcode() != ISD::SHL) break; + // Not likely to be profitable if either the AND or SHIFT node has more // than one use (unless all uses are for address computation). Besides, // isel mechanism requires their node ids to be reused. @@ -1046,7 +1094,6 @@ break; // Get the new AND mask, this folds to a constant. - SDValue X = Shift.getOperand(0); SDValue NewANDMask = CurDAG->getNode(ISD::SRL, dl, N.getValueType(), SDValue(C2, 0), SDValue(C1, 0)); SDValue NewAND = CurDAG->getNode(ISD::AND, dl, N.getValueType(), X, Modified: llvm/trunk/lib/Target/X86/X86Instr64bit.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Instr64bit.td?rev=68962&r1=68961&r2=68962&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86Instr64bit.td (original) +++ llvm/trunk/lib/Target/X86/X86Instr64bit.td Mon Apr 13 11:09:41 2009 @@ -1522,7 +1522,7 @@ // r & (2^32-1) ==> movz def : Pat<(and GR64:$src, 0x00000000FFFFFFFF), - (MOVZX64rr32 (i32 (EXTRACT_SUBREG GR64:$src, x86_subreg_32bit)))>; + (MOVZX64rr32 (EXTRACT_SUBREG GR64:$src, x86_subreg_32bit))>; // r & (2^16-1) ==> movz def : Pat<(and GR64:$src, 0xffff), (MOVZX64rr16 (i16 (EXTRACT_SUBREG GR64:$src, x86_subreg_16bit)))>; @@ -1531,7 +1531,7 @@ (MOVZX64rr8 (i8 (EXTRACT_SUBREG GR64:$src, x86_subreg_8bit)))>; // r & (2^8-1) ==> movz def : Pat<(and GR32:$src1, 0xff), - (MOVZX32rr8 (i8 (EXTRACT_SUBREG GR32:$src1, x86_subreg_8bit)))>, + (MOVZX32rr8 (EXTRACT_SUBREG GR32:$src1, x86_subreg_8bit))>, Requires<[In64BitMode]>; // r & (2^8-1) ==> movz def : Pat<(and GR16:$src1, 0xff), @@ -1540,13 +1540,13 @@ // sext_inreg patterns def : Pat<(sext_inreg GR64:$src, i32), - (MOVSX64rr32 (i32 (EXTRACT_SUBREG GR64:$src, x86_subreg_32bit)))>; + (MOVSX64rr32 (EXTRACT_SUBREG GR64:$src, x86_subreg_32bit))>; def : Pat<(sext_inreg GR64:$src, i16), - (MOVSX64rr16 (i16 (EXTRACT_SUBREG GR64:$src, x86_subreg_16bit)))>; + (MOVSX64rr16 (EXTRACT_SUBREG GR64:$src, x86_subreg_16bit))>; def : Pat<(sext_inreg GR64:$src, i8), - (MOVSX64rr8 (i8 (EXTRACT_SUBREG GR64:$src, x86_subreg_8bit)))>; + (MOVSX64rr8 (EXTRACT_SUBREG GR64:$src, x86_subreg_8bit))>; def : Pat<(sext_inreg GR32:$src, i8), - (MOVSX32rr8 (i8 (EXTRACT_SUBREG GR32:$src, x86_subreg_8bit)))>, + (MOVSX32rr8 (EXTRACT_SUBREG GR32:$src, x86_subreg_8bit))>, Requires<[In64BitMode]>; def : Pat<(sext_inreg GR16:$src, i8), (MOVSX16rr8 (i8 (EXTRACT_SUBREG GR16:$src, x86_subreg_8bit)))>, @@ -1554,16 +1554,63 @@ // trunc patterns def : Pat<(i32 (trunc GR64:$src)), - (i32 (EXTRACT_SUBREG GR64:$src, x86_subreg_32bit))>; + (EXTRACT_SUBREG GR64:$src, x86_subreg_32bit)>; def : Pat<(i16 (trunc GR64:$src)), - (i16 (EXTRACT_SUBREG GR64:$src, x86_subreg_16bit))>; + (EXTRACT_SUBREG GR64:$src, x86_subreg_16bit)>; def : Pat<(i8 (trunc GR64:$src)), - (i8 (EXTRACT_SUBREG GR64:$src, x86_subreg_8bit))>; + (EXTRACT_SUBREG GR64:$src, x86_subreg_8bit)>; def : Pat<(i8 (trunc GR32:$src)), - (i8 (EXTRACT_SUBREG GR32:$src, x86_subreg_8bit))>, + (EXTRACT_SUBREG GR32:$src, x86_subreg_8bit)>, Requires<[In64BitMode]>; def : Pat<(i8 (trunc GR16:$src)), - (i8 (EXTRACT_SUBREG GR16:$src, x86_subreg_8bit))>, + (EXTRACT_SUBREG GR16:$src, x86_subreg_8bit)>, + Requires<[In64BitMode]>; + +// h-register tricks. +// For now, be conservative and only the extract if the value is immediately +// zero-extended or stored, which are somewhat common cases. This uses a bunch +// of code to prevent a register requiring a REX prefix from being allocated in +// the same instruction as the h register, as there's currently no way to +// describe this requirement to the register allocator. + +// h-register extract and zero-extend. +def : Pat<(and (srl_su GR64:$src, (i8 8)), (i64 255)), + (SUBREG_TO_REG + (i64 0), + (MOVZX32_NOREXrr8 + (EXTRACT_SUBREG (COPY_TO_SUBCLASS GR64:$src, GR64_), + x86_subreg_8bit_hi)), + x86_subreg_32bit)>; +def : Pat<(and (srl_su GR32:$src, (i8 8)), (i32 255)), + (MOVZX32_NOREXrr8 + (EXTRACT_SUBREG (COPY_TO_SUBCLASS GR32:$src, GR32_), + x86_subreg_8bit_hi))>, + Requires<[In64BitMode]>; +def : Pat<(srl_su GR16:$src, (i8 8)), + (EXTRACT_SUBREG + (MOVZX32_NOREXrr8 + (EXTRACT_SUBREG (COPY_TO_SUBCLASS GR16:$src, GR16_), + x86_subreg_8bit_hi)), + x86_subreg_16bit)>, + Requires<[In64BitMode]>; + +// h-register extract and store. +def : Pat<(store (i8 (trunc_su (srl_su GR64:$src, (i8 8)))), addr:$dst), + (MOV8mr_NOREX + addr:$dst, + (EXTRACT_SUBREG (COPY_TO_SUBCLASS GR64:$src, GR64_), + x86_subreg_8bit_hi))>; +def : Pat<(store (i8 (trunc_su (srl_su GR32:$src, (i8 8)))), addr:$dst), + (MOV8mr_NOREX + addr:$dst, + (EXTRACT_SUBREG (COPY_TO_SUBCLASS GR32:$src, GR32_), + x86_subreg_8bit_hi))>, + Requires<[In64BitMode]>; +def : Pat<(store (i8 (trunc_su (srl_su GR16:$src, (i8 8)))), addr:$dst), + (MOV8mr_NOREX + addr:$dst, + (EXTRACT_SUBREG (COPY_TO_SUBCLASS GR16:$src, GR16_), + x86_subreg_8bit_hi))>, Requires<[In64BitMode]>; // (shl x, 1) ==> (add x, x) Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=68962&r1=68961&r2=68962&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Mon Apr 13 11:09:41 2009 @@ -258,10 +258,8 @@ { X86::JMP64r, X86::JMP64m, 1 }, { X86::MOV16ri, X86::MOV16mi, 0 }, { X86::MOV16rr, X86::MOV16mr, 0 }, - { X86::MOV16to16_, X86::MOV16_mr, 0 }, { X86::MOV32ri, X86::MOV32mi, 0 }, { X86::MOV32rr, X86::MOV32mr, 0 }, - { X86::MOV32to32_, X86::MOV32_mr, 0 }, { X86::MOV64ri32, X86::MOV64mi32, 0 }, { X86::MOV64rr, X86::MOV64mr, 0 }, { X86::MOV8ri, X86::MOV8mi, 0 }, @@ -372,9 +370,7 @@ { X86::Int_UCOMISDrr, X86::Int_UCOMISDrm }, { X86::Int_UCOMISSrr, X86::Int_UCOMISSrm }, { X86::MOV16rr, X86::MOV16rm }, - { X86::MOV16to16_, X86::MOV16_rm }, { X86::MOV32rr, X86::MOV32rm }, - { X86::MOV32to32_, X86::MOV32_rm }, { X86::MOV64rr, X86::MOV64rm }, { X86::MOV64toPQIrr, X86::MOVQI2PQIrm }, { X86::MOV64toSDrr, X86::MOV64toSDrm }, @@ -404,6 +400,7 @@ { X86::MOVZPQILo2PQIrr, X86::MOVZPQILo2PQIrm }, { X86::MOVZX16rr8, X86::MOVZX16rm8 }, { X86::MOVZX32rr16, X86::MOVZX32rm16 }, + { X86::MOVZX32_NOREXrr8, X86::MOVZX32_NOREXrm8 }, { X86::MOVZX32rr8, X86::MOVZX32rm8 }, { X86::MOVZX64rr16, X86::MOVZX64rm16 }, { X86::MOVZX64rr32, X86::MOVZX64rm32 }, @@ -672,8 +669,6 @@ case X86::MOV16rr: case X86::MOV32rr: case X86::MOV64rr: - case X86::MOV16to16_: - case X86::MOV32to32_: case X86::MOVSSrr: case X86::MOVSDrr: @@ -710,9 +705,7 @@ default: break; case X86::MOV8rm: case X86::MOV16rm: - case X86::MOV16_rm: case X86::MOV32rm: - case X86::MOV32_rm: case X86::MOV64rm: case X86::LD_Fp64m: case X86::MOVSSrm: @@ -741,9 +734,7 @@ default: break; case X86::MOV8mr: case X86::MOV16mr: - case X86::MOV16_mr: case X86::MOV32mr: - case X86::MOV32_mr: case X86::MOV64mr: case X86::ST_FpP64m: case X86::MOVSSmr: @@ -795,9 +786,7 @@ default: break; case X86::MOV8rm: case X86::MOV16rm: - case X86::MOV16_rm: case X86::MOV32rm: - case X86::MOV32_rm: case X86::MOV64rm: case X86::LD_Fp64m: case X86::MOVSSrm: @@ -1670,10 +1659,22 @@ Opc = X86::MOV16rr; } else if (DestRC == &X86::GR8RegClass) { Opc = X86::MOV8rr; + } else if (DestRC == &X86::GR64_RegClass) { + Opc = X86::MOV64rr; } else if (DestRC == &X86::GR32_RegClass) { - Opc = X86::MOV32_rr; + Opc = X86::MOV32rr; } else if (DestRC == &X86::GR16_RegClass) { - Opc = X86::MOV16_rr; + Opc = X86::MOV16rr; + } else if (DestRC == &X86::GR8_RegClass) { + Opc = X86::MOV8rr; + } else if (DestRC == &X86::GR64_NOREXRegClass) { + Opc = X86::MOV64rr; + } else if (DestRC == &X86::GR32_NOREXRegClass) { + Opc = X86::MOV32rr; + } else if (DestRC == &X86::GR16_NOREXRegClass) { + Opc = X86::MOV16rr; + } else if (DestRC == &X86::GR8_NOREXRegClass) { + Opc = X86::MOV8rr; } else if (DestRC == &X86::RFP32RegClass) { Opc = X86::MOV_Fp3232; } else if (DestRC == &X86::RFP64RegClass || DestRC == &X86::RSTRegClass) { @@ -1721,7 +1722,7 @@ return true; } } - + // Moving from ST(0) turns into FpGET_ST0_32 etc. if (SrcRC == &X86::RSTRegClass) { // Copying from ST(0)/ST(1). @@ -1779,10 +1780,22 @@ Opc = X86::MOV16mr; } else if (RC == &X86::GR8RegClass) { Opc = X86::MOV8mr; + } else if (RC == &X86::GR64_RegClass) { + Opc = X86::MOV64mr; } else if (RC == &X86::GR32_RegClass) { - Opc = X86::MOV32_mr; + Opc = X86::MOV32mr; } else if (RC == &X86::GR16_RegClass) { - Opc = X86::MOV16_mr; + Opc = X86::MOV16mr; + } else if (RC == &X86::GR8_RegClass) { + Opc = X86::MOV8mr; + } else if (RC == &X86::GR64_NOREXRegClass) { + Opc = X86::MOV64mr; + } else if (RC == &X86::GR32_NOREXRegClass) { + Opc = X86::MOV32mr; + } else if (RC == &X86::GR16_NOREXRegClass) { + Opc = X86::MOV16mr; + } else if (RC == &X86::GR8_NOREXRegClass) { + Opc = X86::MOV8mr; } else if (RC == &X86::RFP80RegClass) { Opc = X86::ST_FpP80m; // pops } else if (RC == &X86::RFP64RegClass) { @@ -1847,10 +1860,22 @@ Opc = X86::MOV16rm; } else if (RC == &X86::GR8RegClass) { Opc = X86::MOV8rm; + } else if (RC == &X86::GR64_RegClass) { + Opc = X86::MOV64rm; } else if (RC == &X86::GR32_RegClass) { - Opc = X86::MOV32_rm; + Opc = X86::MOV32rm; } else if (RC == &X86::GR16_RegClass) { - Opc = X86::MOV16_rm; + Opc = X86::MOV16rm; + } else if (RC == &X86::GR8_RegClass) { + Opc = X86::MOV8rm; + } else if (RC == &X86::GR64_NOREXRegClass) { + Opc = X86::MOV64rm; + } else if (RC == &X86::GR32_NOREXRegClass) { + Opc = X86::MOV32rm; + } else if (RC == &X86::GR16_NOREXRegClass) { + Opc = X86::MOV16rm; + } else if (RC == &X86::GR8_NOREXRegClass) { + Opc = X86::MOV8rm; } else if (RC == &X86::RFP80RegClass) { Opc = X86::LD_Fp80m; } else if (RC == &X86::RFP64RegClass) { Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=68962&r1=68961&r2=68962&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Mon Apr 13 11:09:41 2009 @@ -181,6 +181,13 @@ def f80mem : X86MemOperand<"printf80mem">; def f128mem : X86MemOperand<"printf128mem">; +// A version of i8mem for use on x86-64 that uses GR64_NOREX instead of +// plain GR64, so that it doesn't potentially require a REX prefix. +def i8mem_NOREX : Operand { + let PrintMethod = "printi8mem"; + let MIOperandInfo = (ops GR64_NOREX, i8imm, GR64_NOREX, i32imm, i8imm); +} + def lea32mem : Operand { let PrintMethod = "printlea32mem"; let MIOperandInfo = (ops GR32, i8imm, GR32, i32imm); @@ -398,6 +405,14 @@ def and_su : PatFrag<(ops node:$lhs, node:$rhs), (and node:$lhs, node:$rhs), [{ return N->hasOneUse(); }]>; +// An 'srl' node with a single use. +def srl_su : PatFrag<(ops node:$lhs, node:$rhs), (srl node:$lhs, node:$rhs), [{ + return N->hasOneUse(); +}]>; +// An 'trunc' node with a single use. +def trunc_su : PatFrag<(ops node:$src), (trunc node:$src), [{ + return N->hasOneUse(); +}]>; // 'shld' and 'shrd' instruction patterns. Note that even though these have // the srl and shl in their patterns, the C++ code must still check for them, @@ -767,7 +782,12 @@ def MOV32mr : I<0x89, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src), "mov{l}\t{$src, $dst|$dst, $src}", [(store GR32:$src, addr:$dst)]>; - + +// A version of MOV8mr that uses i8mem_NOREX so that it can be used for +// storing h registers, which can't be encoded when a REX prefix is present. +def MOV8mr_NOREX : I<0x88, MRMDestMem, (outs), (ins i8mem_NOREX:$dst, GR8:$src), + "mov{b}\t{$src, $dst|$dst, $src} # NOREX", []>; + //===----------------------------------------------------------------------===// // Fixed-Register Multiplication and Division Instructions... // @@ -2899,6 +2919,18 @@ "movz{wl|x}\t{$src, $dst|$dst, $src}", [(set GR32:$dst, (zextloadi32i16 addr:$src))]>, TB; +// These are the same as the regular regular MOVZX32rr8 and MOVZX32rm8 +// except that they use GR32_NOREX for the output operand register class +// instead of GR32. This allows them to operate on h registers on x86-64. +def MOVZX32_NOREXrr8 : I<0xB6, MRMSrcReg, + (outs GR32_NOREX:$dst), (ins GR8:$src), + "movz{bl|x}\t{$src, $dst|$dst, $src} # NOREX", + []>, TB; +def MOVZX32_NOREXrm8 : I<0xB6, MRMSrcMem, + (outs GR32_NOREX:$dst), (ins i8mem:$src), + "movz{bl|x}\t{$src, $dst|$dst, $src} # NOREX", + []>, TB; + let neverHasSideEffects = 1 in { let Defs = [AX], Uses = [AL] in def CBW : I<0x98, RawFrm, (outs), (ins), @@ -2935,33 +2967,6 @@ [(set GR32:$dst, 0)]>; } -// Basic operations on GR16 / GR32 subclasses GR16_ and GR32_ which contains only -// those registers that have GR8 sub-registers (i.e. AX - DX, EAX - EDX). -let neverHasSideEffects = 1, isAsCheapAsAMove = 1 in { -def MOV16to16_ : I<0x89, MRMDestReg, (outs GR16_:$dst), (ins GR16:$src), - "mov{w}\t{$src, $dst|$dst, $src}", []>, OpSize; -def MOV32to32_ : I<0x89, MRMDestReg, (outs GR32_:$dst), (ins GR32:$src), - "mov{l}\t{$src, $dst|$dst, $src}", []>; - -def MOV16_rr : I<0x89, MRMDestReg, (outs GR16_:$dst), (ins GR16_:$src), - "mov{w}\t{$src, $dst|$dst, $src}", []>, OpSize; -def MOV32_rr : I<0x89, MRMDestReg, (outs GR32_:$dst), (ins GR32_:$src), - "mov{l}\t{$src, $dst|$dst, $src}", []>; -} // neverHasSideEffects - -let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in { -def MOV16_rm : I<0x8B, MRMSrcMem, (outs GR16_:$dst), (ins i16mem:$src), - "mov{w}\t{$src, $dst|$dst, $src}", []>, OpSize; -def MOV32_rm : I<0x8B, MRMSrcMem, (outs GR32_:$dst), (ins i32mem:$src), - "mov{l}\t{$src, $dst|$dst, $src}", []>; -} -let mayStore = 1, neverHasSideEffects = 1 in { -def MOV16_mr : I<0x89, MRMDestMem, (outs), (ins i16mem:$dst, GR16_:$src), - "mov{w}\t{$src, $dst|$dst, $src}", []>, OpSize; -def MOV32_mr : I<0x89, MRMDestMem, (outs), (ins i32mem:$dst, GR32_:$src), - "mov{l}\t{$src, $dst|$dst, $src}", []>; -} - //===----------------------------------------------------------------------===// // Thread Local Storage Instructions // @@ -3341,38 +3346,61 @@ // r & (2^16-1) ==> movz def : Pat<(and GR32:$src1, 0xffff), - (MOVZX32rr16 (i16 (EXTRACT_SUBREG GR32:$src1, x86_subreg_16bit)))>; + (MOVZX32rr16 (EXTRACT_SUBREG GR32:$src1, x86_subreg_16bit))>; // r & (2^8-1) ==> movz def : Pat<(and GR32:$src1, 0xff), - (MOVZX32rr8 (i8 (EXTRACT_SUBREG (MOV32to32_ GR32:$src1), - x86_subreg_8bit)))>, + (MOVZX32rr8 (EXTRACT_SUBREG (COPY_TO_SUBCLASS GR32:$src1, GR32_), + x86_subreg_8bit))>, Requires<[In32BitMode]>; // r & (2^8-1) ==> movz def : Pat<(and GR16:$src1, 0xff), - (MOVZX16rr8 (i8 (EXTRACT_SUBREG (MOV16to16_ GR16:$src1), - x86_subreg_8bit)))>, + (MOVZX16rr8 (EXTRACT_SUBREG (COPY_TO_SUBCLASS GR16:$src1, GR16_), + x86_subreg_8bit))>, Requires<[In32BitMode]>; // sext_inreg patterns def : Pat<(sext_inreg GR32:$src, i16), - (MOVSX32rr16 (i16 (EXTRACT_SUBREG GR32:$src, x86_subreg_16bit)))>; + (MOVSX32rr16 (EXTRACT_SUBREG GR32:$src, x86_subreg_16bit))>; def : Pat<(sext_inreg GR32:$src, i8), - (MOVSX32rr8 (i8 (EXTRACT_SUBREG (MOV32to32_ GR32:$src), - x86_subreg_8bit)))>, + (MOVSX32rr8 (EXTRACT_SUBREG (COPY_TO_SUBCLASS GR32:$src, GR32_), + x86_subreg_8bit))>, Requires<[In32BitMode]>; def : Pat<(sext_inreg GR16:$src, i8), - (MOVSX16rr8 (i8 (EXTRACT_SUBREG (MOV16to16_ GR16:$src), - x86_subreg_8bit)))>, + (MOVSX16rr8 (EXTRACT_SUBREG (COPY_TO_SUBCLASS GR16:$src, GR16_), + x86_subreg_8bit))>, Requires<[In32BitMode]>; // trunc patterns def : Pat<(i16 (trunc GR32:$src)), - (i16 (EXTRACT_SUBREG GR32:$src, x86_subreg_16bit))>; + (EXTRACT_SUBREG GR32:$src, x86_subreg_16bit)>; def : Pat<(i8 (trunc GR32:$src)), - (i8 (EXTRACT_SUBREG (MOV32to32_ GR32:$src), x86_subreg_8bit))>, + (EXTRACT_SUBREG (COPY_TO_SUBCLASS GR32:$src, GR32_), + x86_subreg_8bit)>, Requires<[In32BitMode]>; def : Pat<(i8 (trunc GR16:$src)), - (i8 (EXTRACT_SUBREG (MOV16to16_ GR16:$src), x86_subreg_8bit))>, + (EXTRACT_SUBREG (COPY_TO_SUBCLASS GR16:$src, GR16_), + x86_subreg_8bit)>, + Requires<[In32BitMode]>; + +// h-register tricks +def : Pat<(i8 (trunc (srl_su GR16:$src, (i8 8)))), + (EXTRACT_SUBREG (COPY_TO_SUBCLASS GR16:$src, GR16_), + x86_subreg_8bit_hi)>, + Requires<[In32BitMode]>; +def : Pat<(i8 (trunc (srl_su GR32:$src, (i8 8)))), + (EXTRACT_SUBREG (COPY_TO_SUBCLASS GR32:$src, GR32_), + x86_subreg_8bit_hi)>, + Requires<[In32BitMode]>; +def : Pat<(srl_su GR16:$src, (i8 8)), + (EXTRACT_SUBREG + (MOVZX32rr8 + (EXTRACT_SUBREG (COPY_TO_SUBCLASS GR16:$src, GR16_), + x86_subreg_8bit_hi)), + x86_subreg_16bit)>, + Requires<[In32BitMode]>; +def : Pat<(and (srl_su GR32:$src, (i8 8)), (i32 255)), + (MOVZX32rr8 (EXTRACT_SUBREG (COPY_TO_SUBCLASS GR32:$src, GR32_), + x86_subreg_8bit_hi))>, Requires<[In32BitMode]>; // (shl x, 1) ==> (add x, x) Modified: llvm/trunk/lib/Target/X86/X86RegisterInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86RegisterInfo.h?rev=68962&r1=68961&r2=68962&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86RegisterInfo.h (original) +++ llvm/trunk/lib/Target/X86/X86RegisterInfo.h Mon Apr 13 11:09:41 2009 @@ -35,7 +35,7 @@ /// these indices must be kept in sync with the class indices in the /// X86RegisterInfo.td file. enum SubregIndex { - SUBREG_8BIT = 1, SUBREG_16BIT = 2, SUBREG_32BIT = 3 + SUBREG_8BIT = 1, SUBREG_8BIT_HI = 2, SUBREG_16BIT = 3, SUBREG_32BIT = 4 }; } Modified: llvm/trunk/lib/Target/X86/X86RegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86RegisterInfo.td?rev=68962&r1=68961&r2=68962&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86RegisterInfo.td (original) +++ llvm/trunk/lib/Target/X86/X86RegisterInfo.td Mon Apr 13 11:09:41 2009 @@ -49,7 +49,8 @@ def R14B : Register<"r14b">, DwarfRegNum<[14, -2, -2]>; def R15B : Register<"r15b">, DwarfRegNum<[15, -2, -2]>; - // High registers X86-32 only + // High registers. On x86-64, these cannot be used in any instruction + // with a REX prefix. def AH : Register<"ah">, DwarfRegNum<[0, 0, 0]>; def DH : Register<"dh">, DwarfRegNum<[1, 2, 2]>; def CH : Register<"ch">, DwarfRegNum<[2, 1, 1]>; @@ -185,41 +186,45 @@ // def x86_subreg_8bit : PatLeaf<(i32 1)>; -def x86_subreg_16bit : PatLeaf<(i32 2)>; -def x86_subreg_32bit : PatLeaf<(i32 3)>; +def x86_subreg_8bit_hi : PatLeaf<(i32 2)>; +def x86_subreg_16bit : PatLeaf<(i32 3)>; +def x86_subreg_32bit : PatLeaf<(i32 4)>; def : SubRegSet<1, [AX, CX, DX, BX, SP, BP, SI, DI, R8W, R9W, R10W, R11W, R12W, R13W, R14W, R15W], [AL, CL, DL, BL, SPL, BPL, SIL, DIL, R8B, R9B, R10B, R11B, R12B, R13B, R14B, R15B]>; -// It's unclear if this subreg set is safe, given that not all registers -// in the class have an 'H' subreg. -// def : SubRegSet<2, [AX, CX, DX, BX], -// [AH, CH, DH, BH]>; +def : SubRegSet<2, [AX, CX, DX, BX], + [AH, CH, DH, BH]>; def : SubRegSet<1, [EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI, R8D, R9D, R10D, R11D, R12D, R13D, R14D, R15D], [AL, CL, DL, BL, SPL, BPL, SIL, DIL, R8B, R9B, R10B, R11B, R12B, R13B, R14B, R15B]>; -def : SubRegSet<2, [EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI, +def : SubRegSet<2, [EAX, ECX, EDX, EBX], + [AH, CH, DH, BH]>; + +def : SubRegSet<3, [EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI, R8D, R9D, R10D, R11D, R12D, R13D, R14D, R15D], [AX, CX, DX, BX, SP, BP, SI, DI, R8W, R9W, R10W, R11W, R12W, R13W, R14W, R15W]>; - def : SubRegSet<1, [RAX, RCX, RDX, RBX, RSP, RBP, RSI, RDI, R8, R9, R10, R11, R12, R13, R14, R15], [AL, CL, DL, BL, SPL, BPL, SIL, DIL, R8B, R9B, R10B, R11B, R12B, R13B, R14B, R15B]>; -def : SubRegSet<2, [RAX, RCX, RDX, RBX, RSP, RBP, RSI, RDI, +def : SubRegSet<2, [RAX, RCX, RDX, RBX], + [AH, CH, DH, BH]>; + +def : SubRegSet<3, [RAX, RCX, RDX, RBX, RSP, RBP, RSI, RDI, R8, R9, R10, R11, R12, R13, R14, R15], [AX, CX, DX, BX, SP, BP, SI, DI, R8W, R9W, R10W, R11W, R12W, R13W, R14W, R15W]>; - -def : SubRegSet<3, [RAX, RCX, RDX, RBX, RSP, RBP, RSI, RDI, + +def : SubRegSet<4, [RAX, RCX, RDX, RBX, RSP, RBP, RSI, RDI, R8, R9, R10, R11, R12, R13, R14, R15], [EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI, R8D, R9D, R10D, R11D, R12D, R13D, R14D, R15D]>; @@ -236,7 +241,11 @@ // 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, +// FIXME: Allow AH, CH, DH, BH to be used as general-purpose registers in +// 64-bit mode. The main complication is that they cannot be encoded in an +// instruction requiring a REX prefix, while SIL, DIL, BPL, R8D, etc. +// require a REX prefix. For example, "addb %ah, %dil" and "movzbl %ah, %r8d" +// cannot be encoded. def GR8 : RegisterClass<"X86", [i8], 8, [AL, CL, DL, BL, AH, CH, DH, BH, SIL, DIL, BPL, SPL, R8B, R9B, R10B, R11B, R14B, R15B, R12B, R13B]> { @@ -295,7 +304,7 @@ def GR16 : RegisterClass<"X86", [i16], 16, [AX, CX, DX, SI, DI, BX, BP, SP, R8W, R9W, R10W, R11W, R14W, R15W, R12W, R13W]> { - let SubRegClassList = [GR8]; + let SubRegClassList = [GR8, GR8]; let MethodProtos = [{ iterator allocation_order_begin(const MachineFunction &MF) const; iterator allocation_order_end(const MachineFunction &MF) const; @@ -363,7 +372,7 @@ def GR32 : RegisterClass<"X86", [i32], 32, [EAX, ECX, EDX, ESI, EDI, EBX, EBP, ESP, R8D, R9D, R10D, R11D, R14D, R15D, R12D, R13D]> { - let SubRegClassList = [GR8, GR16]; + let SubRegClassList = [GR8, GR8, GR16]; let MethodProtos = [{ iterator allocation_order_begin(const MachineFunction &MF) const; iterator allocation_order_end(const MachineFunction &MF) const; @@ -431,7 +440,7 @@ def GR64 : RegisterClass<"X86", [i64], 64, [RAX, RCX, RDX, RSI, RDI, R8, R9, R10, R11, RBX, R14, R15, R12, R13, RBP, RSP]> { - let SubRegClassList = [GR8, GR16, GR32]; + let SubRegClassList = [GR8, GR8, GR16, GR32]; let MethodProtos = [{ iterator allocation_order_end(const MachineFunction &MF) const; }]; @@ -452,13 +461,118 @@ } -// GR16, GR32 subclasses which contain registers that have GR8 sub-registers. -// These should only be used for 32-bit mode. +// GR8_, GR16_, GR32_, GR64_ - Subclasses of GR8, GR16, GR32, and GR64 +// which contain just the "a" "b", "c", and "d" registers. On x86-32, +// GR16_ and GR32_ are classes for registers that support 8-bit subreg +// operations. On x86-64, GR16_, GR32_, and GR64_ are classes for registers +// that support 8-bit h-register operations. +def GR8_ : RegisterClass<"X86", [i8], 8, [AL, CL, DL, BL]> { +} def GR16_ : RegisterClass<"X86", [i16], 16, [AX, CX, DX, BX]> { - let SubRegClassList = [GR8]; + let SubRegClassList = [GR8_, GR8_]; } def GR32_ : RegisterClass<"X86", [i32], 32, [EAX, ECX, EDX, EBX]> { - let SubRegClassList = [GR8, GR16]; + let SubRegClassList = [GR8_, GR8_, GR16_]; +} +def GR64_ : RegisterClass<"X86", [i64], 64, [RAX, RCX, RDX, RBX]> { + let SubRegClassList = [GR8_, GR8_, GR16_, GR32_]; +} + +// GR8_NOREX, GR16_NOREX, GR32_NOREX, GR64_NOREX - Subclasses of +// GR8, GR16, GR32, and GR64 which contain only the first 8 GPRs. +// On x86-64, GR64_NOREX, GR32_NOREX and GR16_NOREX are the classes +// of registers which do not by themselves require a REX prefix. +def GR8_NOREX : RegisterClass<"X86", [i8], 8, + [AL, CL, DL, SIL, DIL, BL, BPL, SPL]> { +} +def GR16_NOREX : RegisterClass<"X86", [i16], 16, + [AX, CX, DX, SI, DI, BX, BP, SP]> { + let SubRegClassList = [GR8_NOREX, GR8_NOREX]; +} +// GR32_NOREX - GR32 registers which do not require a REX prefix. +def GR32_NOREX : RegisterClass<"X86", [i32], 32, + [EAX, ECX, EDX, ESI, EDI, EBX, EBP, ESP]> { + let SubRegClassList = [GR8_NOREX, GR8_NOREX, GR16_NOREX]; + let MethodProtos = [{ + iterator allocation_order_begin(const MachineFunction &MF) const; + iterator allocation_order_end(const MachineFunction &MF) const; + }]; + let MethodBodies = [{ + // Does the function dedicate RBP / EBP to being a frame ptr? + // If so, don't allocate ESP or EBP. + static const unsigned X86_GR32_NOREX_AO_fp[] = { + X86::EAX, X86::ECX, X86::EDX, X86::ESI, X86::EDI, X86::EBX + }; + // If not, just don't allocate ESP. + static const unsigned X86_GR32_NOREX_AO[] = { + X86::EAX, X86::ECX, X86::EDX, X86::ESI, X86::EDI, X86::EBX, X86::EBP + }; + + GR32_NOREXClass::iterator + GR32_NOREXClass::allocation_order_begin(const MachineFunction &MF) const { + const TargetMachine &TM = MF.getTarget(); + const TargetRegisterInfo *RI = TM.getRegisterInfo(); + if (RI->hasFP(MF)) + return X86_GR32_NOREX_AO_fp; + else + return X86_GR32_NOREX_AO; + } + + GR32_NOREXClass::iterator + GR32_NOREXClass::allocation_order_end(const MachineFunction &MF) const { + const TargetMachine &TM = MF.getTarget(); + const TargetRegisterInfo *RI = TM.getRegisterInfo(); + if (RI->hasFP(MF)) + return X86_GR32_NOREX_AO_fp + + (sizeof(X86_GR32_NOREX_AO_fp) / sizeof(unsigned)); + else + return X86_GR32_NOREX_AO + + (sizeof(X86_GR32_NOREX_AO) / sizeof(unsigned)); + } + }]; +} + +// GR64_NOREX - GR64 registers which do not require a REX prefix. +def GR64_NOREX : RegisterClass<"X86", [i64], 64, + [RAX, RCX, RDX, RSI, RDI, RBX, RBP, RSP]> { + let SubRegClassList = [GR8_NOREX, GR8_NOREX, GR16_NOREX, GR32_NOREX]; + let MethodProtos = [{ + iterator allocation_order_begin(const MachineFunction &MF) const; + iterator allocation_order_end(const MachineFunction &MF) const; + }]; + let MethodBodies = [{ + // Does the function dedicate RBP / EBP to being a frame ptr? + // If so, don't allocate RSP or RBP. + static const unsigned X86_GR64_NOREX_AO_fp[] = { + X86::RAX, X86::RCX, X86::RDX, X86::RSI, X86::RDI, X86::RBX + }; + // If not, just don't allocate RSP. + static const unsigned X86_GR64_NOREX_AO[] = { + X86::RAX, X86::RCX, X86::RDX, X86::RSI, X86::RDI, X86::RBX, X86::RBP + }; + + GR64_NOREXClass::iterator + GR64_NOREXClass::allocation_order_begin(const MachineFunction &MF) const { + const TargetMachine &TM = MF.getTarget(); + const TargetRegisterInfo *RI = TM.getRegisterInfo(); + if (RI->hasFP(MF)) + return X86_GR64_NOREX_AO_fp; + else + return X86_GR64_NOREX_AO; + } + + GR64_NOREXClass::iterator + GR64_NOREXClass::allocation_order_end(const MachineFunction &MF) const { + const TargetMachine &TM = MF.getTarget(); + const TargetRegisterInfo *RI = TM.getRegisterInfo(); + if (RI->hasFP(MF)) + return X86_GR64_NOREX_AO_fp + + (sizeof(X86_GR64_NOREX_AO_fp) / sizeof(unsigned)); + else + return X86_GR64_NOREX_AO + + (sizeof(X86_GR64_NOREX_AO) / sizeof(unsigned)); + } + }]; } // A class to support the 'A' assembler constraint: EAX then EDX. Added: llvm/trunk/test/CodeGen/X86/h-register-addressing-32.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/h-register-addressing-32.ll?rev=68962&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/h-register-addressing-32.ll (added) +++ llvm/trunk/test/CodeGen/X86/h-register-addressing-32.ll Mon Apr 13 11:09:41 2009 @@ -0,0 +1,53 @@ +; RUN: llvm-as < %s | llc -march=x86 | grep {movzbl %\[abcd\]h,} | count 7 + +; Use h-register extract and zero-extend. + +define double @foo8(double* nocapture inreg %p, i32 inreg %x) nounwind readonly { + %t0 = lshr i32 %x, 8 + %t1 = and i32 %t0, 255 + %t2 = getelementptr double* %p, i32 %t1 + %t3 = load double* %t2, align 8 + ret double %t3 +} +define float @foo4(float* nocapture inreg %p, i32 inreg %x) nounwind readonly { + %t0 = lshr i32 %x, 8 + %t1 = and i32 %t0, 255 + %t2 = getelementptr float* %p, i32 %t1 + %t3 = load float* %t2, align 8 + ret float %t3 +} +define i16 @foo2(i16* nocapture inreg %p, i32 inreg %x) nounwind readonly { + %t0 = lshr i32 %x, 8 + %t1 = and i32 %t0, 255 + %t2 = getelementptr i16* %p, i32 %t1 + %t3 = load i16* %t2, align 8 + ret i16 %t3 +} +define i8 @foo1(i8* nocapture inreg %p, i32 inreg %x) nounwind readonly { + %t0 = lshr i32 %x, 8 + %t1 = and i32 %t0, 255 + %t2 = getelementptr i8* %p, i32 %t1 + %t3 = load i8* %t2, align 8 + ret i8 %t3 +} +define i8 @bar8(i8* nocapture inreg %p, i32 inreg %x) nounwind readonly { + %t0 = lshr i32 %x, 5 + %t1 = and i32 %t0, 2040 + %t2 = getelementptr i8* %p, i32 %t1 + %t3 = load i8* %t2, align 8 + ret i8 %t3 +} +define i8 @bar4(i8* nocapture inreg %p, i32 inreg %x) nounwind readonly { + %t0 = lshr i32 %x, 6 + %t1 = and i32 %t0, 1020 + %t2 = getelementptr i8* %p, i32 %t1 + %t3 = load i8* %t2, align 8 + ret i8 %t3 +} +define i8 @bar2(i8* nocapture inreg %p, i32 inreg %x) nounwind readonly { + %t0 = lshr i32 %x, 7 + %t1 = and i32 %t0, 510 + %t2 = getelementptr i8* %p, i32 %t1 + %t3 = load i8* %t2, align 8 + ret i8 %t3 +} Added: llvm/trunk/test/CodeGen/X86/h-register-addressing-64.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/h-register-addressing-64.ll?rev=68962&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/h-register-addressing-64.ll (added) +++ llvm/trunk/test/CodeGen/X86/h-register-addressing-64.ll Mon Apr 13 11:09:41 2009 @@ -0,0 +1,53 @@ +; RUN: llvm-as < %s | llc -march=x86-64 | grep {movzbl %\[abcd\]h,} | count 7 + +; Use h-register extract and zero-extend. + +define double @foo8(double* nocapture inreg %p, i64 inreg %x) nounwind readonly { + %t0 = lshr i64 %x, 8 + %t1 = and i64 %t0, 255 + %t2 = getelementptr double* %p, i64 %t1 + %t3 = load double* %t2, align 8 + ret double %t3 +} +define float @foo4(float* nocapture inreg %p, i64 inreg %x) nounwind readonly { + %t0 = lshr i64 %x, 8 + %t1 = and i64 %t0, 255 + %t2 = getelementptr float* %p, i64 %t1 + %t3 = load float* %t2, align 8 + ret float %t3 +} +define i16 @foo2(i16* nocapture inreg %p, i64 inreg %x) nounwind readonly { + %t0 = lshr i64 %x, 8 + %t1 = and i64 %t0, 255 + %t2 = getelementptr i16* %p, i64 %t1 + %t3 = load i16* %t2, align 8 + ret i16 %t3 +} +define i8 @foo1(i8* nocapture inreg %p, i64 inreg %x) nounwind readonly { + %t0 = lshr i64 %x, 8 + %t1 = and i64 %t0, 255 + %t2 = getelementptr i8* %p, i64 %t1 + %t3 = load i8* %t2, align 8 + ret i8 %t3 +} +define i8 @bar8(i8* nocapture inreg %p, i64 inreg %x) nounwind readonly { + %t0 = lshr i64 %x, 5 + %t1 = and i64 %t0, 2040 + %t2 = getelementptr i8* %p, i64 %t1 + %t3 = load i8* %t2, align 8 + ret i8 %t3 +} +define i8 @bar4(i8* nocapture inreg %p, i64 inreg %x) nounwind readonly { + %t0 = lshr i64 %x, 6 + %t1 = and i64 %t0, 1020 + %t2 = getelementptr i8* %p, i64 %t1 + %t3 = load i8* %t2, align 8 + ret i8 %t3 +} +define i8 @bar2(i8* nocapture inreg %p, i64 inreg %x) nounwind readonly { + %t0 = lshr i64 %x, 7 + %t1 = and i64 %t0, 510 + %t2 = getelementptr i8* %p, i64 %t1 + %t3 = load i8* %t2, align 8 + ret i8 %t3 +} Added: llvm/trunk/test/CodeGen/X86/h-register-store.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/h-register-store.ll?rev=68962&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/h-register-store.ll (added) +++ llvm/trunk/test/CodeGen/X86/h-register-store.ll Mon Apr 13 11:09:41 2009 @@ -0,0 +1,27 @@ +; RUN: llvm-as < %s | llc -march=x86-64 > %t +; RUN: grep mov %t | count 6 +; RUN: grep {movb %ah, (%rsi)} %t | count 3 +; RUN: llvm-as < %s | llc -march=x86 > %t +; RUN: grep mov %t | count 3 +; RUN: grep {movb %ah, (%e} %t | count 3 + +; Use h-register extract and store. + +define void @foo16(i16 inreg %p, i8* inreg %z) nounwind { + %q = lshr i16 %p, 8 + %t = trunc i16 %q to i8 + store i8 %t, i8* %z + ret void +} +define void @foo32(i32 inreg %p, i8* inreg %z) nounwind { + %q = lshr i32 %p, 8 + %t = trunc i32 %q to i8 + store i8 %t, i8* %z + ret void +} +define void @foo64(i64 inreg %p, i8* inreg %z) nounwind { + %q = lshr i64 %p, 8 + %t = trunc i64 %q to i8 + store i8 %t, i8* %z + ret void +} Added: llvm/trunk/test/CodeGen/X86/h-registers.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/h-registers.ll?rev=68962&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/h-registers.ll (added) +++ llvm/trunk/test/CodeGen/X86/h-registers.ll Mon Apr 13 11:09:41 2009 @@ -0,0 +1,48 @@ +; RUN: llvm-as < %s | llc -march=x86-64 | grep {movzbl %\[abcd\]h,} | count 4 +; RUN: llvm-as < %s | llc -march=x86 > %t +; RUN: grep {incb %ah} %t | count 3 +; RUN: grep {movzbl %ah,} %t | count 3 + +; Use h registers. On x86-64, codegen doesn't support general allocation +; of h registers yet, due to x86 encoding complications. + +define void @bar64(i64 inreg %x, i8* inreg %p) nounwind { + %t0 = lshr i64 %x, 8 + %t1 = trunc i64 %t0 to i8 + %t2 = add i8 %t1, 1 + store i8 %t2, i8* %p + ret void +} + +define void @bar32(i32 inreg %x, i8* inreg %p) nounwind { + %t0 = lshr i32 %x, 8 + %t1 = trunc i32 %t0 to i8 + %t2 = add i8 %t1, 1 + store i8 %t2, i8* %p + ret void +} + +define void @bar16(i16 inreg %x, i8* inreg %p) nounwind { + %t0 = lshr i16 %x, 8 + %t1 = trunc i16 %t0 to i8 + %t2 = add i8 %t1, 1 + store i8 %t2, i8* %p + ret void +} + +define i64 @qux64(i64 inreg %x) nounwind { + %t0 = lshr i64 %x, 8 + %t1 = and i64 %t0, 255 + ret i64 %t1 +} + +define i32 @qux32(i32 inreg %x) nounwind { + %t0 = lshr i32 %x, 8 + %t1 = and i32 %t0, 255 + ret i32 %t1 +} + +define i16 @qux16(i16 inreg %x) nounwind { + %t0 = lshr i16 %x, 8 + ret i16 %t0 +} Modified: llvm/trunk/test/CodeGen/X86/inline-asm-out-regs.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/inline-asm-out-regs.ll?rev=68962&r1=68961&r2=68962&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/inline-asm-out-regs.ll (original) +++ llvm/trunk/test/CodeGen/X86/inline-asm-out-regs.ll Mon Apr 13 11:09:41 2009 @@ -1,6 +1,4 @@ ; RUN: llvm-as < %s | llc -mtriple=i386-unknown-linux-gnu -; XFAIL: * -; Expected to run out of registers during allocation. ; PR3391 @pci_indirect = external global { } ; <{ }*> [#uses=1] From evan.cheng at apple.com Mon Apr 13 11:12:25 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 13 Apr 2009 09:12:25 -0700 Subject: [llvm-commits] [llvm] r68813 - in /llvm/trunk: include/llvm/CodeGen/MachineModuleInfo.h lib/CodeGen/MachineModuleInfo.cpp In-Reply-To: <200904101859.n3AIx0Zv029350@zion.cs.uiuc.edu> References: <200904101859.n3AIx0Zv029350@zion.cs.uiuc.edu> Message-ID: Hi Devang, Is this a temporary measure? We want to eliminate machinemoduleinfo. Evan Sent from my iPhone On Apr 10, 2009, at 11:59 AM, Devang Patel wrote: > Author: dpatel > Date: Fri Apr 10 13:58:59 2009 > New Revision: 68813 > > URL: http://llvm.org/viewvc/llvm-project?rev=68813&view=rev > Log: > DebugLabelFolder ruthlessly deletes redundant labels. However, > sometimes the redundant labels is referenced by debug info somewhere > else. This patch provies a way so that dwarf writer can mark labels > as used. > > Modified: > llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h > llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp > > Modified: llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h?rev=68813&r1=68812&r2=68813&view=diff > > === > === > === > ===================================================================== > --- llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h (original) > +++ llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h Fri Apr 10 > 13:58:59 2009 > @@ -37,6 +37,7 @@ > #include "llvm/ADT/DenseMap.h" > #include "llvm/ADT/UniqueVector.h" > #include "llvm/ADT/SmallPtrSet.h" > +#include "llvm/ADT/SmallSet.h" > #include "llvm/ADT/StringMap.h" > #include "llvm/CodeGen/MachineLocation.h" > #include "llvm/GlobalValue.h" > @@ -115,6 +116,9 @@ > // searchable format. > SmallPtrSet UsedFunctions; > > + /// UsedDbgLabels - labels are used by debug info entries. > + SmallSet UsedDbgLabels; > + > bool CallsEHReturn; > bool CallsUnwindInit; > > @@ -195,6 +199,19 @@ > return LabelID ? LabelIDList[LabelID - 1] : 0; > } > > + /// isDbgLabelUsed - Return true if label with LabelID is used by > + /// DwarfWriter. > + bool isDbgLabelUsed(unsigned LabelID) { > + return UsedDbgLabels.count(LabelID); > + } > + > + /// RecordUsedDbgLabel - Mark label with LabelID as used. This is > used > + /// by DwarfWriter to inform DebugLabelFolder that certain labels > are > + /// not to be deleted. > + void RecordUsedDbgLabel(unsigned LabelID) { > + UsedDbgLabels.insert(LabelID); > + } > + > /// getFrameMoves - Returns a reference to a list of moves done in > the current > /// function's prologue. Used to construct frame maps for debug > and exception > /// handling comsumers. > > Modified: llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp?rev=68813&r1=68812&r2=68813&view=diff > > === > === > === > ===================================================================== > --- llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp (original) > +++ llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp Fri Apr 10 13:58:59 > 2009 > @@ -333,7 +333,7 @@ > // Iterate through instructions. > for (MachineBasicBlock::iterator I = BB->begin(), E = BB->end(); > I != E; ) { > // Is it a label. > - if (I->isDebugLabel()) { > + if (I->isDebugLabel() && !MMI->isDbgLabelUsed(I->getOperand > (0).getImm())){ > // The label ID # is always operand #0, an immediate. > unsigned NextLabel = I->getOperand(0).getImm(); > > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From stoklund at 2pi.dk Mon Apr 13 11:23:42 2009 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Mon, 13 Apr 2009 18:23:42 +0200 Subject: [llvm-commits] [llvm] r68961 - in /llvm/trunk: include/llvm/Target/Target.td include/llvm/Target/TargetInstrInfo.h include/llvm/Target/TargetRegisterInfo.h lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.h lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp utils/TableGen/CodeEmitterGen.cpp utils/TableGen/CodeGenDAGPatterns.cpp utils/TableGen/CodeGenTarget.cpp utils/TableGen/DAGISelEmitter.cpp utils/TableGen/InstrInfoEmitter.cpp utils/TableGen/RegisterInfoEmitter.cpp In-Reply-To: <200904131538.n3DFc5h6032744@zion.cs.uiuc.edu> References: <200904131538.n3DFc5h6032744@zion.cs.uiuc.edu> Message-ID: On 13/04/2009, at 17.38, Dan Gohman wrote: > Author: djg > Date: Mon Apr 13 10:38:05 2009 > New Revision: 68961 > > URL: http://llvm.org/viewvc/llvm-project?rev=68961&view=rev > Log: > Add a new TargetInstrInfo MachineInstr opcode, COPY_TO_SUBCLASS. > This will be used to replace things like X86's MOV32to32_. Very nice. I wonder, is it necessary to restrict to subclasses? My Blackfin target has disjoint register classes, but I can still copy between them. COPY_TO_REGCLASS? > Enhance ScheduleDAGSDNodesEmit to be more flexible and robust > in the presense of subregister superclasses and subclasses. It > can now cope with the definition of a virtual register being in > a subclass of a use. Great! This is better than my own patch. > Re-introduce the code for recording register superreg classes and > subreg classes. This is needed because when subreg extracts and > inserts get coalesced away, the virtual registers are left in > the correct subclass. Thanks! From dpatel at apple.com Mon Apr 13 11:25:56 2009 From: dpatel at apple.com (Devang Patel) Date: Mon, 13 Apr 2009 09:25:56 -0700 Subject: [llvm-commits] [llvm] r68813 - in /llvm/trunk: include/llvm/CodeGen/MachineModuleInfo.h lib/CodeGen/MachineModuleInfo.cpp In-Reply-To: References: <200904101859.n3AIx0Zv029350@zion.cs.uiuc.edu> Message-ID: <4B8ED489-D437-4D36-9724-D8580CD94378@apple.com> On Apr 13, 2009, at 9:12 AM, Evan Cheng wrote: > Hi Devang, > > Is this a temporary measure? Yes. Eventually dwarfwriter won't rely on labels created by FastISel and SelectionDAGBuild. > We want to eliminate machinemoduleinfo. - Devang > > > Evan > > Sent from my iPhone > > On Apr 10, 2009, at 11:59 AM, Devang Patel wrote: > >> Author: dpatel >> Date: Fri Apr 10 13:58:59 2009 >> New Revision: 68813 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=68813&view=rev >> Log: >> DebugLabelFolder ruthlessly deletes redundant labels. However, >> sometimes the redundant labels is referenced by debug info somewhere >> else. This patch provies a way so that dwarf writer can mark labels >> as used. >> >> Modified: >> llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h >> llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp >> >> Modified: llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h?rev=68813&r1=68812&r2=68813&view=diff >> >> === >> === >> === >> ===================================================================== >> --- llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h (original) >> +++ llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h Fri Apr 10 >> 13:58:59 2009 >> @@ -37,6 +37,7 @@ >> #include "llvm/ADT/DenseMap.h" >> #include "llvm/ADT/UniqueVector.h" >> #include "llvm/ADT/SmallPtrSet.h" >> +#include "llvm/ADT/SmallSet.h" >> #include "llvm/ADT/StringMap.h" >> #include "llvm/CodeGen/MachineLocation.h" >> #include "llvm/GlobalValue.h" >> @@ -115,6 +116,9 @@ >> // searchable format. >> SmallPtrSet UsedFunctions; >> >> + /// UsedDbgLabels - labels are used by debug info entries. >> + SmallSet UsedDbgLabels; >> + >> bool CallsEHReturn; >> bool CallsUnwindInit; >> >> @@ -195,6 +199,19 @@ >> return LabelID ? LabelIDList[LabelID - 1] : 0; >> } >> >> + /// isDbgLabelUsed - Return true if label with LabelID is used by >> + /// DwarfWriter. >> + bool isDbgLabelUsed(unsigned LabelID) { >> + return UsedDbgLabels.count(LabelID); >> + } >> + >> + /// RecordUsedDbgLabel - Mark label with LabelID as used. This is >> used >> + /// by DwarfWriter to inform DebugLabelFolder that certain labels >> are >> + /// not to be deleted. >> + void RecordUsedDbgLabel(unsigned LabelID) { >> + UsedDbgLabels.insert(LabelID); >> + } >> + >> /// getFrameMoves - Returns a reference to a list of moves done in >> the current >> /// function's prologue. Used to construct frame maps for debug >> and exception >> /// handling comsumers. >> >> Modified: llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp?rev=68813&r1=68812&r2=68813&view=diff >> >> === >> === >> === >> ===================================================================== >> --- llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp (original) >> +++ llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp Fri Apr 10 13:58:59 >> 2009 >> @@ -333,7 +333,7 @@ >> // Iterate through instructions. >> for (MachineBasicBlock::iterator I = BB->begin(), E = BB->end(); >> I != E; ) { >> // Is it a label. >> - if (I->isDebugLabel()) { >> + if (I->isDebugLabel() && !MMI->isDbgLabelUsed(I->getOperand >> (0).getImm())){ >> // The label ID # is always operand #0, an immediate. >> unsigned NextLabel = I->getOperand(0).getImm(); >> >> >> >> _______________________________________________ >> 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 dpatel at apple.com Mon Apr 13 12:02:06 2009 From: dpatel at apple.com (Devang Patel) Date: Mon, 13 Apr 2009 17:02:06 -0000 Subject: [llvm-commits] [llvm] r68964 - in /llvm/trunk: include/llvm/CodeGen/DwarfWriter.h include/llvm/Target/TargetAsmInfo.h lib/CodeGen/AsmPrinter/DwarfWriter.cpp lib/CodeGen/SelectionDAG/FastISel.cpp lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp lib/Target/TargetAsmInfo.cpp lib/Target/X86/X86TargetAsmInfo.cpp Message-ID: <200904131702.n3DH26LH003609@zion.cs.uiuc.edu> Author: dpatel Date: Mon Apr 13 12:02:03 2009 New Revision: 68964 URL: http://llvm.org/viewvc/llvm-project?rev=68964&view=rev Log: Reapply 68847. Now debug_inlined section is covered by TAI->doesDwarfUsesInlineInfoSection(), which is false by default. Modified: llvm/trunk/include/llvm/CodeGen/DwarfWriter.h llvm/trunk/include/llvm/Target/TargetAsmInfo.h llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp llvm/trunk/lib/Target/TargetAsmInfo.cpp llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp Modified: llvm/trunk/include/llvm/CodeGen/DwarfWriter.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/DwarfWriter.h?rev=68964&r1=68963&r2=68964&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/DwarfWriter.h (original) +++ llvm/trunk/include/llvm/CodeGen/DwarfWriter.h Mon Apr 13 12:02:03 2009 @@ -94,6 +94,9 @@ /// RecordRegionStart - Indicate the start of a region. unsigned RecordRegionStart(GlobalVariable *V); + /// RecordRegionStart - Indicate the start of a region. + unsigned RecordRegionStart(GlobalVariable *V, unsigned ID); + /// RecordRegionEnd - Indicate the end of a region. unsigned RecordRegionEnd(GlobalVariable *V); @@ -107,6 +110,10 @@ /// ShouldEmitDwarfDebug - Returns true if Dwarf debugging declarations should /// be emitted. bool ShouldEmitDwarfDebug() const; + + //// RecordInlineInfo - Global variable GV is inlined at the location marked + //// by LabelID label. + void RecordInlineInfo(GlobalVariable *GV, unsigned LabelID); }; Modified: llvm/trunk/include/llvm/Target/TargetAsmInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetAsmInfo.h?rev=68964&r1=68963&r2=68964&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetAsmInfo.h (original) +++ llvm/trunk/include/llvm/Target/TargetAsmInfo.h Mon Apr 13 12:02:03 2009 @@ -463,6 +463,10 @@ /// bool DwarfRequiresFrameSection; // Defaults to true. + /// DwarfUsesInlineInfoSection - True if DwarfDebugInlineSection is used to + /// encode inline subroutine information. + bool DwarfUsesInlineInfoSection; // Defaults to false. + /// SupportsMacInfo - true if the Dwarf output supports macro information /// bool SupportsMacInfoSection; // Defaults to true @@ -506,7 +510,11 @@ /// DwarfPubTypesSection - Section directive for Dwarf info. /// const char *DwarfPubTypesSection; // Defaults to ".debug_pubtypes". - + + /// DwarfDebugInlineSection - Section directive for inline info. + /// + const char *DwarfDebugInlineSection; // Defaults to ".debug_inlined" + /// DwarfStrSection - Section directive for Dwarf info. /// const char *DwarfStrSection; // Defaults to ".debug_str". @@ -847,6 +855,9 @@ bool doesDwarfRequireFrameSection() const { return DwarfRequiresFrameSection; } + bool doesDwarfUsesInlineInfoSection() const { + return DwarfUsesInlineInfoSection; + } bool doesSupportMacInfoSection() const { return SupportsMacInfoSection; } @@ -880,6 +891,9 @@ const char *getDwarfPubTypesSection() const { return DwarfPubTypesSection; } + const char *getDwarfDebugInlineSection() const { + return DwarfDebugInlineSection; + } const char *getDwarfStrSection() const { return DwarfStrSection; } Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp?rev=68964&r1=68963&r2=68964&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp Mon Apr 13 12:02:03 2009 @@ -1252,6 +1252,10 @@ /// DbgScopeMap - Tracks the scopes in the current function. DenseMap DbgScopeMap; + /// InlineInfo - Keep track of inlined functions and their location. + /// This information is used to populate debug_inlined section. + DenseMap > InlineInfo; + /// DebugTimer - Timer for the Dwarf debug writer. Timer *DebugTimer; @@ -2027,15 +2031,18 @@ for (unsigned j = 0, M = Scopes.size(); j < M; ++j) { // Define the Scope debug information entry. DbgScope *Scope = Scopes[j]; - // FIXME - Ignore inlined functions for the time being. - if (!Scope->getParent()) continue; unsigned StartID = MMI->MappedLabel(Scope->getStartLabelID()); unsigned EndID = MMI->MappedLabel(Scope->getEndLabelID()); // Ignore empty scopes. if (StartID == EndID && StartID != 0) continue; - if (Scope->getScopes().empty() && Scope->getVariables().empty()) continue; + + // Do not ignore inlined scope even if it is empty. Inlined scope + // does not have any parent. + if (Scope->getParent() + && Scope->getScopes().empty() && Scope->getVariables().empty()) + continue; if (StartID == ParentStartID && EndID == ParentEndID) { // Just add stuff to the parent scope. @@ -2781,6 +2788,77 @@ } } + /// EmitDebugInlineInfo - Emit inline info using following format. + /// Section Header: + /// 1. length of section + /// 2. Dwarf version number + /// 3. address size. + /// + /// Entries (one "entry" for each function that was inlined): + /// + /// 1. offset into __debug_str section for MIPS linkage name, if exists; + /// otherwise offset into __debug_str for regular function name. + /// 2. offset into __debug_str section for regular function name. + /// 3. an unsigned LEB128 number indicating the number of distinct inlining + /// instances for the function. + /// + /// The rest of the entry consists of a {die_offset, low_pc} pair for each + /// inlined instance; the die_offset points to the inlined_subroutine die in + /// the __debug_info section, and the low_pc is the starting address for the + /// inlining instance. + void EmitDebugInlineInfo() { + if (!TAI->doesDwarfUsesInlineInfoSection()) + return; + + if (!MainCU) + return; + + Asm->SwitchToDataSection(TAI->getDwarfDebugInlineSection()); + Asm->EOL(); + EmitDifference("debug_inlined_end", 1, + "debug_inlined_begin", 1, true); + Asm->EOL("Length of Debug Inlined Information Entry"); + + EmitLabel("debug_inlined_begin", 1); + + Asm->EmitInt16(DWARF_VERSION); Asm->EOL("Dwarf Version"); + Asm->EmitInt8(TD->getPointerSize()); Asm->EOL("Address Size (in bytes)"); + + for (DenseMap >::iterator + I = InlineInfo.begin(), E = InlineInfo.end(); I != E; ++I) { + GlobalVariable *GV = I->first; + SmallVector &Labels = I->second; + DISubprogram SP(GV); + std::string Name; + std::string LName; + + SP.getLinkageName(LName); + SP.getName(Name); + + Asm->EmitString(LName.empty() ? Name : LName); + Asm->EOL("MIPS linkage name"); + + Asm->EmitString(Name); Asm->EOL("Function name"); + + Asm->EmitULEB128Bytes(Labels.size()); Asm->EOL("Inline count"); + + for (SmallVector::iterator LI = Labels.begin(), + LE = Labels.end(); LI != LE; ++LI) { + DIE *SP = MainCU->getDieMapSlotFor(GV); + Asm->EmitInt32(SP->getOffset()); Asm->EOL("DIE offset"); + + if (TD->getPointerSize() == sizeof(int32_t)) + O << TAI->getData32bitsDirective(); + else + O << TAI->getData64bitsDirective(); + PrintLabelName("label", *LI); Asm->EOL("low_pc"); + } + } + + EmitLabel("debug_inlined_end", 1); + Asm->EOL(); + } + /// GetOrCreateSourceID - Look up the source id with the given directory and /// source file names. If none currently exists, create a new id and insert it /// in the SourceIds map. This can update DirectoryNames and SourceFileNames maps @@ -3131,6 +3209,9 @@ // Emit info into a debug macinfo section. EmitDebugMacInfo(); + // Emit inline info. + EmitDebugInlineInfo(); + if (TimePassesIsEnabled) DebugTimer->stopTimer(); } @@ -3337,6 +3418,20 @@ return ID; } + /// RecordRegionStart - Indicate the start of a region. + unsigned RecordRegionStart(GlobalVariable *V, unsigned ID) { + if (TimePassesIsEnabled) + DebugTimer->startTimer(); + + DbgScope *Scope = getOrCreateScope(V); + if (!Scope->getStartLabelID()) Scope->setStartLabelID(ID); + + if (TimePassesIsEnabled) + DebugTimer->stopTimer(); + + return ID; + } + /// RecordRegionEnd - Indicate the end of a region. unsigned RecordRegionEnd(GlobalVariable *V) { if (TimePassesIsEnabled) @@ -3377,6 +3472,23 @@ if (TimePassesIsEnabled) DebugTimer->stopTimer(); } + + //// RecordInlineInfo - Global variable GV is inlined at the location marked + //// by LabelID label. + void RecordInlineInfo(GlobalVariable *GV, unsigned LabelID) { + MMI->RecordUsedDbgLabel(LabelID); + DenseMap >::iterator + I = InlineInfo.find(GV); + if (I == InlineInfo.end()) { + SmallVector Labels; + Labels.push_back(LabelID); + InlineInfo[GV] = Labels; + return; + } + + SmallVector &Labels = I->second; + Labels.push_back(LabelID); + } }; //===----------------------------------------------------------------------===// @@ -4535,6 +4647,11 @@ return DD->RecordRegionStart(V); } +/// RecordRegionStart - Indicate the start of a region. +unsigned DwarfWriter::RecordRegionStart(GlobalVariable *V, unsigned ID) { + return DD->RecordRegionStart(V, ID); +} + /// RecordRegionEnd - Indicate the end of a region. unsigned DwarfWriter::RecordRegionEnd(GlobalVariable *V) { return DD->RecordRegionEnd(V); @@ -4556,3 +4673,10 @@ bool DwarfWriter::ShouldEmitDwarfDebug() const { return DD->ShouldEmitDwarfDebug(); } + +//// RecordInlineInfo - Global variable GV is inlined at the location marked +//// by LabelID label. +void DwarfWriter::RecordInlineInfo(GlobalVariable *GV, unsigned LabelID) { + DD->RecordInlineInfo(GV, LabelID); +} + Modified: llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp?rev=68964&r1=68963&r2=68964&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp Mon Apr 13 12:02:03 2009 @@ -377,11 +377,23 @@ // Record the source line. unsigned Line = Subprogram.getLineNumber(); - DW->RecordSourceLine(Line, 0, SrcFile); + unsigned LabelID = DW->RecordSourceLine(Line, 0, SrcFile); setCurDebugLoc(DebugLoc::get(MF.getOrCreateDebugLocID(SrcFile, Line, 0))); - // llvm.dbg.func_start also defines beginning of function scope. - DW->RecordRegionStart(cast(FSI->getSubprogram())); + std::string SPName; + Subprogram.getLinkageName(SPName); + if (!SPName.empty() + && strcmp(SPName.c_str(), MF.getFunction()->getNameStart())) { + // This is a beginning of inlined function. + DW->RecordRegionStart(cast(FSI->getSubprogram()), + LabelID); + const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL); + BuildMI(MBB, DL, II).addImm(LabelID); + DW->RecordInlineInfo(Subprogram.getGV(), LabelID); + } else { + // llvm.dbg.func_start also defines beginning of function scope. + DW->RecordRegionStart(cast(FSI->getSubprogram())); + } } return true; Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp?rev=68964&r1=68963&r2=68964&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Mon Apr 13 12:02:03 2009 @@ -3955,6 +3955,18 @@ DwarfWriter *DW = DAG.getDwarfWriter(); DbgRegionEndInst &REI = cast(I); if (DW && DW->ValidDebugInfo(REI.getContext())) { + + MachineFunction &MF = DAG.getMachineFunction(); + DISubprogram Subprogram(cast(REI.getContext())); + std::string SPName; + Subprogram.getLinkageName(SPName); + if (!SPName.empty() + && strcmp(SPName.c_str(), MF.getFunction()->getNameStart())) { + // This is end of inlined function. Debugging information for + // inlined function is not handled yet (only supported by FastISel). + return 0; + } + unsigned LabelID = DW->RecordRegionEnd(cast(REI.getContext())); if (Fast) @@ -3974,6 +3986,16 @@ // what (most?) gdb expects. MachineFunction &MF = DAG.getMachineFunction(); DISubprogram Subprogram(cast(SP)); + + std::string SPName; + Subprogram.getLinkageName(SPName); + if (!SPName.empty() + && strcmp(SPName.c_str(), MF.getFunction()->getNameStart())) { + // This is beginning of inlined function. Debugging information for + // inlined function is not handled yet (only supported by FastISel). + return 0; + } + DICompileUnit CompileUnit = Subprogram.getCompileUnit(); std::string Dir, FN; unsigned SrcFile = DW->getOrCreateSourceID(CompileUnit.getDirectory(Dir), Modified: llvm/trunk/lib/Target/TargetAsmInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/TargetAsmInfo.cpp?rev=68964&r1=68963&r2=68964&view=diff ============================================================================== --- llvm/trunk/lib/Target/TargetAsmInfo.cpp (original) +++ llvm/trunk/lib/Target/TargetAsmInfo.cpp Mon Apr 13 12:02:03 2009 @@ -101,6 +101,7 @@ SupportsDebugInformation = false; SupportsExceptionHandling = false; DwarfRequiresFrameSection = true; + DwarfUsesInlineInfoSection = false; SupportsMacInfoSection = true; NonLocalEHFrameLabel = false; GlobalEHDirective = 0; @@ -112,6 +113,7 @@ DwarfFrameSection = ".debug_frame"; DwarfPubNamesSection = ".debug_pubnames"; DwarfPubTypesSection = ".debug_pubtypes"; + DwarfDebugInlineSection = ".debug_inlined"; DwarfStrSection = ".debug_str"; DwarfLocSection = ".debug_loc"; DwarfARangesSection = ".debug_aranges"; Modified: llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp?rev=68964&r1=68963&r2=68964&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp Mon Apr 13 12:02:03 2009 @@ -112,6 +112,8 @@ DwarfFrameSection = ".section __DWARF,__debug_frame,regular,debug"; DwarfPubNamesSection = ".section __DWARF,__debug_pubnames,regular,debug"; DwarfPubTypesSection = ".section __DWARF,__debug_pubtypes,regular,debug"; + DwarfDebugInlineSection = ".section __DWARF,__debug_inlined,regular,debug"; + DwarfUsesInlineInfoSection = true; DwarfStrSection = ".section __DWARF,__debug_str,regular,debug"; DwarfLocSection = ".section __DWARF,__debug_loc,regular,debug"; DwarfARangesSection = ".section __DWARF,__debug_aranges,regular,debug"; From anton at korobeynikov.info Mon Apr 13 12:38:10 2009 From: anton at korobeynikov.info (Anton Korobeynikov) Date: Mon, 13 Apr 2009 21:38:10 +0400 Subject: [llvm-commits] [llvm] r68964 - in /llvm/trunk: include/llvm/CodeGen/DwarfWriter.h include/llvm/Target/TargetAsmInfo.h lib/CodeGen/AsmPrinter/DwarfWriter.cpp lib/CodeGen/SelectionDAG/FastISel.cpp lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp lib/ Message-ID: Hello, Devang > Now debug_inlined section is covered by TAI->doesDwarfUsesInlineInfoSection(), which is false by default. This is definitely redundant. Why don't set DwarfDebugInlineSection to be NULL by default and emit this only if it is non-NULL. This will definitely reduce amount of magic knobs in TAI :) -- With best regards, Anton Korobeynikov Faculty of Mathematics and Mechanics, Saint Petersburg State University From sabre at nondot.org Mon Apr 13 13:00:53 2009 From: sabre at nondot.org (Chris Lattner) Date: Mon, 13 Apr 2009 18:00:53 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r68968 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Message-ID: <200904131800.n3DI0r8a005695@zion.cs.uiuc.edu> Author: lattner Date: Mon Apr 13 13:00:53 2009 New Revision: 68968 URL: http://llvm.org/viewvc/llvm-project?rev=68968&view=rev Log: fix TreeConstantToLLVM::ConvertINTEGER_CST to correctly handle INTEGER_CST's that are 128-bits in size instead of silently discarding the top bits. This allows us to compile: __uint128_t test2() { const __uint128_t c_zero = ~0; return c_zero; } __uint128_t test1() { const __uint128_t c_zero = 1234; return c_zero; } into: define i128 @test2() nounwind readnone { entry: ret i128 -1 } define i128 @test1() nounwind readnone { entry: ret i128 1234 } instead of: define i128 @test2() nounwind readnone { entry: ret i128 18446744073709551615 } define i128 @test1() nounwind readnone { entry: ret i128 1234 } This fixes PR3975. 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=68968&r1=68967&r2=68968&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Mon Apr 13 13:00:53 2009 @@ -6423,12 +6423,20 @@ } Constant *TreeConstantToLLVM::ConvertINTEGER_CST(tree exp) { - // Convert it to a uint64_t. - uint64_t IntValue = getINTEGER_CSTVal(exp); + const IntegerType *Ty = cast(ConvertType(TREE_TYPE(exp))); + + // Handle i128 specially. + if (Ty->getPrimitiveSizeInBits() == 128) { + // GCC only supports i128 on 64-bit systems. + assert(HOST_BITS_PER_WIDE_INT == 64 && + "i128 only supported on 64-bit system"); + uint64_t Bits[] = { TREE_INT_CST_LOW(exp), TREE_INT_CST_HIGH(exp) }; + return ConstantInt::get(APInt(128, 2, Bits)); + } // Build the value as a ulong constant, then constant fold it to the right // type. This handles overflow and other things appropriately. - const Type *Ty = ConvertType(TREE_TYPE(exp)); + uint64_t IntValue = getINTEGER_CSTVal(exp); ConstantInt *C = ConstantInt::get(Type::Int64Ty, IntValue); // The destination type can be a pointer, integer or floating point // so we need a generalized cast here From sabre at nondot.org Mon Apr 13 13:03:09 2009 From: sabre at nondot.org (Chris Lattner) Date: Mon, 13 Apr 2009 18:03:09 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r68970 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Message-ID: <200904131803.n3DI39f2005789@zion.cs.uiuc.edu> Author: lattner Date: Mon Apr 13 13:03:08 2009 New Revision: 68970 URL: http://llvm.org/viewvc/llvm-project?rev=68970&view=rev Log: Fix a bug in my r68968 patch: INTEGER_CST's can have pointer and floating point type in GCC trees (!). 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=68970&r1=68969&r2=68970&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Mon Apr 13 13:03:08 2009 @@ -6423,15 +6423,17 @@ } Constant *TreeConstantToLLVM::ConvertINTEGER_CST(tree exp) { - const IntegerType *Ty = cast(ConvertType(TREE_TYPE(exp))); + const Type *Ty = ConvertType(TREE_TYPE(exp)); // Handle i128 specially. - if (Ty->getPrimitiveSizeInBits() == 128) { - // GCC only supports i128 on 64-bit systems. - assert(HOST_BITS_PER_WIDE_INT == 64 && - "i128 only supported on 64-bit system"); - uint64_t Bits[] = { TREE_INT_CST_LOW(exp), TREE_INT_CST_HIGH(exp) }; - return ConstantInt::get(APInt(128, 2, Bits)); + if (const IntegerType *IT = dyn_cast(Ty)) { + if (IT->getBitWidth() == 128) { + // GCC only supports i128 on 64-bit systems. + assert(HOST_BITS_PER_WIDE_INT == 64 && + "i128 only supported on 64-bit system"); + uint64_t Bits[] = { TREE_INT_CST_LOW(exp), TREE_INT_CST_HIGH(exp) }; + return ConstantInt::get(APInt(128, 2, Bits)); + } } // Build the value as a ulong constant, then constant fold it to the right From dpatel at apple.com Mon Apr 13 13:13:17 2009 From: dpatel at apple.com (Devang Patel) Date: Mon, 13 Apr 2009 18:13:17 -0000 Subject: [llvm-commits] [llvm] r68973 - in /llvm/trunk: include/llvm/CodeGen/DwarfWriter.h lib/CodeGen/AsmPrinter/DwarfWriter.cpp lib/CodeGen/SelectionDAG/FastISel.cpp lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Message-ID: <200904131813.n3DIDHGk006251@zion.cs.uiuc.edu> Author: dpatel Date: Mon Apr 13 13:13:16 2009 New Revision: 68973 URL: http://llvm.org/viewvc/llvm-project?rev=68973&view=rev Log: Right now, Debugging information to encode scopes (DW_TAG_lexical_block) relies on DBG_LABEL. Unfortunately this intefers with the quality of optimized code. This patch updates dwarf writer to encode scoping information in DWARF only in FastISel mode. Modified: llvm/trunk/include/llvm/CodeGen/DwarfWriter.h llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Modified: llvm/trunk/include/llvm/CodeGen/DwarfWriter.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/DwarfWriter.h?rev=68973&r1=68972&r2=68973&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/DwarfWriter.h (original) +++ llvm/trunk/include/llvm/CodeGen/DwarfWriter.h Mon Apr 13 13:13:16 2009 @@ -77,7 +77,7 @@ void EndFunction(MachineFunction *MF); /// ValidDebugInfo - Return true if V represents valid debug info value. - bool ValidDebugInfo(Value *V); + bool ValidDebugInfo(Value *V, bool FastISel); /// RecordSourceLine - Register a source line with debug info. Returns a /// unique label ID used to generate a label and provide correspondence to Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp?rev=68973&r1=68972&r2=68973&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp Mon Apr 13 13:13:16 2009 @@ -3296,7 +3296,7 @@ } /// ValidDebugInfo - Return true if V represents valid debug info value. - bool ValidDebugInfo(Value *V) { + bool ValidDebugInfo(Value *V, bool FastISel) { if (!V) return false; @@ -3335,6 +3335,11 @@ case DW_TAG_subprogram: assert(DISubprogram(GV).Verify() && "Invalid DebugInfo value"); break; + case DW_TAG_lexical_block: + /// FIXME. This interfers with the qualitfy of generated code when + /// during optimization. + if (FastISel == false) + return false; default: break; } @@ -4621,8 +4626,8 @@ } /// ValidDebugInfo - Return true if V represents valid debug info value. -bool DwarfWriter::ValidDebugInfo(Value *V) { - return DD && DD->ValidDebugInfo(V); +bool DwarfWriter::ValidDebugInfo(Value *V, bool FastISel) { + return DD && DD->ValidDebugInfo(V, FastISel); } /// RecordSourceLine - Records location information and associates it with a Modified: llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp?rev=68973&r1=68972&r2=68973&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp Mon Apr 13 13:13:16 2009 @@ -326,7 +326,7 @@ default: break; case Intrinsic::dbg_stoppoint: { DbgStopPointInst *SPI = cast(I); - if (DW && DW->ValidDebugInfo(SPI->getContext())) { + if (DW && DW->ValidDebugInfo(SPI->getContext(), true)) { DICompileUnit CU(cast(SPI->getContext())); std::string Dir, FN; unsigned SrcFile = DW->getOrCreateSourceID(CU.getDirectory(Dir), @@ -343,7 +343,7 @@ } case Intrinsic::dbg_region_start: { DbgRegionStartInst *RSI = cast(I); - if (DW && DW->ValidDebugInfo(RSI->getContext())) { + if (DW && DW->ValidDebugInfo(RSI->getContext(), true)) { unsigned ID = DW->RecordRegionStart(cast(RSI->getContext())); const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL); @@ -353,7 +353,7 @@ } case Intrinsic::dbg_region_end: { DbgRegionEndInst *REI = cast(I); - if (DW && DW->ValidDebugInfo(REI->getContext())) { + if (DW && DW->ValidDebugInfo(REI->getContext(), true)) { unsigned ID = DW->RecordRegionEnd(cast(REI->getContext())); const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL); @@ -366,7 +366,7 @@ DbgFuncStartInst *FSI = cast(I); Value *SP = FSI->getSubprogram(); - if (DW->ValidDebugInfo(SP)) { + if (DW->ValidDebugInfo(SP, true)) { // llvm.dbg.func.start implicitly defines a dbg_stoppoint which is what // (most?) gdb expects. DISubprogram Subprogram(cast(SP)); @@ -401,7 +401,7 @@ case Intrinsic::dbg_declare: { DbgDeclareInst *DI = cast(I); Value *Variable = DI->getVariable(); - if (DW && DW->ValidDebugInfo(Variable)) { + if (DW && DW->ValidDebugInfo(Variable, true)) { // Determine the address of the declared object. Value *Address = DI->getAddress(); if (BitCastInst *BCI = dyn_cast(Address)) Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp?rev=68973&r1=68972&r2=68973&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Mon Apr 13 13:13:16 2009 @@ -332,7 +332,7 @@ DwarfWriter *DW = DAG.getDwarfWriter(); DbgStopPointInst *SPI = cast(I); - if (DW && DW->ValidDebugInfo(SPI->getContext())) { + if (DW && DW->ValidDebugInfo(SPI->getContext(), false)) { DICompileUnit CU(cast(SPI->getContext())); std::string Dir, FN; unsigned SrcFile = DW->getOrCreateSourceID(CU.getDirectory(Dir), @@ -351,7 +351,7 @@ DbgFuncStartInst *FSI = cast(I); Value *SP = FSI->getSubprogram(); - if (DW->ValidDebugInfo(SP)) { + if (DW->ValidDebugInfo(SP, false)) { DISubprogram Subprogram(cast(SP)); DICompileUnit CU(Subprogram.getCompileUnit()); std::string Dir, FN; @@ -3921,7 +3921,7 @@ case Intrinsic::dbg_stoppoint: { DwarfWriter *DW = DAG.getDwarfWriter(); DbgStopPointInst &SPI = cast(I); - if (DW && DW->ValidDebugInfo(SPI.getContext())) { + if (DW && DW->ValidDebugInfo(SPI.getContext(), Fast)) { MachineFunction &MF = DAG.getMachineFunction(); if (Fast) DAG.setRoot(DAG.getDbgStopPoint(getRoot(), @@ -3941,12 +3941,11 @@ case Intrinsic::dbg_region_start: { DwarfWriter *DW = DAG.getDwarfWriter(); DbgRegionStartInst &RSI = cast(I); - if (DW && DW->ValidDebugInfo(RSI.getContext())) { + if (DW && DW->ValidDebugInfo(RSI.getContext(), Fast)) { unsigned LabelID = DW->RecordRegionStart(cast(RSI.getContext())); - if (Fast) - DAG.setRoot(DAG.getLabel(ISD::DBG_LABEL, getCurDebugLoc(), - getRoot(), LabelID)); + DAG.setRoot(DAG.getLabel(ISD::DBG_LABEL, getCurDebugLoc(), + getRoot(), LabelID)); } return 0; @@ -3954,7 +3953,7 @@ case Intrinsic::dbg_region_end: { DwarfWriter *DW = DAG.getDwarfWriter(); DbgRegionEndInst &REI = cast(I); - if (DW && DW->ValidDebugInfo(REI.getContext())) { + if (DW && DW->ValidDebugInfo(REI.getContext(), Fast)) { MachineFunction &MF = DAG.getMachineFunction(); DISubprogram Subprogram(cast(REI.getContext())); @@ -3969,9 +3968,8 @@ unsigned LabelID = DW->RecordRegionEnd(cast(REI.getContext())); - if (Fast) - DAG.setRoot(DAG.getLabel(ISD::DBG_LABEL, getCurDebugLoc(), - getRoot(), LabelID)); + DAG.setRoot(DAG.getLabel(ISD::DBG_LABEL, getCurDebugLoc(), + getRoot(), LabelID)); } return 0; @@ -3981,7 +3979,7 @@ if (!DW) return 0; DbgFuncStartInst &FSI = cast(I); Value *SP = FSI.getSubprogram(); - if (SP && DW->ValidDebugInfo(SP)) { + if (SP && DW->ValidDebugInfo(SP, Fast)) { // llvm.dbg.func.start implicitly defines a dbg_stoppoint which is // what (most?) gdb expects. MachineFunction &MF = DAG.getMachineFunction(); @@ -4023,7 +4021,7 @@ DwarfWriter *DW = DAG.getDwarfWriter(); DbgDeclareInst &DI = cast(I); Value *Variable = DI.getVariable(); - if (DW && DW->ValidDebugInfo(Variable)) + if (DW && DW->ValidDebugInfo(Variable, Fast)) DAG.setRoot(DAG.getNode(ISD::DECLARE, dl, MVT::Other, getRoot(), getValue(DI.getAddress()), getValue(Variable))); } else { From clattner at apple.com Mon Apr 13 13:16:47 2009 From: clattner at apple.com (Chris Lattner) Date: Mon, 13 Apr 2009 11:16:47 -0700 Subject: [llvm-commits] [llvm] r68940 - in /llvm/trunk: docs/ include/llvm/ include/llvm/CodeGen/ lib/AsmParser/ lib/Bitcode/Reader/ lib/Bitcode/Writer/ lib/CodeGen/ lib/CodeGen/AsmPrinter/ lib/Linker/ lib/Target/CppBackend/ lib/VMCore/ test/CodeGen/Gener In-Reply-To: References: Message-ID: <41F740D6-23D6-413A-BDBA-598D5892DF89@apple.com> On Apr 13, 2009, at 12:38 AM, Eli Friedman wrote: > On Sun, Apr 12, 2009 at 10:44 PM, Chris Lattner > wrote: >> Author: lattner >> Date: Mon Apr 13 00:44:34 2009 >> New Revision: 68940 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=68940&view=rev >> Log: >> Add a new "available_externally" linkage type. This is intended >> to support C99 inline, GNU extern inline, etc. Related bugzilla's >> include PR3517, PR3100, & PR2933. Nothing uses this yet, but it >> appears to work. > > Interesting. One serious issue from looking over it: the C99 rules > require that only calls from within the same translation unit are > allowed to use an inline definition. This could be handled by having the linker drop "available_externally" symbols when it does linking, but do you expect this to be a problem in practice? Why would it be ok to inline a body in one translation unit but not in another? -Chris From dalej at apple.com Mon Apr 13 13:20:53 2009 From: dalej at apple.com (Dale Johannesen) Date: Mon, 13 Apr 2009 11:20:53 -0700 Subject: [llvm-commits] [llvm] r68940 - in /llvm/trunk: docs/ include/llvm/ include/llvm/CodeGen/ lib/AsmParser/ lib/Bitcode/Reader/ lib/Bitcode/Writer/ lib/CodeGen/ lib/CodeGen/AsmPrinter/ lib/Linker/ lib/Target/CppBackend/ lib/VMCore/ test/CodeGen/Gener In-Reply-To: <41F740D6-23D6-413A-BDBA-598D5892DF89@apple.com> References: <41F740D6-23D6-413A-BDBA-598D5892DF89@apple.com> Message-ID: On Apr 13, 2009, at 11:16 AMPDT, Chris Lattner wrote: > On Apr 13, 2009, at 12:38 AM, Eli Friedman wrote: >> On Sun, Apr 12, 2009 at 10:44 PM, Chris Lattner >> wrote: >>> Author: lattner >>> Date: Mon Apr 13 00:44:34 2009 >>> New Revision: 68940 >>> >>> URL: http://llvm.org/viewvc/llvm-project?rev=68940&view=rev >>> Log: >>> Add a new "available_externally" linkage type. This is intended >>> to support C99 inline, GNU extern inline, etc. Related bugzilla's >>> include PR3517, PR3100, & PR2933. Nothing uses this yet, but it >>> appears to work. >> >> Interesting. One serious issue from looking over it: the C99 rules >> require that only calls from within the same translation unit are >> allowed to use an inline definition. > > This could be handled by having the linker drop "available_externally" > symbols when it does linking, but do you expect this to be a problem > in practice? Why would it be ok to inline a body in one translation > unit but not in another? If all you're concerned about is a problem in practice, what we had before is probably OK; this form of inline is not widely used. The reason to do what you're doing IMO is to implement something standard conformant. From clattner at apple.com Mon Apr 13 13:34:03 2009 From: clattner at apple.com (Chris Lattner) Date: Mon, 13 Apr 2009 11:34:03 -0700 Subject: [llvm-commits] [llvm] r68940 - in /llvm/trunk: docs/ include/llvm/ include/llvm/CodeGen/ lib/AsmParser/ lib/Bitcode/Reader/ lib/Bitcode/Writer/ lib/CodeGen/ lib/CodeGen/AsmPrinter/ lib/Linker/ lib/Target/CppBackend/ lib/VMCore/ test/CodeGen/Gener In-Reply-To: References: <41F740D6-23D6-413A-BDBA-598D5892DF89@apple.com> Message-ID: On Apr 13, 2009, at 11:20 AM, Dale Johannesen wrote: >>> >>> Interesting. One serious issue from looking over it: the C99 rules >>> require that only calls from within the same translation unit are >>> allowed to use an inline definition. >> >> This could be handled by having the linker drop >> "available_externally" >> symbols when it does linking, but do you expect this to be a problem >> in practice? Why would it be ok to inline a body in one translation >> unit but not in another? > > If all you're concerned about is a problem in practice, what we had > before is probably OK; this form of inline is not widely used. The > reason to do what you're doing IMO is to implement something standard > conformant. What we had before is not acceptable for Clang. It defaults to gnu99 (unlike gcc, which defaults to gnu89), so no inline functions get inlined without this. -Chris From dalej at apple.com Mon Apr 13 13:37:45 2009 From: dalej at apple.com (Dale Johannesen) Date: Mon, 13 Apr 2009 11:37:45 -0700 Subject: [llvm-commits] [llvm] r68940 - in /llvm/trunk: docs/ include/llvm/ include/llvm/CodeGen/ lib/AsmParser/ lib/Bitcode/Reader/ lib/Bitcode/Writer/ lib/CodeGen/ lib/CodeGen/AsmPrinter/ lib/Linker/ lib/Target/CppBackend/ lib/VMCore/ test/CodeGen/Gener In-Reply-To: References: <41F740D6-23D6-413A-BDBA-598D5892DF89@apple.com> Message-ID: On Apr 13, 2009, at 11:34 AMPDT, Chris Lattner wrote: > > On Apr 13, 2009, at 11:20 AM, Dale Johannesen wrote: > >>>> >>>> Interesting. One serious issue from looking over it: the C99 rules >>>> require that only calls from within the same translation unit are >>>> allowed to use an inline definition. >>> >>> This could be handled by having the linker drop >>> "available_externally" >>> symbols when it does linking, but do you expect this to be a problem >>> in practice? Why would it be ok to inline a body in one translation >>> unit but not in another? >> >> If all you're concerned about is a problem in practice, what we had >> before is probably OK; this form of inline is not widely used. The >> reason to do what you're doing IMO is to implement something standard >> conformant. > > What we had before is not acceptable for Clang. It defaults to gnu99 > (unlike gcc, which defaults to gnu89), so no inline functions get > inlined without this. I see. Sure you want to do that? I think you'll find most existing code expects inline to behave like gnu89. From clattner at apple.com Mon Apr 13 13:38:58 2009 From: clattner at apple.com (Chris Lattner) Date: Mon, 13 Apr 2009 11:38:58 -0700 Subject: [llvm-commits] [llvm] r68940 - in /llvm/trunk: docs/ include/llvm/ include/llvm/CodeGen/ lib/AsmParser/ lib/Bitcode/Reader/ lib/Bitcode/Writer/ lib/CodeGen/ lib/CodeGen/AsmPrinter/ lib/Linker/ lib/Target/CppBackend/ lib/VMCore/ test/CodeGen/Gener In-Reply-To: References: <41F740D6-23D6-413A-BDBA-598D5892DF89@apple.com> Message-ID: On Apr 13, 2009, at 11:37 AM, Dale Johannesen wrote: >>> >>> If all you're concerned about is a problem in practice, what we had >>> before is probably OK; this form of inline is not widely used. The >>> reason to do what you're doing IMO is to implement something >>> standard >>> conformant. >> >> What we had before is not acceptable for Clang. It defaults to gnu99 >> (unlike gcc, which defaults to gnu89), so no inline functions get >> inlined without this. > > I see. Sure you want to do that? I think you'll find most existing > code expects inline to behave like gnu89. Yes, I'm sure. Code has an easy workaround (build with -std=gnu89) and "moving to a new compiler" is a good time to change things like default languages IMO. C99 is not new anymore :) -Chris From dgregor at apple.com Mon Apr 13 14:43:10 2009 From: dgregor at apple.com (Douglas Gregor) Date: Mon, 13 Apr 2009 19:43:10 -0000 Subject: [llvm-commits] [llvm] r68977 - /llvm/trunk/include/llvm/ADT/APInt.h Message-ID: <200904131943.n3DJhBd8009767@zion.cs.uiuc.edu> Author: dgregor Date: Mon Apr 13 14:43:10 2009 New Revision: 68977 URL: http://llvm.org/viewvc/llvm-project?rev=68977&view=rev Log: Add a static APInt::getNumWords Modified: llvm/trunk/include/llvm/ADT/APInt.h Modified: llvm/trunk/include/llvm/ADT/APInt.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/APInt.h?rev=68977&r1=68976&r2=68977&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/APInt.h (original) +++ llvm/trunk/include/llvm/ADT/APInt.h Mon Apr 13 14:43:10 2009 @@ -1000,6 +1000,14 @@ /// @returns the number of words to hold the integer value of this APInt. /// @brief Get the number of words. unsigned getNumWords() const { + return getNumWords(BitWidth); + } + + /// Here one word's bitwidth equals to that of uint64_t. + /// @returns the number of words to hold the integer value with a + /// given bit width. + /// @brief Get the number of words. + static unsigned getNumWords(unsigned BitWidth) { return (BitWidth + APINT_BITS_PER_WORD - 1) / APINT_BITS_PER_WORD; } From isanbard at gmail.com Mon Apr 13 14:45:05 2009 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 13 Apr 2009 19:45:05 -0000 Subject: [llvm-commits] [llvm] r68978 - /llvm/trunk/examples/Kaleidoscope/toy.cpp Message-ID: <200904131945.n3DJj5Ne009845@zion.cs.uiuc.edu> Author: void Date: Mon Apr 13 14:45:05 2009 New Revision: 68978 URL: http://llvm.org/viewvc/llvm-project?rev=68978&view=rev Log: Get rid of some compile warnings. Modified: llvm/trunk/examples/Kaleidoscope/toy.cpp Modified: llvm/trunk/examples/Kaleidoscope/toy.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/Kaleidoscope/toy.cpp?rev=68978&r1=68977&r2=68978&view=diff ============================================================================== --- llvm/trunk/examples/Kaleidoscope/toy.cpp (original) +++ llvm/trunk/examples/Kaleidoscope/toy.cpp Mon Apr 13 14:45:05 2009 @@ -512,7 +512,7 @@ static PrototypeAST *ParsePrototype() { std::string FnName; - int Kind = 0; // 0 = identifier, 1 = unary, 2 = binary. + unsigned Kind = 0; // 0 = identifier, 1 = unary, 2 = binary. unsigned BinaryPrecedence = 30; switch (CurTok) { @@ -791,7 +791,6 @@ // Make the new basic block for the loop header, inserting after current // block. - BasicBlock *PreheaderBB = Builder.GetInsertBlock(); BasicBlock *LoopBB = BasicBlock::Create("loop", TheFunction); // Insert an explicit fall through from the current block to the LoopBB. @@ -837,7 +836,6 @@ "loopcond"); // Create the "after loop" block and insert it. - BasicBlock *LoopEndBB = Builder.GetInsertBlock(); BasicBlock *AfterBB = BasicBlock::Create("afterloop", TheFunction); // Insert the conditional branch into the end of LoopEndBB. From gohman at apple.com Mon Apr 13 14:49:32 2009 From: gohman at apple.com (Dan Gohman) Date: Mon, 13 Apr 2009 12:49:32 -0700 Subject: [llvm-commits] [llvm] r68961 - in /llvm/trunk: include/llvm/Target/Target.td include/llvm/Target/TargetInstrInfo.h include/llvm/Target/TargetRegisterInfo.h lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.h lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp utils/TableGen/CodeEmitterGen.cpp utils/TableGen/CodeGenDAGPatterns.cpp utils/TableGen/CodeGenTarget.cpp utils/TableGen/DAGISelEmitter.cpp utils/TableGen/InstrInfoEmitter.cpp utils/TableGen/RegisterInfoEmitter.cpp In-Reply-To: References: <200904131538.n3DFc5h6032744@zion.cs.uiuc.edu> Message-ID: <5BFA7225-AFD4-4BCD-9FF0-EB6F07DDDC9B@apple.com> On Apr 13, 2009, at 9:23 AM, Jakob Stoklund Olesen wrote: > > On 13/04/2009, at 17.38, Dan Gohman wrote: > >> Author: djg >> Date: Mon Apr 13 10:38:05 2009 >> New Revision: 68961 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=68961&view=rev >> Log: >> Add a new TargetInstrInfo MachineInstr opcode, COPY_TO_SUBCLASS. >> This will be used to replace things like X86's MOV32to32_. > > Very nice. I wonder, is it necessary to restrict to subclasses? My > Blackfin target has disjoint register classes, but I can still copy > between them. COPY_TO_REGCLASS? With the register class enhancement changes that accompanied this change, the code that expands post-isel SDNodes into MachineInstrs now automatically inserts copies when needed to bridge between different register classes. COPY_TO_SUBCLASS is only needed in situations where the the register class of the virtual registers needs to be something other than what the instruction patterns indicate they require. Can you give an example of a pattern where this would be used? Dan From gohman at apple.com Mon Apr 13 14:59:08 2009 From: gohman at apple.com (Dan Gohman) Date: Mon, 13 Apr 2009 12:59:08 -0700 Subject: [llvm-commits] [llvm-gcc-4.2] r68848 - /llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp In-Reply-To: <200904110017.n3B0HseT009219@zion.cs.uiuc.edu> References: <200904110017.n3B0HseT009219@zion.cs.uiuc.edu> Message-ID: <6A75B539-DA9D-44E9-BC3F-E7808C47B9F9@apple.com> On Apr 10, 2009, at 5:17 PM, Devang Patel wrote: > Author: dpatel > Date: Fri Apr 10 19:17:54 2009 > New Revision: 68848 > > URL: http://llvm.org/viewvc/llvm-project?rev=68848&view=rev > Log: > If linkage name is not available then use function display name as > linkage name. Hi Devang, What does this fix? Why is a bogus linkage name better than no linkage name? Dan > > > Modified: > llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp > > Modified: llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp?rev=68848&r1=68847&r2=68848&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp (original) > +++ llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp Fri Apr 10 19:17:54 2009 > @@ -190,7 +190,7 @@ > return IDENTIFIER_POINTER(DECL_ASSEMBLER_NAME(Node)); > } > } > - return ""; > + return NULL; > } > > DebugInfo::DebugInfo(Module *m) > @@ -211,12 +211,11 @@ > // Gather location information. > expanded_location Loc = GetNodeLocation(FnDecl, false); > const char *LinkageName = getLinkageName(FnDecl); > - > + const char *FnName = lang_hooks.dwarf_name(FnDecl, 0); > DISubprogram SP = > DebugFactory.CreateSubprogram(findRegion(FnDecl), > - lang_hooks.dwarf_name(FnDecl, 0), > - lang_hooks.dwarf_name(FnDecl, 0), > - LinkageName, > + FnName, FnName, > + LinkageName ? LinkageName : FnName, > getOrCreateCompileUnit(Loc.file), > CurLineNo, > getOrCreateType(TREE_TYPE(FnDecl)), > Fn->hasInternalLinkage(), > @@ -345,11 +344,11 @@ > if (IDENTIFIER_POINTER(DECL_NAME(decl))) > DispName = IDENTIFIER_POINTER(DECL_NAME(decl)); > } > - > + const char *LinkageName = getLinkageName(decl); > DebugFactory.CreateGlobalVariable(getOrCreateCompileUnit(Loc.file), > GV->getNameStr(), > DispName, > - getLinkageName(decl), > + LinkageName ? LinkageName : > DispName, > > getOrCreateCompileUnit(Loc.file), Loc.line, > TyD, GV->hasInternalLinkage(), > true/*definition*/, GV); > @@ -668,7 +667,7 @@ > DIType SPTy = getOrCreateType(TREE_TYPE(Member)); > DISubprogram SP = > DebugFactory.CreateSubprogram(findRegion(Member), MemberName, > MemberName, > - LinkageName, > + LinkageName ? LinkageName : > MemberName, > > getOrCreateCompileUnit(MemLoc.file), > MemLoc.line, SPTy, false, false); > EltTys.push_back(SP); > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From eli.friedman at gmail.com Mon Apr 13 14:59:22 2009 From: eli.friedman at gmail.com (Eli Friedman) Date: Mon, 13 Apr 2009 12:59:22 -0700 Subject: [llvm-commits] [llvm] r68940 - in /llvm/trunk: docs/ include/llvm/ include/llvm/CodeGen/ lib/AsmParser/ lib/Bitcode/Reader/ lib/Bitcode/Writer/ lib/CodeGen/ lib/CodeGen/AsmPrinter/ lib/Linker/ lib/Target/CppBackend/ lib/VMCore/ test/CodeGen/Gener In-Reply-To: <41F740D6-23D6-413A-BDBA-598D5892DF89@apple.com> References: <41F740D6-23D6-413A-BDBA-598D5892DF89@apple.com> Message-ID: On Mon, Apr 13, 2009 at 11:16 AM, Chris Lattner wrote: > This could be handled by having the linker drop "available_externally" > symbols when it does linking, but do you expect this to be a problem > in practice? ?Why would it be ok to inline a body in one translation > unit but not in another? >From the C99 rationale: "Second, the requirement that all definitions of an inline function be 'exactly the same' is replaced by the requirement that the behavior of the program should not depend on whether a call is implemented with a visible inline definition, or the external definition, of a function. This allows an inline definition to be specialized for its use within a particular translation unit. For example, the external definition of a library function might include some argument validation that is not needed for calls made from other functions in the same library." -Eli From evan.cheng at apple.com Mon Apr 13 15:04:24 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 13 Apr 2009 20:04:24 -0000 Subject: [llvm-commits] [llvm] r68979 - in /llvm/trunk: lib/CodeGen/TwoAddressInstructionPass.cpp test/CodeGen/X86/2009-04-13-2AddrAssert.ll Message-ID: <200904132004.n3DK4O2W010608@zion.cs.uiuc.edu> Author: evancheng Date: Mon Apr 13 15:04:24 2009 New Revision: 68979 URL: http://llvm.org/viewvc/llvm-project?rev=68979&view=rev Log: PR3934: Fix a bogus two-address pass assertion. Added: llvm/trunk/test/CodeGen/X86/2009-04-13-2AddrAssert.ll Modified: llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp Modified: llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp?rev=68979&r1=68978&r2=68979&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp (original) +++ llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp Mon Apr 13 15:04:24 2009 @@ -628,10 +628,10 @@ if (IsDstPhys && !IsSrcPhys) DstRegMap.insert(std::make_pair(SrcReg, DstReg)); else if (!IsDstPhys && IsSrcPhys) { - bool isNew = - SrcRegMap.insert(std::make_pair(DstReg, SrcReg)).second; - isNew = isNew; // Silence compiler warning. - assert(isNew && "Can't map to two src physical registers!"); + bool isNew = SrcRegMap.insert(std::make_pair(DstReg, SrcReg)).second; + if (!isNew) + assert(SrcRegMap[DstReg] == SrcReg && + "Can't map to two src physical registers!"); SmallVector VirtRegPairs; bool isCopy = false; @@ -653,8 +653,9 @@ break; } bool isNew = SrcRegMap.insert(std::make_pair(NewReg, DstReg)).second; - isNew = isNew; // Silence compiler warning. - assert(isNew && "Can't map to two src physical registers!"); + if (!isNew) + assert(SrcRegMap[NewReg] == DstReg && + "Can't map to two src physical registers!"); VirtRegPairs.push_back(NewReg); DstReg = NewReg; } @@ -666,8 +667,9 @@ unsigned FromReg = VirtRegPairs.back(); VirtRegPairs.pop_back(); bool isNew = DstRegMap.insert(std::make_pair(FromReg, ToReg)).second; - isNew = isNew; // Silence compiler warning. - assert(isNew && "Can't map to two dst physical registers!"); + if (!isNew) + assert(DstRegMap[FromReg] == ToReg && + "Can't map to two dst physical registers!"); ToReg = FromReg; } } Added: llvm/trunk/test/CodeGen/X86/2009-04-13-2AddrAssert.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2009-04-13-2AddrAssert.ll?rev=68979&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/2009-04-13-2AddrAssert.ll (added) +++ llvm/trunk/test/CodeGen/X86/2009-04-13-2AddrAssert.ll Mon Apr 13 15:04:24 2009 @@ -0,0 +1,16 @@ +; RUN: llvm-as < %s | llc +; rdar://6781755 +; PR3934 + +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" +target triple = "x86_64-undermydesk-freebsd8.0" + +define i32 @main(i32 %argc, i8** nocapture %argv) nounwind { +entry: + %call = tail call i32 (...)* @getpid() ; [#uses=1] + %conv = trunc i32 %call to i16 ; [#uses=1] + %0 = tail call i16 asm "xchgb ${0:h}, ${0:b}","=Q,0,~{dirflag},~{fpsr},~{flags}"(i16 %conv) nounwind ; [#uses=0] + ret i32 undef +} + +declare i32 @getpid(...) From dpatel at apple.com Mon Apr 13 15:05:40 2009 From: dpatel at apple.com (Devang Patel) Date: Mon, 13 Apr 2009 13:05:40 -0700 Subject: [llvm-commits] [llvm-gcc-4.2] r68848 - /llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp In-Reply-To: <6A75B539-DA9D-44E9-BC3F-E7808C47B9F9@apple.com> References: <200904110017.n3B0HseT009219@zion.cs.uiuc.edu> <6A75B539-DA9D-44E9-BC3F-E7808C47B9F9@apple.com> Message-ID: <81F7E9A5-859F-4384-880D-5457892664C8@apple.com> On Apr 13, 2009, at 12:59 PM, Dan Gohman wrote: > > On Apr 10, 2009, at 5:17 PM, Devang Patel wrote: > >> Author: dpatel >> Date: Fri Apr 10 19:17:54 2009 >> New Revision: 68848 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=68848&view=rev >> Log: >> If linkage name is not available then use function display name as >> linkage name. > > Hi Devang, > > What does this fix? Why is a bogus linkage name better than no > linkage name? In C, linkage name is same as name. This info is used during FastISel to decide whether we are at the beginning of inlined subroutine or not. std::string SPName; Subprogram.getLinkageName(SPName); if (!SPName.empty() && strcmp(SPName.c_str(), MF.getFunction()- >getNameStart())) { - Devang > > > Dan > >> >> >> Modified: >> llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp >> >> Modified: llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp?rev=68848&r1=68847&r2=68848&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp (original) >> +++ llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp Fri Apr 10 19:17:54 2009 >> @@ -190,7 +190,7 @@ >> return IDENTIFIER_POINTER(DECL_ASSEMBLER_NAME(Node)); >> } >> } >> - return ""; >> + return NULL; >> } >> >> DebugInfo::DebugInfo(Module *m) >> @@ -211,12 +211,11 @@ >> // Gather location information. >> expanded_location Loc = GetNodeLocation(FnDecl, false); >> const char *LinkageName = getLinkageName(FnDecl); >> - >> + const char *FnName = lang_hooks.dwarf_name(FnDecl, 0); >> DISubprogram SP = >> DebugFactory.CreateSubprogram(findRegion(FnDecl), >> - lang_hooks.dwarf_name(FnDecl, 0), >> - lang_hooks.dwarf_name(FnDecl, 0), >> - LinkageName, >> + FnName, FnName, >> + LinkageName ? LinkageName : >> FnName, >> getOrCreateCompileUnit(Loc.file), >> CurLineNo, >> getOrCreateType(TREE_TYPE(FnDecl)), >> Fn->hasInternalLinkage(), >> @@ -345,11 +344,11 @@ >> if (IDENTIFIER_POINTER(DECL_NAME(decl))) >> DispName = IDENTIFIER_POINTER(DECL_NAME(decl)); >> } >> - >> + const char *LinkageName = getLinkageName(decl); >> DebugFactory.CreateGlobalVariable(getOrCreateCompileUnit(Loc.file), >> GV->getNameStr(), >> DispName, >> - getLinkageName(decl), >> + LinkageName ? LinkageName : >> DispName, >> >> getOrCreateCompileUnit(Loc.file), Loc.line, >> TyD, GV->hasInternalLinkage(), >> true/*definition*/, GV); >> @@ -668,7 +667,7 @@ >> DIType SPTy = getOrCreateType(TREE_TYPE(Member)); >> DISubprogram SP = >> DebugFactory.CreateSubprogram(findRegion(Member), MemberName, >> MemberName, >> - LinkageName, >> + LinkageName ? LinkageName : >> MemberName, >> >> getOrCreateCompileUnit(MemLoc.file), >> MemLoc.line, SPTy, false, false); >> EltTys.push_back(SP); >> >> >> _______________________________________________ >> 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 clattner at apple.com Mon Apr 13 15:12:19 2009 From: clattner at apple.com (Chris Lattner) Date: Mon, 13 Apr 2009 13:12:19 -0700 Subject: [llvm-commits] [llvm] r68940 - in /llvm/trunk: docs/ include/llvm/ include/llvm/CodeGen/ lib/AsmParser/ lib/Bitcode/Reader/ lib/Bitcode/Writer/ lib/CodeGen/ lib/CodeGen/AsmPrinter/ lib/Linker/ lib/Target/CppBackend/ lib/VMCore/ test/CodeGen/Gener In-Reply-To: References: <41F740D6-23D6-413A-BDBA-598D5892DF89@apple.com> Message-ID: <065E7D4A-EEF1-40B2-BFC0-B9FBA02F48A2@apple.com> On Apr 13, 2009, at 12:59 PM, Eli Friedman wrote: > On Mon, Apr 13, 2009 at 11:16 AM, Chris Lattner > wrote: >> This could be handled by having the linker drop >> "available_externally" >> symbols when it does linking, but do you expect this to be a problem >> in practice? Why would it be ok to inline a body in one translation >> unit but not in another? > >> From the C99 rationale: "Second, the requirement that all definitions > of an inline function be 'exactly the same' is replaced by the > requirement that the behavior of the program should not depend on > whether a call is implemented with a visible inline definition, or the > external definition, of a function. This allows an inline definition > to be specialized for its use within a particular translation unit. > For example, the external definition of a library function might > include some argument validation that is not needed for calls made > from other functions in the same library." Consider: --- a.c int foo(); int bar() { return foo(); } --- b.c inline int foo() {return 1;} ... Do you think that it is bad to allow bar to inline the definition of foo from b.c? How important is it to worry about this? Again, it is straight-forward to throw the information away, but this pessimizes other clients (e.g. the C++ vtable example) -Chris From stoklund at 2pi.dk Mon Apr 13 15:13:39 2009 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Mon, 13 Apr 2009 22:13:39 +0200 Subject: [llvm-commits] [llvm] r68961 - in /llvm/trunk: include/llvm/Target/Target.td include/llvm/Target/TargetInstrInfo.h include/llvm/Target/TargetRegisterInfo.h lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.h lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp utils/TableGen/CodeEmitterGen.cpp utils/TableGen/CodeGenDAGPatterns.cpp utils/TableGen/CodeGenTarget.cpp utils/TableGen/DAGISelEmitter.cpp utils/TableGen/InstrInfoEmitter.cpp utils/TableGen/RegisterInfoEmitter.cpp In-Reply-To: <5BFA7225-AFD4-4BCD-9FF0-EB6F07DDDC9B@apple.com> References: <200904131538.n3DFc5h6032744@zion.cs.uiuc.edu> <5BFA7225-AFD4-4BCD-9FF0-EB6F07DDDC9B@apple.com> Message-ID: <669E3F71-005B-4164-880D-A122E223325B@2pi.dk> On 13/04/2009, at 21.49, Dan Gohman wrote: > > On Apr 13, 2009, at 9:23 AM, Jakob Stoklund Olesen wrote: >> Very nice. I wonder, is it necessary to restrict to subclasses? My >> Blackfin target has disjoint register classes, but I can still copy >> between them. COPY_TO_REGCLASS? > > With the register class enhancement changes that accompanied this > change, the code that expands post-isel SDNodes into MachineInstrs > now automatically inserts copies when needed to bridge between > different register classes. COPY_TO_SUBCLASS is only needed in > situations where the the register class of the virtual registers > needs to be something other than what the instruction patterns > indicate they require. Right, like the EXTRACT_SUBREG patterns in X86. > Can you give an example of a pattern where this would be used? Not a really good one, it just seemed like an unnecessary restriction. On Blackfin, I have register classes D for data, P for pointers. The classes are disjoint. I can only access subregisters in the D class, so a pattern fragment like this is not unthinkable: (EXTRACT_SUBREG (COPY_TO_REGCLASS P:$ptr, D), bfin_subreg_lo16) EXTRACT_SUBREG doesn't know what regclass to expect, so the automatic copies won't work. I don't actually have any patterns like that, so it is no big deal. From bob.wilson at apple.com Mon Apr 13 15:20:30 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Mon, 13 Apr 2009 20:20:30 -0000 Subject: [llvm-commits] [llvm] r68981 - /llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200904132020.n3DKKVI9011320@zion.cs.uiuc.edu> Author: bwilson Date: Mon Apr 13 15:20:30 2009 New Revision: 68981 URL: http://llvm.org/viewvc/llvm-project?rev=68981&view=rev Log: Refactor some code in SelectionDAGLegalize::ExpandBUILD_VECTOR. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=68981&r1=68980&r2=68981&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Mon Apr 13 15:20:30 2009 @@ -5476,13 +5476,16 @@ /// ExpandBUILD_VECTOR - Expand a BUILD_VECTOR node on targets that don't /// support the operation, but do support the resultant vector type. SDValue SelectionDAGLegalize::ExpandBUILD_VECTOR(SDNode *Node) { + unsigned NumElems = Node->getNumOperands(); + SDValue SplatValue = Node->getOperand(0); + DebugLoc dl = Node->getDebugLoc(); + MVT VT = Node->getValueType(0); + MVT OpVT = SplatValue.getValueType(); + MVT EltVT = VT.getVectorElementType(); // If the only non-undef value is the low element, turn this into a // SCALAR_TO_VECTOR node. If this is { X, X, X, X }, determine X. - unsigned NumElems = Node->getNumOperands(); bool isOnlyLowElement = true; - SDValue SplatValue = Node->getOperand(0); - DebugLoc dl = Node->getDebugLoc(); // FIXME: it would be far nicer to change this into map // and use a bitmask instead of a list of elements. @@ -5511,15 +5514,13 @@ if (isOnlyLowElement) { // If the low element is an undef too, then this whole things is an undef. if (Node->getOperand(0).getOpcode() == ISD::UNDEF) - return DAG.getUNDEF(Node->getValueType(0)); + return DAG.getUNDEF(VT); // Otherwise, turn this into a scalar_to_vector node. - return DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, Node->getValueType(0), - Node->getOperand(0)); + return DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VT, Node->getOperand(0)); } // If all elements are constants, create a load from the constant pool. if (isConstant) { - MVT VT = Node->getValueType(0); std::vector CV; for (unsigned i = 0, e = NumElems; i != e; ++i) { if (ConstantFPSDNode *V = @@ -5530,8 +5531,7 @@ CV.push_back(const_cast(V->getConstantIntValue())); } else { assert(Node->getOperand(i).getOpcode() == ISD::UNDEF); - const Type *OpNTy = - Node->getOperand(0).getValueType().getTypeForMVT(); + const Type *OpNTy = OpVT.getTypeForMVT(); CV.push_back(UndefValue::get(OpNTy)); } } @@ -5552,17 +5552,14 @@ &ZeroVec[0], ZeroVec.size()); // If the target supports VECTOR_SHUFFLE and this shuffle mask, use it. - if (isShuffleLegal(Node->getValueType(0), SplatMask)) { + if (isShuffleLegal(VT, SplatMask)) { // Get the splatted value into the low element of a vector register. SDValue LowValVec = - DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, - Node->getValueType(0), SplatValue); + DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VT, SplatValue); // Return shuffle(LowValVec, undef, <0,0,0,0>) - return DAG.getNode(ISD::VECTOR_SHUFFLE, dl, - Node->getValueType(0), LowValVec, - DAG.getUNDEF(Node->getValueType(0)), - SplatMask); + return DAG.getNode(ISD::VECTOR_SHUFFLE, dl, VT, LowValVec, + DAG.getUNDEF(VT), SplatMask); } } @@ -5605,22 +5602,20 @@ &MaskVec[0], MaskVec.size()); // If the target supports SCALAR_TO_VECTOR and this shuffle mask, use it. - if (TLI.isOperationLegalOrCustom(ISD::SCALAR_TO_VECTOR, - Node->getValueType(0)) && - isShuffleLegal(Node->getValueType(0), ShuffleMask)) { - Val1 = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl,Node->getValueType(0), Val1); - Val2 = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl,Node->getValueType(0), Val2); + if (TLI.isOperationLegalOrCustom(ISD::SCALAR_TO_VECTOR, VT) && + isShuffleLegal(VT, ShuffleMask)) { + Val1 = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VT, Val1); + Val2 = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VT, Val2); SDValue Ops[] = { Val1, Val2, ShuffleMask }; // Return shuffle(LoValVec, HiValVec, <0,1,0,1>) - return DAG.getNode(ISD::VECTOR_SHUFFLE, dl,Node->getValueType(0), Ops, 3); + return DAG.getNode(ISD::VECTOR_SHUFFLE, dl, VT, Ops, 3); } } // Otherwise, we can't handle this case efficiently. Allocate a sufficiently // aligned object on the stack, store each element into it, then load // the result as a vector. - MVT VT = Node->getValueType(0); // Create the stack frame object. SDValue FIPtr = DAG.CreateStackTemporary(VT); int FI = cast(FIPtr.getNode())->getIndex(); @@ -5628,7 +5623,7 @@ // Emit a store of each element to the stack slot. SmallVector Stores; - unsigned TypeByteSize = Node->getOperand(0).getValueType().getSizeInBits()/8; + unsigned TypeByteSize = OpVT.getSizeInBits() / 8; // Store (in the right endianness) the elements to memory. for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) { // Ignore undef elements. From dalej at apple.com Mon Apr 13 15:22:27 2009 From: dalej at apple.com (Dale Johannesen) Date: Mon, 13 Apr 2009 13:22:27 -0700 Subject: [llvm-commits] [llvm] r68940 - in /llvm/trunk: docs/ include/llvm/ include/llvm/CodeGen/ lib/AsmParser/ lib/Bitcode/Reader/ lib/Bitcode/Writer/ lib/CodeGen/ lib/CodeGen/AsmPrinter/ lib/Linker/ lib/Target/CppBackend/ lib/VMCore/ test/CodeGen/Gener In-Reply-To: <065E7D4A-EEF1-40B2-BFC0-B9FBA02F48A2@apple.com> References: <41F740D6-23D6-413A-BDBA-598D5892DF89@apple.com> <065E7D4A-EEF1-40B2-BFC0-B9FBA02F48A2@apple.com> Message-ID: <9CF64C70-B3B6-48F6-9933-E755A08113FC@apple.com> On Apr 13, 2009, at 1:12 PMPDT, Chris Lattner wrote: > > On Apr 13, 2009, at 12:59 PM, Eli Friedman wrote: > >> On Mon, Apr 13, 2009 at 11:16 AM, Chris Lattner >> wrote: >>> This could be handled by having the linker drop >>> "available_externally" >>> symbols when it does linking, but do you expect this to be a problem >>> in practice? Why would it be ok to inline a body in one translation >>> unit but not in another? >> >>> From the C99 rationale: "Second, the requirement that all >>> definitions >> of an inline function be 'exactly the same' is replaced by the >> requirement that the behavior of the program should not depend on >> whether a call is implemented with a visible inline definition, or >> the >> external definition, of a function. This allows an inline definition >> to be specialized for its use within a particular translation unit. >> For example, the external definition of a library function might >> include some argument validation that is not needed for calls made >> from other functions in the same library." I guess it's time to point out that making inline definitions available in the wrong files can produce incorrect results: /* file 1 */ extern int foo(); inline void inn(int i) { printf("1\n"); } main() { foo(); inn(1); } /* file 2 */ inline void inn(int i) { printf("2\n"); } int foo() { inn(2); } /* file 3 */ void inn(int i) { printf("%d\n", i); } From mrs at apple.com Mon Apr 13 15:59:47 2009 From: mrs at apple.com (Mike Stump) Date: Mon, 13 Apr 2009 13:59:47 -0700 Subject: [llvm-commits] [llvm] r68912 - in /llvm/trunk/examples: CMakeLists.txt Kaleidoscope/ Kaleidoscope/CMakeLists.txt Kaleidoscope/Makefile Kaleidoscope/toy.cpp Makefile In-Reply-To: <200904122047.n3CKlOGL014503@zion.cs.uiuc.edu> References: <200904122047.n3CKlOGL014503@zion.cs.uiuc.edu> Message-ID: <44C779D1-4995-4659-8785-811D32930B5E@apple.com> On Apr 12, 2009, at 1:47 PM, Nick Lewycky wrote: > Author: nicholas > Date: Sun Apr 12 15:47:23 2009 > New Revision: 68912 > > URL: http://llvm.org/viewvc/llvm-project?rev=68912&view=rev > Log: > Add Kaleidoscope to examples I think this causes: llvm/examples/Kaleidoscope/toy.cpp: In function ?void HandleTopLevelExpression()?: llvm/examples/Kaleidoscope/toy.cpp:1036: warning: ISO C++ forbids casting between pointer-to-function and pointer-to-object From eli.friedman at gmail.com Mon Apr 13 16:03:20 2009 From: eli.friedman at gmail.com (Eli Friedman) Date: Mon, 13 Apr 2009 14:03:20 -0700 Subject: [llvm-commits] [llvm] r68940 - in /llvm/trunk: docs/ include/llvm/ include/llvm/CodeGen/ lib/AsmParser/ lib/Bitcode/Reader/ lib/Bitcode/Writer/ lib/CodeGen/ lib/CodeGen/AsmPrinter/ lib/Linker/ lib/Target/CppBackend/ lib/VMCore/ test/CodeGen/Gener In-Reply-To: <065E7D4A-EEF1-40B2-BFC0-B9FBA02F48A2@apple.com> References: <41F740D6-23D6-413A-BDBA-598D5892DF89@apple.com> <065E7D4A-EEF1-40B2-BFC0-B9FBA02F48A2@apple.com> Message-ID: On Mon, Apr 13, 2009 at 1:12 PM, Chris Lattner wrote: > Consider: > > --- a.c > int foo(); > int bar() { return foo(); } > --- b.c > inline int foo() {return 1;} > ... > > Do you think that it is bad to allow bar to inline the definition of > foo from b.c? ?How important is it to worry about this? It can lead to wrong code generation. The importance is hard to judge. > Again, it is > straight-forward to throw the information away, but this pessimizes > other clients (e.g. the C++ vtable example) C99 semantics minimally require something like the following for an inline function: If only one of the files provides a declaration or definition of the given symbol, we can keep it. If two files provide identical definitions with available_externally, we can keep either one. Otherwise, we must discard both. I think this scheme addresses the C++ vtable example. Otherwise, we can always add available_externally_odr :) Of course, we could implement C99 inline purely in the front-end: we just emit the inline version as an internal function with a different name, and make direct calls use that instead of the external version. -Eli From gohman at apple.com Mon Apr 13 16:06:26 2009 From: gohman at apple.com (Dan Gohman) Date: Mon, 13 Apr 2009 21:06:26 -0000 Subject: [llvm-commits] [llvm] r68986 - in /llvm/trunk: include/llvm/Target/Target.td include/llvm/Target/TargetInstrInfo.h lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.h lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp lib/Target/X86/X86Instr64bit.td lib/Target/X86/X86InstrInfo.td utils/TableGen/CodeEmitterGen.cpp utils/TableGen/CodeGenDAGPatterns.cpp utils/TableGen/CodeGenTarget.cpp utils/TableGen/InstrInfoEmitter.cpp Message-ID: <200904132106.n3DL6QBZ013000@zion.cs.uiuc.edu> Author: djg Date: Mon Apr 13 16:06:25 2009 New Revision: 68986 URL: http://llvm.org/viewvc/llvm-project?rev=68986&view=rev Log: Rename COPY_TO_SUBCLASS to COPY_TO_REGCLASS, and generalize it accordingly. Thanks to Jakob Stoklund Olesen for pointing out how this might be useful. Modified: llvm/trunk/include/llvm/Target/Target.td llvm/trunk/include/llvm/Target/TargetInstrInfo.h llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.h llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp llvm/trunk/lib/Target/X86/X86Instr64bit.td llvm/trunk/lib/Target/X86/X86InstrInfo.td llvm/trunk/utils/TableGen/CodeEmitterGen.cpp llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp llvm/trunk/utils/TableGen/CodeGenTarget.cpp llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp Modified: llvm/trunk/include/llvm/Target/Target.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/Target.td?rev=68986&r1=68985&r2=68986&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/Target.td (original) +++ llvm/trunk/include/llvm/Target/Target.td Mon Apr 13 16:06:25 2009 @@ -400,7 +400,7 @@ let Namespace = "TargetInstrInfo"; let neverHasSideEffects = 1; } -def COPY_TO_SUBCLASS : Instruction { +def COPY_TO_REGCLASS : Instruction { let OutOperandList = (ops unknown:$dst); let InOperandList = (ops unknown:$src, i32imm:$regclass); let AsmString = ""; Modified: llvm/trunk/include/llvm/Target/TargetInstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetInstrInfo.h?rev=68986&r1=68985&r2=68986&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetInstrInfo.h (original) +++ llvm/trunk/include/llvm/Target/TargetInstrInfo.h Mon Apr 13 16:06:25 2009 @@ -75,12 +75,14 @@ /// zext from i32 to i64 via implicit zero-extension). SUBREG_TO_REG = 9, - /// COPY_TO_SUBCLASS - This instruction is a placeholder for a plain + /// COPY_TO_REGCLASS - This instruction is a placeholder for a plain /// register-to-register copy into a specific register class. This is only /// used between instruction selection and MachineInstr creation, before - /// virtual registers have been created for all the instructions. As with - /// normal copies, these may be optimized away by the coalescer. - COPY_TO_SUBCLASS = 10 + /// virtual registers have been created for all the instructions, and it's + /// only needed in cases where the register classes implied by the + /// instructions are insufficient. The actual MachineInstrs to perform + /// the copy are emitted with the TargetInstrInfo::copyRegToReg hook. + COPY_TO_REGCLASS = 10 }; unsigned getNumOpcodes() const { return NumOpcodes; } Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.h?rev=68986&r1=68985&r2=68986&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.h (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.h Mon Apr 13 16:06:25 2009 @@ -134,10 +134,10 @@ void EmitSubregNode(SDNode *Node, DenseMap &VRBaseMap); - /// EmitCopyToSubclassNode - Generate machine code for COPY_TO_SUBCLASS + /// EmitCopyToRegClassNode - Generate machine code for COPY_TO_REGCLASS /// nodes. /// - void EmitCopyToSubclassNode(SDNode *Node, + void EmitCopyToRegClassNode(SDNode *Node, DenseMap &VRBaseMap); /// getVR - Return the virtual register corresponding to the specified result Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp?rev=68986&r1=68985&r2=68986&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp Mon Apr 13 16:06:25 2009 @@ -464,12 +464,12 @@ assert(isNew && "Node emitted out of order - early"); } -/// EmitCopyToSubclassNode - Generate machine code for COPY_TO_SUBCLASS nodes. -/// COPY_TO_SUBCLASS is just a normal copy, except that the destination +/// EmitCopyToRegClassNode - Generate machine code for COPY_TO_REGCLASS nodes. +/// COPY_TO_REGCLASS is just a normal copy, except that the destination /// register is constrained to be in a particular register class. /// void -ScheduleDAGSDNodes::EmitCopyToSubclassNode(SDNode *Node, +ScheduleDAGSDNodes::EmitCopyToRegClassNode(SDNode *Node, DenseMap &VRBaseMap) { unsigned VReg = getVR(Node->getOperand(0), VRBaseMap); const TargetRegisterClass *SrcRC = MRI.getRegClass(VReg); @@ -477,19 +477,18 @@ unsigned DstRCIdx = cast(Node->getOperand(1))->getZExtValue(); const TargetRegisterClass *DstRC = TRI->getRegClass(DstRCIdx); - assert(SrcRC->hasSubClass(DstRC) && - "COPY_TO_SUBCLASS destination class is not a proper subclass!"); - // Create the new VReg in the destination class and emit a copy. unsigned NewVReg = MRI.createVirtualRegister(DstRC); bool Emitted = TII->copyRegToReg(*BB, InsertPos, NewVReg, VReg, DstRC, SrcRC); - // If the target didn't handle that, emit a plain copy. - if (!Emitted) + // If the target didn't handle the copy with different register + // classes and the destination is a subset of the source, + // try a normal same-RC copy. + if (!Emitted && SrcRC->hasSubClass(DstRC)) Emitted = TII->copyRegToReg(*BB, InsertPos, NewVReg, VReg, SrcRC, SrcRC); assert(Emitted && - "Unable to issue a copy instruction for a COPY_TO_SUBCLASS node!\n"); + "Unable to issue a copy instruction for a COPY_TO_REGCLASS node!\n"); SDValue Op(Node, 0); bool isNew = VRBaseMap.insert(std::make_pair(Op, NewVReg)).second; @@ -513,9 +512,9 @@ return; } - // Handle COPY_TO_SUBCLASS specially. - if (Opc == TargetInstrInfo::COPY_TO_SUBCLASS) { - EmitCopyToSubclassNode(Node, VRBaseMap); + // Handle COPY_TO_REGCLASS specially. + if (Opc == TargetInstrInfo::COPY_TO_REGCLASS) { + EmitCopyToRegClassNode(Node, VRBaseMap); return; } Modified: llvm/trunk/lib/Target/X86/X86Instr64bit.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Instr64bit.td?rev=68986&r1=68985&r2=68986&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86Instr64bit.td (original) +++ llvm/trunk/lib/Target/X86/X86Instr64bit.td Mon Apr 13 16:06:25 2009 @@ -1578,18 +1578,18 @@ (SUBREG_TO_REG (i64 0), (MOVZX32_NOREXrr8 - (EXTRACT_SUBREG (COPY_TO_SUBCLASS GR64:$src, GR64_), + (EXTRACT_SUBREG (COPY_TO_REGCLASS GR64:$src, GR64_), x86_subreg_8bit_hi)), x86_subreg_32bit)>; def : Pat<(and (srl_su GR32:$src, (i8 8)), (i32 255)), (MOVZX32_NOREXrr8 - (EXTRACT_SUBREG (COPY_TO_SUBCLASS GR32:$src, GR32_), + (EXTRACT_SUBREG (COPY_TO_REGCLASS GR32:$src, GR32_), x86_subreg_8bit_hi))>, Requires<[In64BitMode]>; def : Pat<(srl_su GR16:$src, (i8 8)), (EXTRACT_SUBREG (MOVZX32_NOREXrr8 - (EXTRACT_SUBREG (COPY_TO_SUBCLASS GR16:$src, GR16_), + (EXTRACT_SUBREG (COPY_TO_REGCLASS GR16:$src, GR16_), x86_subreg_8bit_hi)), x86_subreg_16bit)>, Requires<[In64BitMode]>; @@ -1598,18 +1598,18 @@ def : Pat<(store (i8 (trunc_su (srl_su GR64:$src, (i8 8)))), addr:$dst), (MOV8mr_NOREX addr:$dst, - (EXTRACT_SUBREG (COPY_TO_SUBCLASS GR64:$src, GR64_), + (EXTRACT_SUBREG (COPY_TO_REGCLASS GR64:$src, GR64_), x86_subreg_8bit_hi))>; def : Pat<(store (i8 (trunc_su (srl_su GR32:$src, (i8 8)))), addr:$dst), (MOV8mr_NOREX addr:$dst, - (EXTRACT_SUBREG (COPY_TO_SUBCLASS GR32:$src, GR32_), + (EXTRACT_SUBREG (COPY_TO_REGCLASS GR32:$src, GR32_), x86_subreg_8bit_hi))>, Requires<[In64BitMode]>; def : Pat<(store (i8 (trunc_su (srl_su GR16:$src, (i8 8)))), addr:$dst), (MOV8mr_NOREX addr:$dst, - (EXTRACT_SUBREG (COPY_TO_SUBCLASS GR16:$src, GR16_), + (EXTRACT_SUBREG (COPY_TO_REGCLASS GR16:$src, GR16_), x86_subreg_8bit_hi))>, Requires<[In64BitMode]>; Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=68986&r1=68985&r2=68986&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Mon Apr 13 16:06:25 2009 @@ -3349,12 +3349,12 @@ (MOVZX32rr16 (EXTRACT_SUBREG GR32:$src1, x86_subreg_16bit))>; // r & (2^8-1) ==> movz def : Pat<(and GR32:$src1, 0xff), - (MOVZX32rr8 (EXTRACT_SUBREG (COPY_TO_SUBCLASS GR32:$src1, GR32_), + (MOVZX32rr8 (EXTRACT_SUBREG (COPY_TO_REGCLASS GR32:$src1, GR32_), x86_subreg_8bit))>, Requires<[In32BitMode]>; // r & (2^8-1) ==> movz def : Pat<(and GR16:$src1, 0xff), - (MOVZX16rr8 (EXTRACT_SUBREG (COPY_TO_SUBCLASS GR16:$src1, GR16_), + (MOVZX16rr8 (EXTRACT_SUBREG (COPY_TO_REGCLASS GR16:$src1, GR16_), x86_subreg_8bit))>, Requires<[In32BitMode]>; @@ -3362,11 +3362,11 @@ def : Pat<(sext_inreg GR32:$src, i16), (MOVSX32rr16 (EXTRACT_SUBREG GR32:$src, x86_subreg_16bit))>; def : Pat<(sext_inreg GR32:$src, i8), - (MOVSX32rr8 (EXTRACT_SUBREG (COPY_TO_SUBCLASS GR32:$src, GR32_), + (MOVSX32rr8 (EXTRACT_SUBREG (COPY_TO_REGCLASS GR32:$src, GR32_), x86_subreg_8bit))>, Requires<[In32BitMode]>; def : Pat<(sext_inreg GR16:$src, i8), - (MOVSX16rr8 (EXTRACT_SUBREG (COPY_TO_SUBCLASS GR16:$src, GR16_), + (MOVSX16rr8 (EXTRACT_SUBREG (COPY_TO_REGCLASS GR16:$src, GR16_), x86_subreg_8bit))>, Requires<[In32BitMode]>; @@ -3374,32 +3374,32 @@ def : Pat<(i16 (trunc GR32:$src)), (EXTRACT_SUBREG GR32:$src, x86_subreg_16bit)>; def : Pat<(i8 (trunc GR32:$src)), - (EXTRACT_SUBREG (COPY_TO_SUBCLASS GR32:$src, GR32_), + (EXTRACT_SUBREG (COPY_TO_REGCLASS GR32:$src, GR32_), x86_subreg_8bit)>, Requires<[In32BitMode]>; def : Pat<(i8 (trunc GR16:$src)), - (EXTRACT_SUBREG (COPY_TO_SUBCLASS GR16:$src, GR16_), + (EXTRACT_SUBREG (COPY_TO_REGCLASS GR16:$src, GR16_), x86_subreg_8bit)>, Requires<[In32BitMode]>; // h-register tricks def : Pat<(i8 (trunc (srl_su GR16:$src, (i8 8)))), - (EXTRACT_SUBREG (COPY_TO_SUBCLASS GR16:$src, GR16_), + (EXTRACT_SUBREG (COPY_TO_REGCLASS GR16:$src, GR16_), x86_subreg_8bit_hi)>, Requires<[In32BitMode]>; def : Pat<(i8 (trunc (srl_su GR32:$src, (i8 8)))), - (EXTRACT_SUBREG (COPY_TO_SUBCLASS GR32:$src, GR32_), + (EXTRACT_SUBREG (COPY_TO_REGCLASS GR32:$src, GR32_), x86_subreg_8bit_hi)>, Requires<[In32BitMode]>; def : Pat<(srl_su GR16:$src, (i8 8)), (EXTRACT_SUBREG (MOVZX32rr8 - (EXTRACT_SUBREG (COPY_TO_SUBCLASS GR16:$src, GR16_), + (EXTRACT_SUBREG (COPY_TO_REGCLASS GR16:$src, GR16_), x86_subreg_8bit_hi)), x86_subreg_16bit)>, Requires<[In32BitMode]>; def : Pat<(and (srl_su GR32:$src, (i8 8)), (i32 255)), - (MOVZX32rr8 (EXTRACT_SUBREG (COPY_TO_SUBCLASS GR32:$src, GR32_), + (MOVZX32rr8 (EXTRACT_SUBREG (COPY_TO_REGCLASS GR32:$src, GR32_), x86_subreg_8bit_hi))>, Requires<[In32BitMode]>; Modified: llvm/trunk/utils/TableGen/CodeEmitterGen.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeEmitterGen.cpp?rev=68986&r1=68985&r2=68986&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/CodeEmitterGen.cpp (original) +++ llvm/trunk/utils/TableGen/CodeEmitterGen.cpp Mon Apr 13 16:06:25 2009 @@ -34,7 +34,7 @@ R->getName() == "INSERT_SUBREG" || R->getName() == "IMPLICIT_DEF" || R->getName() == "SUBREG_TO_REG" || - R->getName() == "COPY_TO_SUBCLASS") continue; + R->getName() == "COPY_TO_REGCLASS") continue; BitsInit *BI = R->getValueAsBitsInit("Inst"); @@ -111,7 +111,7 @@ R->getName() == "INSERT_SUBREG" || R->getName() == "IMPLICIT_DEF" || R->getName() == "SUBREG_TO_REG" || - R->getName() == "COPY_TO_SUBCLASS") { + R->getName() == "COPY_TO_REGCLASS") { o << " 0U,\n"; continue; } @@ -149,7 +149,7 @@ InstName == "INSERT_SUBREG" || InstName == "IMPLICIT_DEF" || InstName == "SUBREG_TO_REG" || - InstName == "COPY_TO_SUBCLASS") continue; + InstName == "COPY_TO_REGCLASS") continue; BitsInit *BI = R->getValueAsBitsInit("Inst"); const std::vector &Vals = R->getValues(); Modified: llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp?rev=68986&r1=68985&r2=68986&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp (original) +++ llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp Mon Apr 13 16:06:25 2009 @@ -884,7 +884,7 @@ MadeChange = getChild(i)->ApplyTypeConstraints(TP, NotRegisters); MadeChange |= UpdateNodeType(MVT::isVoid, TP); return MadeChange; - } else if (getOperator()->getName() == "COPY_TO_SUBCLASS") { + } else if (getOperator()->getName() == "COPY_TO_REGCLASS") { bool MadeChange = false; MadeChange |= getChild(0)->ApplyTypeConstraints(TP, NotRegisters); MadeChange |= getChild(1)->ApplyTypeConstraints(TP, NotRegisters); Modified: llvm/trunk/utils/TableGen/CodeGenTarget.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenTarget.cpp?rev=68986&r1=68985&r2=68986&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/CodeGenTarget.cpp (original) +++ llvm/trunk/utils/TableGen/CodeGenTarget.cpp Mon Apr 13 16:06:25 2009 @@ -345,10 +345,10 @@ throw "Could not find 'SUBREG_TO_REG' instruction!"; const CodeGenInstruction *SUBREG_TO_REG = &I->second; - I = getInstructions().find("COPY_TO_SUBCLASS"); + I = getInstructions().find("COPY_TO_REGCLASS"); if (I == Instructions.end()) - throw "Could not find 'COPY_TO_SUBCLASS' instruction!"; - const CodeGenInstruction *COPY_TO_SUBCLASS = &I->second; + throw "Could not find 'COPY_TO_REGCLASS' instruction!"; + const CodeGenInstruction *COPY_TO_REGCLASS = &I->second; // Print out the rest of the instructions now. NumberedInstructions.push_back(PHI); @@ -361,7 +361,7 @@ NumberedInstructions.push_back(INSERT_SUBREG); NumberedInstructions.push_back(IMPLICIT_DEF); NumberedInstructions.push_back(SUBREG_TO_REG); - NumberedInstructions.push_back(COPY_TO_SUBCLASS); + NumberedInstructions.push_back(COPY_TO_REGCLASS); for (inst_iterator II = inst_begin(), E = inst_end(); II != E; ++II) if (&II->second != PHI && &II->second != INLINEASM && @@ -373,7 +373,7 @@ &II->second != INSERT_SUBREG && &II->second != IMPLICIT_DEF && &II->second != SUBREG_TO_REG && - &II->second != COPY_TO_SUBCLASS) + &II->second != COPY_TO_REGCLASS) NumberedInstructions.push_back(&II->second); } Modified: llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp?rev=68986&r1=68985&r2=68986&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp Mon Apr 13 16:06:25 2009 @@ -341,7 +341,7 @@ R->getName() != "INSERT_SUBREG" && R->getName() != "IMPLICIT_DEF" && R->getName() != "SUBREG_TO_REG" && - R->getName() != "COPY_TO_SUBCLASS") + R->getName() != "COPY_TO_REGCLASS") throw R->getName() + " doesn't have a field named '" + Val->getValue() + "'!"; return; From isanbard at gmail.com Mon Apr 13 16:46:06 2009 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 13 Apr 2009 21:46:06 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r68993 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Message-ID: <200904132146.n3DLk6kH014647@zion.cs.uiuc.edu> Author: void Date: Mon Apr 13 16:46:05 2009 New Revision: 68993 URL: http://llvm.org/viewvc/llvm-project?rev=68993&view=rev Log: If the second argument of __builtin_longjmp isn't '1', then issue an error. GCC issues this error, but during the RTX phase. 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=68993&r1=68992&r2=68993&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Mon Apr 13 16:46:05 2009 @@ -5011,19 +5011,31 @@ #if 1 // FIXME: Should handle these GCC extensions eventually. - case BUILT_IN_APPLY_ARGS: - case BUILT_IN_APPLY: - case BUILT_IN_RETURN: - case BUILT_IN_SAVEREGS: - case BUILT_IN_ARGS_INFO: - case BUILT_IN_NEXT_ARG: - case BUILT_IN_CLASSIFY_TYPE: - case BUILT_IN_AGGREGATE_INCOMING_ADDRESS: - case BUILT_IN_SETJMP_SETUP: - case BUILT_IN_SETJMP_DISPATCHER: - case BUILT_IN_SETJMP_RECEIVER: - case BUILT_IN_LONGJMP: - case BUILT_IN_UPDATE_SETJMP_BUF: + case BUILT_IN_LONGJMP: { + tree arglist = TREE_OPERAND(exp, 1); + + if (validate_arglist(arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) { + tree value = TREE_VALUE(TREE_CHAIN(arglist)); + + if (TREE_CODE(value) != INTEGER_CST || + cast(Emit(value, 0))->getValue() != 1) { + error ("%<__builtin_longjmp%> second argument must be 1"); + return false; + } + } + } + case BUILT_IN_APPLY_ARGS: + case BUILT_IN_APPLY: + case BUILT_IN_RETURN: + case BUILT_IN_SAVEREGS: + case BUILT_IN_ARGS_INFO: + case BUILT_IN_NEXT_ARG: + case BUILT_IN_CLASSIFY_TYPE: + case BUILT_IN_AGGREGATE_INCOMING_ADDRESS: + case BUILT_IN_SETJMP_SETUP: + case BUILT_IN_SETJMP_DISPATCHER: + case BUILT_IN_SETJMP_RECEIVER: + case BUILT_IN_UPDATE_SETJMP_BUF: // FIXME: HACK: Just ignore these. { From isanbard at gmail.com Mon Apr 13 17:01:47 2009 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 13 Apr 2009 15:01:47 -0700 Subject: [llvm-commits] [llvm] r68912 - in /llvm/trunk/examples: CMakeLists.txt Kaleidoscope/ Kaleidoscope/CMakeLists.txt Kaleidoscope/Makefile Kaleidoscope/toy.cpp Makefile In-Reply-To: <44C779D1-4995-4659-8785-811D32930B5E@apple.com> References: <200904122047.n3CKlOGL014503@zion.cs.uiuc.edu> <44C779D1-4995-4659-8785-811D32930B5E@apple.com> Message-ID: <16e5fdf90904131501m35913725ha2371c40d9247b85@mail.gmail.com> On Mon, Apr 13, 2009 at 1:59 PM, Mike Stump wrote: > On Apr 12, 2009, at 1:47 PM, Nick Lewycky wrote: >> Author: nicholas >> Date: Sun Apr 12 15:47:23 2009 >> New Revision: 68912 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=68912&view=rev >> Log: >> Add Kaleidoscope to examples > > I think this causes: > > llvm/examples/Kaleidoscope/toy.cpp: In function ?void > HandleTopLevelExpression()?: > llvm/examples/Kaleidoscope/toy.cpp:1036: warning: ISO C++ forbids > casting between pointer-to-function and pointer-to-object > It does. I looked at it (while fixing other warnings), and I'm not sure what the proper fix for that is... -bw From bob.wilson at apple.com Mon Apr 13 17:05:19 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Mon, 13 Apr 2009 22:05:19 -0000 Subject: [llvm-commits] [llvm] r68996 - in /llvm/trunk: include/llvm/CodeGen/SelectionDAGNodes.h lib/CodeGen/SelectionDAG/DAGCombiner.cpp lib/CodeGen/SelectionDAG/LegalizeDAG.cpp lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200904132205.n3DM5JYn015331@zion.cs.uiuc.edu> Author: bwilson Date: Mon Apr 13 17:05:19 2009 New Revision: 68996 URL: http://llvm.org/viewvc/llvm-project?rev=68996&view=rev Log: Change SelectionDAG type legalization to allow BUILD_VECTOR operands to be promoted to legal types without changing the type of the vector. This is following a suggestion from Duncan (http://lists.cs.uiuc.edu/pipermail/llvmdev/2009-February/019923.html). The transformation that used to be done during type legalization is now postponed to DAG legalization. This allows the BUILD_VECTORs to be optimized and potentially handled specially by target-specific code. It turns out that this is also consistent with an optimization done by the DAG combiner: a BUILD_VECTOR and INSERT_VECTOR_ELT may be combined by replacing one of the BUILD_VECTOR operands with the newly inserted element; but INSERT_VECTOR_ELT allows its scalar operand to be larger than the element type, with any extra high bits being implicitly truncated. The result is a BUILD_VECTOR where one of the operands has a type larger the the vector element type. Any code that operates on BUILD_VECTORs may now need to be aware of the potential type discrepancy between the vector element type and the BUILD_VECTOR operands. This patch updates all of the places that I could find to handle that case. Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp 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=68996&r1=68995&r2=68996&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h (original) +++ llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h Mon Apr 13 17:05:19 2009 @@ -290,7 +290,11 @@ /// BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a vector /// with the specified, possibly variable, elements. The number of elements - /// is required to be a power of two. + /// is required to be a power of two. The types of the operands must + /// all be the same. They must match the vector element type, except if an + /// integer element type is not legal for the target, the operands may + /// be promoted to a legal type, in which case the operands are implicitly + /// truncated to the vector element types. BUILD_VECTOR, /// INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=68996&r1=68995&r2=68996&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Mon Apr 13 17:05:19 2009 @@ -3795,7 +3795,7 @@ /// destination element value type. SDValue DAGCombiner:: ConstantFoldBIT_CONVERTofBUILD_VECTOR(SDNode *BV, MVT DstEltVT) { - MVT SrcEltVT = BV->getOperand(0).getValueType(); + MVT SrcEltVT = BV->getValueType(0).getVectorElementType(); // If this is already the right type, we're done. if (SrcEltVT == DstEltVT) return SDValue(BV, 0); @@ -3808,8 +3808,17 @@ if (SrcBitSize == DstBitSize) { SmallVector Ops; for (unsigned i = 0, e = BV->getNumOperands(); i != e; ++i) { + SDValue Op = BV->getOperand(i); + // If the vector element type is not legal, the BUILD_VECTOR operands + // are promoted and implicitly truncated. Make that explicit here. + if (Op.getValueType() != SrcEltVT) { + if (Op.getOpcode() == ISD::UNDEF) + Op = DAG.getUNDEF(SrcEltVT); + else + Op = DAG.getNode(ISD::TRUNCATE, BV->getDebugLoc(), SrcEltVT, Op); + } Ops.push_back(DAG.getNode(ISD::BIT_CONVERT, BV->getDebugLoc(), - DstEltVT, BV->getOperand(i))); + DstEltVT, Op)); AddToWorkList(Ops.back().getNode()); } MVT VT = MVT::getVectorVT(DstEltVT, @@ -3860,8 +3869,8 @@ if (Op.getOpcode() == ISD::UNDEF) continue; EltIsUndef = false; - NewBits |= - APInt(cast(Op)->getAPIntValue()).zext(DstBitSize); + NewBits |= (APInt(cast(Op)->getAPIntValue()). + zextOrTrunc(SrcBitSize).zext(DstBitSize)); } if (EltIsUndef) @@ -3889,7 +3898,8 @@ continue; } - APInt OpVal = cast(BV->getOperand(i))->getAPIntValue(); + APInt OpVal = APInt(cast(BV->getOperand(i))-> + getAPIntValue()).zextOrTrunc(SrcBitSize); for (unsigned j = 0; j != NumOutputsPerInput; ++j) { APInt ThisVal = APInt(OpVal).trunc(DstBitSize); Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=68996&r1=68995&r2=68996&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Mon Apr 13 17:05:19 2009 @@ -5483,6 +5483,41 @@ MVT OpVT = SplatValue.getValueType(); MVT EltVT = VT.getVectorElementType(); + // Check if the BUILD_VECTOR operands were promoted to legalize their types. + if (OpVT != EltVT) { + // Now that the DAG combiner and target-specific lowering have had a + // chance to optimize/recognize the BUILD_VECTOR with promoted operands, + // transform it so the operand types match the vector. Build a vector of + // half the length out of elements of twice the bitwidth. + // For example <4 x i16> -> <2 x i32>. + MVT NewVT = MVT::getIntegerVT(2 * EltVT.getSizeInBits()); + assert(OpVT.isSimple() && NewVT.isSimple()); + SmallVector NewElts; + + for (unsigned i = 0; i < NumElems; i += 2) { + // Combine two successive elements into one promoted element. + SDValue Lo = Node->getOperand(i); + SDValue Hi = Node->getOperand(i+1); + if (TLI.isBigEndian()) + std::swap(Lo, Hi); + Lo = DAG.getZeroExtendInReg(Lo, dl, EltVT); + Hi = DAG.getNode(ISD::SHL, dl, OpVT, Hi, + DAG.getConstant(EltVT.getSizeInBits(), + TLI.getPointerTy())); + NewElts.push_back(DAG.getNode(ISD::OR, dl, OpVT, Lo, Hi)); + } + + SDValue NewVec = DAG.getNode(ISD::BUILD_VECTOR, dl, + MVT::getVectorVT(NewVT, NewElts.size()), + &NewElts[0], NewElts.size()); + + // Recurse + NewVec = ExpandBUILD_VECTOR(NewVec.getNode()); + + // Convert the new vector to the old vector type. + return DAG.getNode(ISD::BIT_CONVERT, dl, VT, NewVec); + } + // If the only non-undef value is the low element, turn this into a // SCALAR_TO_VECTOR node. If this is { X, X, X, X }, determine X. bool isOnlyLowElement = true; Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp?rev=68996&r1=68995&r2=68996&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp Mon Apr 13 17:05:19 2009 @@ -799,32 +799,20 @@ MVT VecVT = N->getValueType(0); unsigned NumElts = VecVT.getVectorNumElements(); assert(!(NumElts & 1) && "Legal vector of one illegal element?"); - DebugLoc dl = N->getDebugLoc(); - - // Build a vector of half the length out of elements of twice the bitwidth. - // For example <4 x i16> -> <2 x i32>. - MVT OldVT = N->getOperand(0).getValueType(); - MVT NewVT = MVT::getIntegerVT(2 * OldVT.getSizeInBits()); - assert(OldVT.isSimple() && NewVT.isSimple()); - std::vector NewElts; - NewElts.reserve(NumElts/2); - - for (unsigned i = 0; i < NumElts; i += 2) { - // Combine two successive elements into one promoted element. - SDValue Lo = N->getOperand(i); - SDValue Hi = N->getOperand(i+1); - if (TLI.isBigEndian()) - std::swap(Lo, Hi); - NewElts.push_back(JoinIntegers(Lo, Hi)); + // Promote the inserted value. The type does not need to match the + // vector element type. Check that any extra bits introduced will be + // truncated away. + assert(N->getOperand(0).getValueType().getSizeInBits() >= + N->getValueType(0).getVectorElementType().getSizeInBits() && + "Type of inserted value narrower than vector element type!"); + + SmallVector NewOps; + for (unsigned i = 0; i < NumElts; ++i) { + NewOps.push_back(GetPromotedInteger(N->getOperand(i))); } - SDValue NewVec = DAG.getNode(ISD::BUILD_VECTOR, dl, - MVT::getVectorVT(NewVT, NewElts.size()), - &NewElts[0], NewElts.size()); - - // Convert the new vector to the old vector type. - return DAG.getNode(ISD::BIT_CONVERT, dl, VecVT, NewVec); + return DAG.UpdateNodeOperands(SDValue(N, 0), &NewOps[0], NumElts); } SDValue DAGTypeLegalizer::PromoteIntOp_CONVERT_RNDSAT(SDNode *N) { Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp?rev=68996&r1=68995&r2=68996&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp Mon Apr 13 17:05:19 2009 @@ -278,6 +278,9 @@ MVT NewVT = TLI.getTypeToTransformTo(OldVT); DebugLoc dl = N->getDebugLoc(); + assert(OldVT == VecVT.getVectorElementType() && + "BUILD_VECTOR operand type doesn't match vector element type!"); + // Build a vector of twice the length out of the expanded elements. // For example <3 x i64> -> <6 x i32>. std::vector NewElts; Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=68996&r1=68995&r2=68996&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Mon Apr 13 17:05:19 2009 @@ -768,7 +768,8 @@ // following checks at least makes it possible to legalize most of the time. // MVT EltVT = N->getValueType(0).getVectorElementType(); // for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); I != E; ++I) -// assert(I->getValueType() == EltVT && +// assert((I->getValueType() == EltVT || +// I->getValueType() == TLI.getTypeToTransformTo(EltVT)) && // "Wrong operand type!"); break; } @@ -2550,8 +2551,17 @@ // EXTRACT_VECTOR_ELT of BUILD_VECTOR is often formed while lowering is // expanding large vector constants. - if (N2C && N1.getOpcode() == ISD::BUILD_VECTOR) - return N1.getOperand(N2C->getZExtValue()); + if (N2C && N1.getOpcode() == ISD::BUILD_VECTOR) { + SDValue Elt = N1.getOperand(N2C->getZExtValue()); + if (Elt.getValueType() != VT) { + // If the vector element type is not legal, the BUILD_VECTOR operands + // are promoted and implicitly truncated. Make that explicit here. + assert(Elt.getValueType() == TLI.getTypeToTransformTo(VT) && + "Bad type for BUILD_VECTOR operand"); + Elt = getNode(ISD::TRUNCATE, DL, VT, Elt); + } + return Elt; + } // EXTRACT_VECTOR_ELT of INSERT_VECTOR_ELT is often formed when vector // operations are lowered to scalars. @@ -5569,7 +5579,8 @@ if (OpVal.getOpcode() == ISD::UNDEF) SplatUndef |= APInt::getBitsSet(sz, BitPos, BitPos +EltBitSize); else if (ConstantSDNode *CN = dyn_cast(OpVal)) - SplatValue |= APInt(CN->getAPIntValue()).zextOrTrunc(sz) << BitPos; + SplatValue |= (APInt(CN->getAPIntValue()).zextOrTrunc(EltBitSize). + zextOrTrunc(sz) << BitPos); else if (ConstantFPSDNode *CN = dyn_cast(OpVal)) SplatValue |= CN->getValueAPF().bitcastToAPInt().zextOrTrunc(sz) < Author: ddunbar Date: Mon Apr 13 17:26:09 2009 New Revision: 68998 URL: http://llvm.org/viewvc/llvm-project?rev=68998&view=rev Log: Make these errors more noticable in build logs. 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=68998&r1=68997&r2=68998&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Mon Apr 13 17:26:09 2009 @@ -5145,8 +5145,8 @@ Input.ConstraintVT.isInteger()) || (OpInfo.ConstraintVT.getSizeInBits() != Input.ConstraintVT.getSizeInBits())) { - cerr << "Unsupported asm: input constraint with a matching output " - << "constraint of incompatible type!\n"; + cerr << "llvm: error: Unsupported asm: input constraint with a " + << "matching output constraint of incompatible type!\n"; exit(1); } Input.ConstraintVT = OpInfo.ConstraintVT; @@ -5250,7 +5250,7 @@ // Copy the output from the appropriate register. Find a register that // we can use. if (OpInfo.AssignedRegs.Regs.empty()) { - cerr << "Couldn't allocate output reg for constraint '" + cerr << "llvm: error: Couldn't allocate output reg for constraint '" << OpInfo.ConstraintCode << "'!\n"; exit(1); } @@ -5344,7 +5344,7 @@ TLI.LowerAsmOperandForConstraint(InOperandVal, OpInfo.ConstraintCode[0], hasMemory, Ops, DAG); if (Ops.empty()) { - cerr << "Invalid operand for inline asm constraint '" + cerr << "llvm: error: Invalid operand for inline asm constraint '" << OpInfo.ConstraintCode << "'!\n"; exit(1); } @@ -5376,7 +5376,7 @@ // Copy the input into the appropriate registers. if (OpInfo.AssignedRegs.Regs.empty()) { - cerr << "Couldn't allocate output reg for constraint '" + cerr << "llvm: error: Couldn't allocate output reg for constraint '" << OpInfo.ConstraintCode << "'!\n"; exit(1); } From mrs at apple.com Mon Apr 13 17:41:07 2009 From: mrs at apple.com (Mike Stump) Date: Mon, 13 Apr 2009 15:41:07 -0700 Subject: [llvm-commits] [llvm] r68912 - in /llvm/trunk/examples: CMakeLists.txt Kaleidoscope/ Kaleidoscope/CMakeLists.txt Kaleidoscope/Makefile Kaleidoscope/toy.cpp Makefile In-Reply-To: <16e5fdf90904131501m35913725ha2371c40d9247b85@mail.gmail.com> References: <200904122047.n3CKlOGL014503@zion.cs.uiuc.edu> <44C779D1-4995-4659-8785-811D32930B5E@apple.com> <16e5fdf90904131501m35913725ha2371c40d9247b85@mail.gmail.com> Message-ID: <7BA13105-F130-4D41-9ED6-4CCF88DA6D32@apple.com> On Apr 13, 2009, at 3:01 PM, Bill Wendling wrote: > On Mon, Apr 13, 2009 at 1:59 PM, Mike Stump wrote: >> On Apr 12, 2009, at 1:47 PM, Nick Lewycky wrote: >>> Author: nicholas >>> Date: Sun Apr 12 15:47:23 2009 >>> New Revision: 68912 >>> >>> URL: http://llvm.org/viewvc/llvm-project?rev=68912&view=rev >>> Log: >>> Add Kaleidoscope to examples >> >> I think this causes: >> >> llvm/examples/Kaleidoscope/toy.cpp: In function ?void >> HandleTopLevelExpression()?: >> llvm/examples/Kaleidoscope/toy.cpp:1036: warning: ISO C++ forbids >> casting between pointer-to-function and pointer-to-object >> > It does. I looked at it (while fixing other warnings), and I'm not > sure what the proper fix for that is... The basic problem, void (*)() != void *. Most people don't buy into that pedanticism from the standard and use void *, even for pointer to functions. From isanbard at gmail.com Mon Apr 13 17:45:24 2009 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 13 Apr 2009 22:45:24 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r69001 - in /llvm-gcc-4.2/trunk/gcc: ChangeLog.apple c-typeck.c testsuite/g++.apple/6755006.C testsuite/gcc.apple/block-seq-2.c testsuite/gcc.apple/block-seq-3.c tree-ssa-loop-ivopts.c version.c Message-ID: <200904132245.n3DMjOuX016788@zion.cs.uiuc.edu> Author: void Date: Mon Apr 13 17:45:18 2009 New Revision: 69001 URL: http://llvm.org/viewvc/llvm-project?rev=69001&view=rev Log: --- Merging (from foreign repository) r68999 into '.': A testsuite/gcc.apple/block-seq-2.c A testsuite/gcc.apple/block-seq-3.c A testsuite/g++.apple/6755006.C U tree-ssa-loop-ivopts.c U ChangeLog.apple U c-typeck.c U version.c --- Merging (from foreign repository) r69000 into '.': U testsuite/g++.apple/6755006.C Update llvm-gcc to Apple gcc 5645. Added: llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/6755006.C llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-seq-2.c llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-seq-3.c Modified: llvm-gcc-4.2/trunk/gcc/ChangeLog.apple llvm-gcc-4.2/trunk/gcc/c-typeck.c llvm-gcc-4.2/trunk/gcc/tree-ssa-loop-ivopts.c llvm-gcc-4.2/trunk/gcc/version.c Modified: llvm-gcc-4.2/trunk/gcc/ChangeLog.apple URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/ChangeLog.apple?rev=69001&r1=69000&r2=69001&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/ChangeLog.apple (original) +++ llvm-gcc-4.2/trunk/gcc/ChangeLog.apple Mon Apr 13 17:45:18 2009 @@ -1,3 +1,9 @@ +2009-04-06 Stuart Hastings + + Radar 6755006 + * tree-ssa-loop-ivopts.c (aff_combination_to_tree): Unsigned + types can't be negative. + 2009-03-12 Caroline Tice Radar 6144634 Modified: llvm-gcc-4.2/trunk/gcc/c-typeck.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/c-typeck.c?rev=69001&r1=69000&r2=69001&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/c-typeck.c (original) +++ llvm-gcc-4.2/trunk/gcc/c-typeck.c Mon Apr 13 17:45:18 2009 @@ -4232,7 +4232,7 @@ /* APPLE LOCAL begin __block assign sequence point 6639533 */ { if (insert_sequence_point) - result = build2 (COMPOUND_EXPR, TREE_TYPE (result), rhs, result); + result = build2 (COMPOUND_EXPR, TREE_TYPE (result), build1 (NOP_EXPR, void_type_node, rhs), result); return result; } /* APPLE LOCAL end __block assign sequence point 6639533 */ @@ -4286,7 +4286,7 @@ /* APPLE LOCAL begin __block assign sequence point 6639533 */ { if (insert_sequence_point) - result = build2 (COMPOUND_EXPR, TREE_TYPE (result), rhs, result); + result = build2 (COMPOUND_EXPR, TREE_TYPE (result), build1 (NOP_EXPR, void_type_node, rhs), result); return result; } /* APPLE LOCAL end __block assign sequence point 6639533 */ @@ -4299,7 +4299,7 @@ /* APPLE LOCAL begin __block assign sequence point 6639533 */ if (insert_sequence_point) - result = build2 (COMPOUND_EXPR, TREE_TYPE (result), rhs, result); + result = build2 (COMPOUND_EXPR, TREE_TYPE (result), build1 (NOP_EXPR, void_type_node, rhs), result); /* APPLE LOCAL end __block assign sequence point 6639533 */ /* If we got the LHS in a different type for storing in, Added: llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/6755006.C URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/g%2B%2B.apple/6755006.C?rev=69001&view=auto ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/6755006.C (added) +++ llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/6755006.C Mon Apr 13 17:45:18 2009 @@ -0,0 +1,28 @@ +// APPLE LOCAL file 6755006 +//#include +// { dg-do run } +// { dg-options "-Os -m32" } +#include +#include +enum foo { + some_keyword0, + NUM_OBJC_KEYWORDS = 23 +}; +struct IdentifierInfo { + unsigned ObjCOrBuiltinID : 13; +}; +unsigned X = 429; +int main() { + IdentifierInfo IDs; + for (unsigned i = 0, e = X; i != e; ++i) { + IDs.ObjCOrBuiltinID = i+6583 + 23; + // assert(IDs.ObjCOrBuiltinID - 23 == i+6583 && "ID too large for field!"); + if (IDs.ObjCOrBuiltinID - 23 != i+6583) { + abort(); + // printf("ID too large for field! i == %d\n", i); + // return -1; + } + } + return 0; +} + Added: llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-seq-2.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-seq-2.c?rev=69001&view=auto ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-seq-2.c (added) +++ llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-seq-2.c Mon Apr 13 17:45:18 2009 @@ -0,0 +1,14 @@ +/* APPLE LOCAL file __block assign sequence point 6722072 */ +/* { dg-do run { target *-*-darwin[1-2][0-9]* } } */ +/* { dg-options "-fblocks" } */ +/* { dg-skip-if "" { powerpc*-*-darwin* } { "-m64" } { "" } } */ + +int i = 0; + +int die() { return i++; } + +int main() { + __block int ret = 1; + ret = die(); + return ret; +} Added: llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-seq-3.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-seq-3.c?rev=69001&view=auto ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-seq-3.c (added) +++ llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-seq-3.c Mon Apr 13 17:45:18 2009 @@ -0,0 +1,10 @@ +/* APPLE LOCAL file __block assign sequence point 6724165 */ +/* { dg-do compile { target *-*-darwin[1-2][0-9]* } } */ +/* { dg-options "-fblocks -Wall" } */ + +int foo() { + __block int i = 0; + int value = 0; + i = (value != 0); + return i; +} Modified: llvm-gcc-4.2/trunk/gcc/tree-ssa-loop-ivopts.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/tree-ssa-loop-ivopts.c?rev=69001&r1=69000&r2=69001&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/tree-ssa-loop-ivopts.c (original) +++ llvm-gcc-4.2/trunk/gcc/tree-ssa-loop-ivopts.c Mon Apr 13 17:45:18 2009 @@ -2959,7 +2959,10 @@ expr = add_elt_to_tree (expr, type, comb->elts[i], comb->coefs[i], comb->mask); - if ((comb->offset | (comb->mask >> 1)) == comb->mask) + /* APPLE LOCAL begin 6755006 */ + if (( ! TYPE_UNSIGNED (comb->type)) + && ((comb->offset | (comb->mask >> 1)) == comb->mask)) + /* APPLE LOCAL end 6755006 */ { /* Offset is negative. */ off = (-comb->offset) & comb->mask; Modified: llvm-gcc-4.2/trunk/gcc/version.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/version.c?rev=69001&r1=69000&r2=69001&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/version.c (original) +++ llvm-gcc-4.2/trunk/gcc/version.c Mon Apr 13 17:45:18 2009 @@ -11,12 +11,12 @@ /* APPLE LOCAL begin Apple version */ #ifdef ENABLE_LLVM #ifdef LLVM_VERSION_INFO -#define VERSUFFIX " (Based on Apple Inc. build 5644) (LLVM build " LLVM_VERSION_INFO ")" +#define VERSUFFIX " (Based on Apple Inc. build 5645) (LLVM build " LLVM_VERSION_INFO ")" #else -#define VERSUFFIX " (Based on Apple Inc. build 5644) (LLVM build)" +#define VERSUFFIX " (Based on Apple Inc. build 5645) (LLVM build)" #endif #else -#define VERSUFFIX " (Based on Apple Inc. build 5644)" +#define VERSUFFIX " (Based on Apple Inc. build 5645)" #endif /* APPLE LOCAL end Apple version */ From evan.cheng at apple.com Mon Apr 13 19:32:26 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 14 Apr 2009 00:32:26 -0000 Subject: [llvm-commits] [llvm] r69006 - in /llvm/trunk: lib/CodeGen/TwoAddressInstructionPass.cpp test/CodeGen/X86/2009-04-13-2AddrAssert-2.ll test/CodeGen/X86/subreg-to-reg-1.ll Message-ID: <200904140032.n3E0WQN5020941@zion.cs.uiuc.edu> Author: evancheng Date: Mon Apr 13 19:32:25 2009 New Revision: 69006 URL: http://llvm.org/viewvc/llvm-project?rev=69006&view=rev Log: Fix PR3934 part 2. findOnlyInterestingUse() was not setting IsCopy and IsDstPhys which are returned by value and used by callee. This happened to work on the earlier test cases because of a logic error in the caller side. Added: llvm/trunk/test/CodeGen/X86/2009-04-13-2AddrAssert-2.ll Modified: llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp llvm/trunk/test/CodeGen/X86/subreg-to-reg-1.ll Modified: llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp?rev=69006&r1=69005&r2=69006&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp (original) +++ llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp Mon Apr 13 19:32:25 2009 @@ -405,7 +405,7 @@ MachineInstr *findOnlyInterestingUse(unsigned Reg, MachineBasicBlock *MBB, MachineRegisterInfo *MRI, const TargetInstrInfo *TII, - bool &isCopy, + bool &IsCopy, unsigned &DstReg, bool &IsDstPhys) { MachineRegisterInfo::use_iterator UI = MRI->use_begin(Reg); if (UI == MRI->use_end()) @@ -418,11 +418,15 @@ return 0; unsigned SrcReg; bool IsSrcPhys; - if (isCopyToReg(UseMI, TII, SrcReg, DstReg, IsSrcPhys, IsDstPhys)) + if (isCopyToReg(UseMI, TII, SrcReg, DstReg, IsSrcPhys, IsDstPhys)) { + IsCopy = true; return &UseMI; + } IsDstPhys = false; - if (isTwoAddrUse(UseMI, Reg, DstReg)) + if (isTwoAddrUse(UseMI, Reg, DstReg)) { + IsDstPhys = TargetRegisterInfo::isPhysicalRegister(DstReg); return &UseMI; + } return 0; } @@ -634,12 +638,12 @@ "Can't map to two src physical registers!"); SmallVector VirtRegPairs; - bool isCopy = false; + bool IsCopy = false; unsigned NewReg = 0; while (MachineInstr *UseMI = findOnlyInterestingUse(DstReg, MBB, MRI,TII, - isCopy, NewReg, IsDstPhys)) { - if (isCopy) { - if (Processed.insert(UseMI)) + IsCopy, NewReg, IsDstPhys)) { + if (IsCopy) { + if (!Processed.insert(UseMI)) break; } @@ -654,8 +658,8 @@ } bool isNew = SrcRegMap.insert(std::make_pair(NewReg, DstReg)).second; if (!isNew) - assert(SrcRegMap[NewReg] == DstReg && - "Can't map to two src physical registers!"); + assert(SrcRegMap[NewReg] == DstReg && + "Can't map to two src physical registers!"); VirtRegPairs.push_back(NewReg); DstReg = NewReg; } Added: llvm/trunk/test/CodeGen/X86/2009-04-13-2AddrAssert-2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2009-04-13-2AddrAssert-2.ll?rev=69006&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/2009-04-13-2AddrAssert-2.ll (added) +++ llvm/trunk/test/CodeGen/X86/2009-04-13-2AddrAssert-2.ll Mon Apr 13 19:32:25 2009 @@ -0,0 +1,15 @@ +; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin +; rdar://6781755 +; PR3934 + + type { i32, i32 } ; type %0 + +define void @bn_sqr_comba8(i32* nocapture %r, i32* %a) nounwind { +entry: + %asmtmp23 = tail call %0 asm "mulq $3", "={ax},={dx},{ax},*m,~{dirflag},~{fpsr},~{flags},~{cc}"(i32 0, i32* %a) nounwind ; <%0> [#uses=1] + %asmresult25 = extractvalue %0 %asmtmp23, 1 ; [#uses=1] + %asmtmp26 = tail call %0 asm "addq $0,$0; adcq $2,$1", "={dx},=r,imr,0,1,~{dirflag},~{fpsr},~{flags},~{cc}"(i32 0, i32 %asmresult25, i32 0) nounwind ; <%0> [#uses=1] + %asmresult27 = extractvalue %0 %asmtmp26, 0 ; [#uses=1] + %asmtmp29 = tail call %0 asm "addq $0,$0; adcq $2,$1", "={ax},={dx},imr,0,1,~{dirflag},~{fpsr},~{flags},~{cc}"(i32 0, i32 0, i32 %asmresult27) nounwind ; <%0> [#uses=0] + ret void +} Modified: llvm/trunk/test/CodeGen/X86/subreg-to-reg-1.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/subreg-to-reg-1.ll?rev=69006&r1=69005&r2=69006&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/subreg-to-reg-1.ll (original) +++ llvm/trunk/test/CodeGen/X86/subreg-to-reg-1.ll Mon Apr 13 19:32:25 2009 @@ -5,7 +5,7 @@ ; though this isn't necessary; The point of this test is to make sure ; a 32-bit add is used. -define i64 @foo(i64 %a) { +define i64 @foo(i64 %a) nounwind { %b = add i64 %a, 4294967295 %c = and i64 %b, 4294967295 %d = add i64 %c, 1 From dalej at apple.com Mon Apr 13 19:56:56 2009 From: dalej at apple.com (Dale Johannesen) Date: Tue, 14 Apr 2009 00:56:56 -0000 Subject: [llvm-commits] [llvm] r69008 - /llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Message-ID: <200904140056.n3E0uulx021952@zion.cs.uiuc.edu> Author: johannes Date: Mon Apr 13 19:56:56 2009 New Revision: 69008 URL: http://llvm.org/viewvc/llvm-project?rev=69008&view=rev Log: Do not force asm's to be chained if they don't touch memory and aren't volatile. This was interfering with good scheduling. 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=69008&r1=69007&r2=69008&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Mon Apr 13 19:56:56 2009 @@ -5439,6 +5439,9 @@ } setValue(CS.getInstruction(), Val); + // Don't need to use this as a chain in this case. + if (!IA->hasSideEffects() && !hasMemory && IndirectStoresToEmit.empty()) + return; } std::vector > StoresToEmit; From resistor at mac.com Mon Apr 13 20:04:19 2009 From: resistor at mac.com (Owen Anderson) Date: Tue, 14 Apr 2009 01:04:19 -0000 Subject: [llvm-commits] [llvm] r69011 - /llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Message-ID: <200904140104.n3E14JW0022262@zion.cs.uiuc.edu> Author: resistor Date: Mon Apr 13 20:04:19 2009 New Revision: 69011 URL: http://llvm.org/viewvc/llvm-project?rev=69011&view=rev Log: LoopIndexSplit needs to inform the loop pass manager of the instructions it is deleting, not just the basic block. Modified: llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp?rev=69011&r1=69010&r2=69011&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Mon Apr 13 20:04:19 2009 @@ -695,6 +695,7 @@ Instruction *I = BBI; ++BBI; I->replaceAllUsesWith(UndefValue::get(I->getType())); + LPM->deleteSimpleAnalysisValue(I, LP); I->eraseFromParent(); } DT->eraseNode(BB); From evan.cheng at apple.com Mon Apr 13 20:24:33 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 13 Apr 2009 18:24:33 -0700 Subject: [llvm-commits] [llvm] r68545 - in /llvm/trunk: include/llvm/Target/TargetRegisterInfo.h lib/Target/ARM/ARMISelDAGToDAG.cpp lib/Target/ARM/ARMISelLowering.cpp lib/Target/ARM/ARMInstrInfo.cpp lib/Target/ARM/ARMInstrThumb.td lib/Target/ARM/ARMRegisterInfo.cpp lib/Target/ARM/ARMRegisterInfo.h lib/Target/ARM/ARMRegisterInfo.td In-Reply-To: <200904072034.n37KYAJU026667@zion.cs.uiuc.edu> References: <200904072034.n37KYAJU026667@zion.cs.uiuc.edu> Message-ID: <8A646114-F648-4815-9C05-94AB41FCC0A1@apple.com> Looks great. Thanks. Can you add some comments in ARMInstrThumb.td about tMOVhir2lor and friends? Evan On Apr 7, 2009, at 1:34 PM, Jim Grosbach wrote: > Author: grosbach > Date: Tue Apr 7 15:34:09 2009 > New Revision: 68545 > > URL: http://llvm.org/viewvc/llvm-project?rev=68545&view=rev > Log: > PR2985 / > > When compiling in Thumb mode, only the low (R0-R7) registers are > available > for most instructions. Breaking the low registers into a new > register class > handles this. Uses of R12, SP, etc, are handled explicitly where > needed > with copies inserted to move results into low registers where the > rest of > the code generator can deal with them. > > > Modified: > llvm/trunk/include/llvm/Target/TargetRegisterInfo.h > llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp > llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp > llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp > llvm/trunk/lib/Target/ARM/ARMInstrThumb.td > llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp > llvm/trunk/lib/Target/ARM/ARMRegisterInfo.h > llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td > > Modified: llvm/trunk/include/llvm/Target/TargetRegisterInfo.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetRegisterInfo.h?rev=68545&r1=68544&r2=68545&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/include/llvm/Target/TargetRegisterInfo.h (original) > +++ llvm/trunk/include/llvm/Target/TargetRegisterInfo.h Tue Apr 7 > 15:34:09 2009 > @@ -273,8 +273,8 @@ > /// getPhysicalRegisterRegClass - Returns the Register Class of a > physical > /// register of the given type. If type is MVT::Other, then just > return any > /// register class the register belongs to. > - const TargetRegisterClass *getPhysicalRegisterRegClass(unsigned > Reg, > - MVT VT = MVT::Other) const; > + virtual const TargetRegisterClass * > + getPhysicalRegisterRegClass(unsigned Reg, MVT VT = MVT::Other) > const; > > /// getAllocatableSet - Returns a bitset indexed by register number > /// indicating if a register is allocatable or not. If a register > class is > > Modified: llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp?rev=68545&r1=68544&r2=68545&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp (original) > +++ llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp Tue Apr 7 > 15:34:09 2009 > @@ -584,10 +584,10 @@ > // Selects to ADDri FI, 0 which in turn will become ADDri SP, imm. > int FI = cast(N)->getIndex(); > SDValue TFI = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); > - if (Subtarget->isThumb()) > + if (Subtarget->isThumb()) { > return CurDAG->SelectNodeTo(N, ARM::tADDrSPi, MVT::i32, TFI, > CurDAG->getTargetConstant(0, > MVT::i32)); > - else { > + } else { > SDValue Ops[] = { TFI, CurDAG->getTargetConstant(0, MVT::i32), > getAL(CurDAG), CurDAG->getRegister(0, > MVT::i32), > CurDAG->getRegister(0, MVT::i32) }; > @@ -607,7 +607,9 @@ > std::swap(LHSR, RHSR); > } > if (RHSR && RHSR->getReg() == ARM::SP) { > - return CurDAG->SelectNodeTo(N, ARM::tADDhirr, Op.getValueType > (), N0, N1); > + SDValue Val = SDValue(CurDAG->getTargetNode(ARM::tMOVlor2hir, > dl, > + Op.getValueType(), N0, N0), 0); > + return CurDAG->SelectNodeTo(N, ARM::tADDhirr, Op.getValueType > (), Val, N1); > } > break; > } > > Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=68545&r1=68544&r2=68545&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) > +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Tue Apr 7 > 15:34:09 2009 > @@ -117,7 +117,10 @@ > } > } > > - addRegisterClass(MVT::i32, ARM::GPRRegisterClass); > + if (Subtarget->isThumb()) > + addRegisterClass(MVT::i32, ARM::tGPRRegisterClass); > + else > + addRegisterClass(MVT::i32, ARM::GPRRegisterClass); > if (!UseSoftFloat && Subtarget->hasVFP2() && !Subtarget->isThumb > ()) { > addRegisterClass(MVT::f32, ARM::SPRRegisterClass); > addRegisterClass(MVT::f64, ARM::DPRRegisterClass); > @@ -937,6 +940,7 @@ > MVT ObjectVT = Op.getValue(ArgNo).getValueType(); > SDValue Root = Op.getOperand(0); > MachineRegisterInfo &RegInfo = MF.getRegInfo(); > + ARMFunctionInfo *AFI = MF.getInfo(); > > static const unsigned GPRArgRegs[] = { > ARM::R0, ARM::R1, ARM::R2, ARM::R3 > @@ -955,17 +959,28 @@ > > SDValue ArgValue; > if (ObjGPRs == 1) { > - unsigned VReg = RegInfo.createVirtualRegister(&ARM::GPRRegClass); > + unsigned VReg; > + if (AFI->isThumbFunction()) > + VReg = RegInfo.createVirtualRegister(ARM::tGPRRegisterClass); > + else > + VReg = RegInfo.createVirtualRegister(ARM::GPRRegisterClass); > RegInfo.addLiveIn(GPRArgRegs[NumGPRs], VReg); > ArgValue = DAG.getCopyFromReg(Root, dl, VReg, MVT::i32); > if (ObjectVT == MVT::f32) > ArgValue = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::f32, > ArgValue); > } else if (ObjGPRs == 2) { > - unsigned VReg = RegInfo.createVirtualRegister(&ARM::GPRRegClass); > + unsigned VReg; > + if (AFI->isThumbFunction()) > + VReg = RegInfo.createVirtualRegister(ARM::tGPRRegisterClass); > + else > + VReg = RegInfo.createVirtualRegister(ARM::GPRRegisterClass); > RegInfo.addLiveIn(GPRArgRegs[NumGPRs], VReg); > ArgValue = DAG.getCopyFromReg(Root, dl, VReg, MVT::i32); > > - VReg = RegInfo.createVirtualRegister(&ARM::GPRRegClass); > + if (AFI->isThumbFunction()) > + VReg = RegInfo.createVirtualRegister(ARM::tGPRRegisterClass); > + else > + VReg = RegInfo.createVirtualRegister(ARM::GPRRegisterClass); > RegInfo.addLiveIn(GPRArgRegs[NumGPRs+1], VReg); > SDValue ArgValue2 = DAG.getCopyFromReg(Root, dl, VReg, MVT::i32); > > @@ -1029,7 +1044,11 @@ > > SmallVector MemOps; > for (; NumGPRs < 4; ++NumGPRs) { > - unsigned VReg = RegInfo.createVirtualRegister > (&ARM::GPRRegClass); > + unsigned VReg; > + if (AFI->isThumbFunction()) > + VReg = RegInfo.createVirtualRegister > (ARM::tGPRRegisterClass); > + else > + VReg = RegInfo.createVirtualRegister > (ARM::GPRRegisterClass); > RegInfo.addLiveIn(GPRArgRegs[NumGPRs], VReg); > SDValue Val = DAG.getCopyFromReg(Root, dl, VReg, MVT::i32); > SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN, > NULL, 0); > @@ -1965,8 +1984,10 @@ > // GCC RS6000 Constraint Letters > switch (Constraint[0]) { > case 'l': > - // FIXME: in thumb mode, 'l' is only low-regs. > - // FALL THROUGH. > + if (Subtarget->isThumb()) > + return std::make_pair(0U, ARM::tGPRRegisterClass); > + else > + return std::make_pair(0U, ARM::GPRRegisterClass); > case 'r': > return std::make_pair(0U, ARM::GPRRegisterClass); > case 'w': > @@ -1989,6 +2010,9 @@ > switch (Constraint[0]) { // GCC ARM Constraint Letters > default: break; > case 'l': > + return make_vector(ARM::R0, ARM::R1, ARM::R2, ARM::R3, > + ARM::R4, ARM::R5, ARM::R6, ARM::R7, > + 0); > case 'r': > return make_vector(ARM::R0, ARM::R1, ARM::R2, ARM::R3, > ARM::R4, ARM::R5, ARM::R6, ARM::R7, > > Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp?rev=68545&r1=68544&r2=68545&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp (original) > +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp Tue Apr 7 15:34:09 > 2009 > @@ -64,6 +64,9 @@ > return true; > case ARM::MOVr: > case ARM::tMOVr: > + case ARM::tMOVhir2lor: > + case ARM::tMOVlor2hir: > + case ARM::tMOVhir2hir: > assert(MI.getDesc().getNumOperands() >= 2 && > MI.getOperand(0).isReg() && > MI.getOperand(1).isReg() && > @@ -483,23 +486,43 @@ > unsigned DestReg, unsigned SrcReg, > const TargetRegisterClass *DestRC, > const TargetRegisterClass *SrcRC) > const { > + MachineFunction &MF = *MBB.getParent(); > + ARMFunctionInfo *AFI = MF.getInfo(); > + DebugLoc DL = DebugLoc::getUnknownLoc(); > + if (I != MBB.end()) DL = I->getDebugLoc(); > + > + if (!AFI->isThumbFunction()) { > + if (DestRC == ARM::GPRRegisterClass) { > + AddDefaultCC(AddDefaultPred(BuildMI(MBB, I, DL, get > (ARM::MOVr), DestReg) > + .addReg(SrcReg))); > + return true; > + } > + } else { > + if (DestRC == ARM::GPRRegisterClass) { > + if (SrcRC == ARM::GPRRegisterClass) { > + BuildMI(MBB, I, DL, get(ARM::tMOVhir2hir), DestReg).addReg > (SrcReg); > + return true; > + } else if (SrcRC == ARM::tGPRRegisterClass) { > + BuildMI(MBB, I, DL, get(ARM::tMOVlor2hir), DestReg).addReg > (SrcReg); > + return true; > + } > + } else if (DestRC == ARM::tGPRRegisterClass) { > + if (SrcRC == ARM::GPRRegisterClass) { > + BuildMI(MBB, I, DL, get(ARM::tMOVhir2lor), DestReg).addReg > (SrcReg); > + return true; > + } else if (SrcRC == ARM::tGPRRegisterClass) { > + BuildMI(MBB, I, DL, get(ARM::tMOVr), DestReg).addReg(SrcReg); > + return true; > + } > + } > + } > if (DestRC != SrcRC) { > // Not yet supported! > return false; > } > > - DebugLoc DL = DebugLoc::getUnknownLoc(); > - if (I != MBB.end()) DL = I->getDebugLoc(); > > - if (DestRC == ARM::GPRRegisterClass) { > - MachineFunction &MF = *MBB.getParent(); > - ARMFunctionInfo *AFI = MF.getInfo(); > - if (AFI->isThumbFunction()) > - BuildMI(MBB, I, DL, get(ARM::tMOVr), DestReg).addReg(SrcReg); > - else > - AddDefaultCC(AddDefaultPred(BuildMI(MBB, I, DL, get > (ARM::MOVr), DestReg) > - .addReg(SrcReg))); > - } else if (DestRC == ARM::SPRRegisterClass) > + if (DestRC == ARM::SPRRegisterClass) > AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FCPYS), DestReg) > .addReg(SrcReg)); > else if (DestRC == ARM::DPRRegisterClass) > @@ -521,14 +544,17 @@ > if (RC == ARM::GPRRegisterClass) { > MachineFunction &MF = *MBB.getParent(); > ARMFunctionInfo *AFI = MF.getInfo(); > - if (AFI->isThumbFunction()) > - BuildMI(MBB, I, DL, get(ARM::tSpill)) > - .addReg(SrcReg, false, false, isKill) > - .addFrameIndex(FI).addImm(0); > - else > - AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::STR)) > - .addReg(SrcReg, false, false, isKill) > - .addFrameIndex(FI).addReg(0).addImm(0)); > + assert (!AFI->isThumbFunction()); > + AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::STR)) > + .addReg(SrcReg, false, false, isKill) > + .addFrameIndex(FI).addReg(0).addImm(0)); > + } else if (RC == ARM::tGPRRegisterClass) { > + MachineFunction &MF = *MBB.getParent(); > + ARMFunctionInfo *AFI = MF.getInfo(); > + assert (AFI->isThumbFunction()); > + BuildMI(MBB, I, DL, get(ARM::tSpill)) > + .addReg(SrcReg, false, false, isKill) > + .addFrameIndex(FI).addImm(0); > } else if (RC == ARM::DPRRegisterClass) { > AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FSTD)) > .addReg(SrcReg, false, false, isKill) > @@ -586,12 +612,15 @@ > if (RC == ARM::GPRRegisterClass) { > MachineFunction &MF = *MBB.getParent(); > ARMFunctionInfo *AFI = MF.getInfo(); > - if (AFI->isThumbFunction()) > - BuildMI(MBB, I, DL, get(ARM::tRestore), DestReg) > - .addFrameIndex(FI).addImm(0); > - else > - AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::LDR), DestReg) > - .addFrameIndex(FI).addReg(0).addImm(0)); > + assert (!AFI->isThumbFunction()); > + AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::LDR), DestReg) > + .addFrameIndex(FI).addReg(0).addImm(0)); > + } else if (RC == ARM::tGPRRegisterClass) { > + MachineFunction &MF = *MBB.getParent(); > + ARMFunctionInfo *AFI = MF.getInfo(); > + assert (AFI->isThumbFunction()); > + BuildMI(MBB, I, DL, get(ARM::tRestore), DestReg) > + .addFrameIndex(FI).addImm(0); > } else if (RC == ARM::DPRRegisterClass) { > AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FLDD), DestReg) > .addFrameIndex(FI).addImm(0)); > @@ -715,7 +744,10 @@ > } > break; > } > - case ARM::tMOVr: { > + case ARM::tMOVr: > + case ARM::tMOVlor2hir: > + case ARM::tMOVhir2lor: > + case ARM::tMOVhir2hir: { > if (OpNum == 0) { // move -> store > unsigned SrcReg = MI->getOperand(1).getReg(); > bool isKill = MI->getOperand(1).isKill(); > @@ -788,7 +820,10 @@ > case ARM::MOVr: > // If it is updating CPSR, then it cannot be folded. > return MI->getOperand(4).getReg() != ARM::CPSR; > - case ARM::tMOVr: { > + case ARM::tMOVr: > + case ARM::tMOVlor2hir: > + case ARM::tMOVhir2lor: > + case ARM::tMOVhir2hir: { > if (OpNum == 0) { // move -> store > unsigned SrcReg = MI->getOperand(1).getReg(); > if (RI.isPhysicalRegister(SrcReg) && !RI.isLowRegister(SrcReg)) > > Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb.td > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb.td?rev=68545&r1=68544&r2=68545&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/ARM/ARMInstrThumb.td (original) > +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb.td Tue Apr 7 15:34:09 > 2009 > @@ -73,7 +73,7 @@ > def t_addrmode_rr : Operand, > ComplexPattern []> { > let PrintMethod = "printThumbAddrModeRROperand"; > - let MIOperandInfo = (ops GPR:$base, GPR:$offsreg); > + let MIOperandInfo = (ops tGPR:$base, tGPR:$offsreg); > } > > // t_addrmode_s4 := reg + reg > @@ -82,7 +82,7 @@ > def t_addrmode_s4 : Operand, > ComplexPattern []> { > let PrintMethod = "printThumbAddrModeS4Operand"; > - let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm, GPR:$offsreg); > + let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm, tGPR: > $offsreg); > } > > // t_addrmode_s2 := reg + reg > @@ -91,7 +91,7 @@ > def t_addrmode_s2 : Operand, > ComplexPattern []> { > let PrintMethod = "printThumbAddrModeS2Operand"; > - let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm, GPR:$offsreg); > + let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm, tGPR: > $offsreg); > } > > // t_addrmode_s1 := reg + reg > @@ -100,7 +100,7 @@ > def t_addrmode_s1 : Operand, > ComplexPattern []> { > let PrintMethod = "printThumbAddrModeS1Operand"; > - let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm, GPR:$offsreg); > + let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm, tGPR: > $offsreg); > } > > // t_addrmode_sp := sp + imm8 * 4 > @@ -108,7 +108,7 @@ > def t_addrmode_sp : Operand, > ComplexPattern []> { > let PrintMethod = "printThumbAddrModeSPOperand"; > - let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm); > + let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm); > } > > // > = > = > = > ----------------------------------------------------------------------= > ==// > @@ -128,9 +128,9 @@ > } > > let isNotDuplicable = 1 in > -def tPICADD : TIt<(outs GPR:$dst), (ins GPR:$lhs, pclabel:$cp), > +def tPICADD : TIt<(outs tGPR:$dst), (ins tGPR:$lhs, pclabel:$cp), > "$cp:\n\tadd $dst, pc", > - [(set GPR:$dst, (ARMpic_add GPR:$lhs, imm:$cp))]>; > + [(set tGPR:$dst, (ARMpic_add tGPR:$lhs, imm:$cp))] > >; > > // > = > = > = > ----------------------------------------------------------------------= > ==// > // Control Flow Instructions. > @@ -139,7 +139,7 @@ > let isReturn = 1, isTerminator = 1 in { > def tBX_RET : TI<(outs), (ins), "bx lr", [(ARMretflag)]>; > // Alternative return instruction used by vararg functions. > - def tBX_RET_vararg : TI<(outs), (ins GPR:$target), "bx $target", > []>; > + def tBX_RET_vararg : TI<(outs), (ins tGPR:$target), "bx $target", > []>; > } > > // FIXME: remove when we have a way to marking a MI with these > properties. > @@ -157,13 +157,13 @@ > def tBLXi : TIx2<(outs), (ins i32imm:$func, variable_ops), > "blx ${func:call}", > [(ARMcall tglobaladdr:$func)]>, Requires<[HasV5T] > >; > - def tBLXr : TI<(outs), (ins GPR:$func, variable_ops), > + def tBLXr : TI<(outs), (ins tGPR:$func, variable_ops), > "blx $func", > - [(ARMtcall GPR:$func)]>, Requires<[HasV5T]>; > + [(ARMtcall tGPR:$func)]>, Requires<[HasV5T]>; > // ARMv4T > - def tBX : TIx2<(outs), (ins GPR:$func, variable_ops), > + def tBX : TIx2<(outs), (ins tGPR:$func, variable_ops), > "cpy lr, pc\n\tbx $func", > - [(ARMcall_nolink GPR:$func)]>; > + [(ARMcall_nolink tGPR:$func)]>; > } > > let isBranch = 1, isTerminator = 1 in { > @@ -176,9 +176,9 @@ > def tBfar : TIx2<(outs), (ins brtarget:$target), "bl $target\t@ > far jump",[]>; > > def tBR_JTr : TJTI<(outs), > - (ins GPR:$target, jtblock_operand:$jt, i32imm: > $id), > + (ins tGPR:$target, jtblock_operand:$jt, i32imm: > $id), > "cpy pc, $target \n\t.align\t2\n$jt", > - [(ARMbrjt GPR:$target, tjumptable:$jt, imm: > $id)]>; > + [(ARMbrjt tGPR:$target, tjumptable:$jt, imm: > $id)]>; > } > } > > @@ -193,68 +193,68 @@ > // > > let canFoldAsLoad = 1 in > -def tLDR : TI4<(outs GPR:$dst), (ins t_addrmode_s4:$addr), > +def tLDR : TI4<(outs tGPR:$dst), (ins t_addrmode_s4:$addr), > "ldr $dst, $addr", > - [(set GPR:$dst, (load t_addrmode_s4:$addr))]>; > + [(set tGPR:$dst, (load t_addrmode_s4:$addr))]>; > > -def tLDRB : TI1<(outs GPR:$dst), (ins t_addrmode_s1:$addr), > +def tLDRB : TI1<(outs tGPR:$dst), (ins t_addrmode_s1:$addr), > "ldrb $dst, $addr", > - [(set GPR:$dst, (zextloadi8 t_addrmode_s1:$addr))]>; > + [(set tGPR:$dst, (zextloadi8 t_addrmode_s1:$addr))]>; > > -def tLDRH : TI2<(outs GPR:$dst), (ins t_addrmode_s2:$addr), > +def tLDRH : TI2<(outs tGPR:$dst), (ins t_addrmode_s2:$addr), > "ldrh $dst, $addr", > - [(set GPR:$dst, (zextloadi16 t_addrmode_s2:$addr))]>; > + [(set tGPR:$dst, (zextloadi16 t_addrmode_s2:$addr))] > >; > > -def tLDRSB : TI1<(outs GPR:$dst), (ins t_addrmode_rr:$addr), > +def tLDRSB : TI1<(outs tGPR:$dst), (ins t_addrmode_rr:$addr), > "ldrsb $dst, $addr", > - [(set GPR:$dst, (sextloadi8 t_addrmode_rr:$addr))]>; > + [(set tGPR:$dst, (sextloadi8 t_addrmode_rr:$addr))] > >; > > -def tLDRSH : TI2<(outs GPR:$dst), (ins t_addrmode_rr:$addr), > +def tLDRSH : TI2<(outs tGPR:$dst), (ins t_addrmode_rr:$addr), > "ldrsh $dst, $addr", > - [(set GPR:$dst, (sextloadi16 t_addrmode_rr:$addr))] > >; > + [(set tGPR:$dst, (sextloadi16 t_addrmode_rr: > $addr))]>; > > let canFoldAsLoad = 1 in > -def tLDRspi : TIs<(outs GPR:$dst), (ins t_addrmode_sp:$addr), > +def tLDRspi : TIs<(outs tGPR:$dst), (ins t_addrmode_sp:$addr), > "ldr $dst, $addr", > - [(set GPR:$dst, (load t_addrmode_sp:$addr))]>; > + [(set tGPR:$dst, (load t_addrmode_sp:$addr))]>; > > // Special instruction for restore. It cannot clobber condition > register > // when it's expanded by eliminateCallFramePseudoInstr(). > let canFoldAsLoad = 1, mayLoad = 1 in > -def tRestore : TIs<(outs GPR:$dst), (ins t_addrmode_sp:$addr), > +def tRestore : TIs<(outs tGPR:$dst), (ins t_addrmode_sp:$addr), > "ldr $dst, $addr", []>; > > // Load tconstpool > let canFoldAsLoad = 1 in > -def tLDRpci : TIs<(outs GPR:$dst), (ins i32imm:$addr), > +def tLDRpci : TIs<(outs tGPR:$dst), (ins i32imm:$addr), > "ldr $dst, $addr", > - [(set GPR:$dst, (load (ARMWrapper tconstpool: > $addr)))]>; > + [(set tGPR:$dst, (load (ARMWrapper tconstpool: > $addr)))]>; > > // Special LDR for loads from non-pc-relative constpools. > let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1 in > -def tLDRcp : TIs<(outs GPR:$dst), (ins i32imm:$addr), > +def tLDRcp : TIs<(outs tGPR:$dst), (ins i32imm:$addr), > "ldr $dst, $addr", []>; > > -def tSTR : TI4<(outs), (ins GPR:$src, t_addrmode_s4:$addr), > +def tSTR : TI4<(outs), (ins tGPR:$src, t_addrmode_s4:$addr), > "str $src, $addr", > - [(store GPR:$src, t_addrmode_s4:$addr)]>; > + [(store tGPR:$src, t_addrmode_s4:$addr)]>; > > -def tSTRB : TI1<(outs), (ins GPR:$src, t_addrmode_s1:$addr), > +def tSTRB : TI1<(outs), (ins tGPR:$src, t_addrmode_s1:$addr), > "strb $src, $addr", > - [(truncstorei8 GPR:$src, t_addrmode_s1:$addr)]>; > + [(truncstorei8 tGPR:$src, t_addrmode_s1:$addr)]>; > > -def tSTRH : TI2<(outs), (ins GPR:$src, t_addrmode_s2:$addr), > +def tSTRH : TI2<(outs), (ins tGPR:$src, t_addrmode_s2:$addr), > "strh $src, $addr", > - [(truncstorei16 GPR:$src, t_addrmode_s2:$addr)]>; > + [(truncstorei16 tGPR:$src, t_addrmode_s2:$addr)]>; > > -def tSTRspi : TIs<(outs), (ins GPR:$src, t_addrmode_sp:$addr), > +def tSTRspi : TIs<(outs), (ins tGPR:$src, t_addrmode_sp:$addr), > "str $src, $addr", > - [(store GPR:$src, t_addrmode_sp:$addr)]>; > + [(store tGPR:$src, t_addrmode_sp:$addr)]>; > > let mayStore = 1 in { > // Special instruction for spill. It cannot clobber condition register > // when it's expanded by eliminateCallFramePseudoInstr(). > -def tSpill : TIs<(outs), (ins GPR:$src, t_addrmode_sp:$addr), > +def tSpill : TIs<(outs), (ins tGPR:$src, t_addrmode_sp:$addr), > "str $src, $addr", []>; > } > > @@ -277,205 +277,213 @@ > // > > // Add with carry > -def tADC : TIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), > +def tADC : TIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), > "adc $dst, $rhs", > - [(set GPR:$dst, (adde GPR:$lhs, GPR:$rhs))]>; > + [(set tGPR:$dst, (adde tGPR:$lhs, tGPR:$rhs))]>; > > -def tADDS : TI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), > +def tADDS : TI<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), > "add $dst, $lhs, $rhs", > - [(set GPR:$dst, (addc GPR:$lhs, GPR:$rhs))]>; > + [(set tGPR:$dst, (addc tGPR:$lhs, tGPR:$rhs))]>; > > > -def tADDi3 : TI<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), > +def tADDi3 : TI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), > "add $dst, $lhs, $rhs", > - [(set GPR:$dst, (add GPR:$lhs, imm0_7:$rhs))]>; > + [(set tGPR:$dst, (add tGPR:$lhs, imm0_7:$rhs))]>; > > -def tADDi8 : TIt<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), > +def tADDi8 : TIt<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), > "add $dst, $rhs", > - [(set GPR:$dst, (add GPR:$lhs, imm8_255:$rhs))]>; > + [(set tGPR:$dst, (add tGPR:$lhs, imm8_255:$rhs))]>; > > -def tADDrr : TI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), > +def tADDrr : TI<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), > "add $dst, $lhs, $rhs", > - [(set GPR:$dst, (add GPR:$lhs, GPR:$rhs))]>; > + [(set tGPR:$dst, (add tGPR:$lhs, tGPR:$rhs))]>; > > -def tADDhirr : TIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), > - "add $dst, $rhs", []>; > +def tADDhirr : TIt<(outs tGPR:$dst), (ins GPR:$lhs, GPR:$rhs), > + "add $dst, $rhs @ addhirr", []>; > > -def tADDrPCi : TI<(outs GPR:$dst), (ins i32imm:$rhs), > +def tADDrPCi : TI<(outs tGPR:$dst), (ins i32imm:$rhs), > "add $dst, pc, $rhs * 4", []>; > -def tADDrSPi : TI<(outs GPR:$dst), (ins GPR:$sp, i32imm:$rhs), > - "add $dst, $sp, $rhs * 4", []>; > -def tADDspi : TIt<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), > + > +def tADDrSPi : TI<(outs tGPR:$dst), (ins GPR:$sp, i32imm:$rhs), > + "add $dst, $sp, $rhs * 4 @ addrspi", []>; > + > +def tADDspi : TIt<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), > "add $dst, $rhs * 4", []>; > > -def tAND : TIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), > +def tAND : TIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), > "and $dst, $rhs", > - [(set GPR:$dst, (and GPR:$lhs, GPR:$rhs))]>; > + [(set tGPR:$dst, (and tGPR:$lhs, tGPR:$rhs))]>; > > -def tASRri : TI<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), > +def tASRri : TI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), > "asr $dst, $lhs, $rhs", > - [(set GPR:$dst, (sra GPR:$lhs, imm:$rhs))]>; > + [(set tGPR:$dst, (sra tGPR:$lhs, imm:$rhs))]>; > > -def tASRrr : TIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), > +def tASRrr : TIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), > "asr $dst, $rhs", > - [(set GPR:$dst, (sra GPR:$lhs, GPR:$rhs))]>; > + [(set tGPR:$dst, (sra tGPR:$lhs, tGPR:$rhs))]>; > > -def tBIC : TIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), > +def tBIC : TIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), > "bic $dst, $rhs", > - [(set GPR:$dst, (and GPR:$lhs, (not GPR:$rhs)))]>; > + [(set tGPR:$dst, (and tGPR:$lhs, (not tGPR:$rhs)))]>; > > > -def tCMN : TI<(outs), (ins GPR:$lhs, GPR:$rhs), > +def tCMN : TI<(outs), (ins tGPR:$lhs, tGPR:$rhs), > "cmn $lhs, $rhs", > - [(ARMcmp GPR:$lhs, (ineg GPR:$rhs))]>; > + [(ARMcmp tGPR:$lhs, (ineg tGPR:$rhs))]>; > > -def tCMPi8 : TI<(outs), (ins GPR:$lhs, i32imm:$rhs), > +def tCMPi8 : TI<(outs), (ins tGPR:$lhs, i32imm:$rhs), > "cmp $lhs, $rhs", > - [(ARMcmp GPR:$lhs, imm0_255:$rhs)]>; > + [(ARMcmp tGPR:$lhs, imm0_255:$rhs)]>; > > -def tCMPr : TI<(outs), (ins GPR:$lhs, GPR:$rhs), > +def tCMPr : TI<(outs), (ins tGPR:$lhs, tGPR:$rhs), > "cmp $lhs, $rhs", > - [(ARMcmp GPR:$lhs, GPR:$rhs)]>; > + [(ARMcmp tGPR:$lhs, tGPR:$rhs)]>; > > -def tTST : TI<(outs), (ins GPR:$lhs, GPR:$rhs), > +def tTST : TI<(outs), (ins tGPR:$lhs, tGPR:$rhs), > "tst $lhs, $rhs", > - [(ARMcmpNZ (and GPR:$lhs, GPR:$rhs), 0)]>; > + [(ARMcmpNZ (and tGPR:$lhs, tGPR:$rhs), 0)]>; > > -def tCMNNZ : TI<(outs), (ins GPR:$lhs, GPR:$rhs), > +def tCMNNZ : TI<(outs), (ins tGPR:$lhs, tGPR:$rhs), > "cmn $lhs, $rhs", > - [(ARMcmpNZ GPR:$lhs, (ineg GPR:$rhs))]>; > + [(ARMcmpNZ tGPR:$lhs, (ineg tGPR:$rhs))]>; > > -def tCMPNZi8 : TI<(outs), (ins GPR:$lhs, i32imm:$rhs), > +def tCMPNZi8 : TI<(outs), (ins tGPR:$lhs, i32imm:$rhs), > "cmp $lhs, $rhs", > - [(ARMcmpNZ GPR:$lhs, imm0_255:$rhs)]>; > + [(ARMcmpNZ tGPR:$lhs, imm0_255:$rhs)]>; > > -def tCMPNZr : TI<(outs), (ins GPR:$lhs, GPR:$rhs), > +def tCMPNZr : TI<(outs), (ins tGPR:$lhs, tGPR:$rhs), > "cmp $lhs, $rhs", > - [(ARMcmpNZ GPR:$lhs, GPR:$rhs)]>; > + [(ARMcmpNZ tGPR:$lhs, tGPR:$rhs)]>; > > // TODO: A7-37: CMP(3) - cmp hi regs > > -def tEOR : TIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), > +def tEOR : TIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), > "eor $dst, $rhs", > - [(set GPR:$dst, (xor GPR:$lhs, GPR:$rhs))]>; > + [(set tGPR:$dst, (xor tGPR:$lhs, tGPR:$rhs))]>; > > -def tLSLri : TI<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), > +def tLSLri : TI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), > "lsl $dst, $lhs, $rhs", > - [(set GPR:$dst, (shl GPR:$lhs, imm:$rhs))]>; > + [(set tGPR:$dst, (shl tGPR:$lhs, imm:$rhs))]>; > > -def tLSLrr : TIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), > +def tLSLrr : TIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), > "lsl $dst, $rhs", > - [(set GPR:$dst, (shl GPR:$lhs, GPR:$rhs))]>; > + [(set tGPR:$dst, (shl tGPR:$lhs, tGPR:$rhs))]>; > > -def tLSRri : TI<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), > +def tLSRri : TI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), > "lsr $dst, $lhs, $rhs", > - [(set GPR:$dst, (srl GPR:$lhs, imm:$rhs))]>; > + [(set tGPR:$dst, (srl tGPR:$lhs, imm:$rhs))]>; > > -def tLSRrr : TIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), > +def tLSRrr : TIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), > "lsr $dst, $rhs", > - [(set GPR:$dst, (srl GPR:$lhs, GPR:$rhs))]>; > + [(set tGPR:$dst, (srl tGPR:$lhs, tGPR:$rhs))]>; > > // FIXME: This is not rematerializable because mov changes the > condition code. > -def tMOVi8 : TI<(outs GPR:$dst), (ins i32imm:$src), > +def tMOVi8 : TI<(outs tGPR:$dst), (ins i32imm:$src), > "mov $dst, $src", > - [(set GPR:$dst, imm0_255:$src)]>; > + [(set tGPR:$dst, imm0_255:$src)]>; > > // TODO: A7-73: MOV(2) - mov setting flag. > > > // Note: MOV(2) of two low regs updates the flags, so we emit this > as 'cpy', > // which is MOV(3). This also supports high registers. > -def tMOVr : TI<(outs GPR:$dst), (ins GPR:$src), > - "cpy $dst, $src", []>; > +def tMOVr : TI<(outs tGPR:$dst), (ins tGPR:$src), > + "cpy $dst, $src", []>; > +def tMOVhir2lor : TI<(outs tGPR:$dst), (ins GPR:$src), > + "cpy $dst, $src\t@ hir2lor", []>; > +def tMOVlor2hir : TI<(outs GPR:$dst), (ins tGPR:$src), > + "cpy $dst, $src\t@ lor2hir", []>; > +def tMOVhir2hir : TI<(outs GPR:$dst), (ins GPR:$src), > + "cpy $dst, $src\t@ hir2hir", []>; > > -def tMUL : TIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), > +def tMUL : TIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), > "mul $dst, $rhs", > - [(set GPR:$dst, (mul GPR:$lhs, GPR:$rhs))]>; > + [(set tGPR:$dst, (mul tGPR:$lhs, tGPR:$rhs))]>; > > -def tMVN : TI<(outs GPR:$dst), (ins GPR:$src), > +def tMVN : TI<(outs tGPR:$dst), (ins tGPR:$src), > "mvn $dst, $src", > - [(set GPR:$dst, (not GPR:$src))]>; > + [(set tGPR:$dst, (not tGPR:$src))]>; > > -def tNEG : TI<(outs GPR:$dst), (ins GPR:$src), > +def tNEG : TI<(outs tGPR:$dst), (ins tGPR:$src), > "neg $dst, $src", > - [(set GPR:$dst, (ineg GPR:$src))]>; > + [(set tGPR:$dst, (ineg tGPR:$src))]>; > > -def tORR : TIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), > +def tORR : TIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), > "orr $dst, $rhs", > - [(set GPR:$dst, (or GPR:$lhs, GPR:$rhs))]>; > + [(set tGPR:$dst, (or tGPR:$lhs, tGPR:$rhs))]>; > > > -def tREV : TI<(outs GPR:$dst), (ins GPR:$src), > +def tREV : TI<(outs tGPR:$dst), (ins tGPR:$src), > "rev $dst, $src", > - [(set GPR:$dst, (bswap GPR:$src))]>, > + [(set tGPR:$dst, (bswap tGPR:$src))]>, > Requires<[IsThumb, HasV6]>; > > -def tREV16 : TI<(outs GPR:$dst), (ins GPR:$src), > +def tREV16 : TI<(outs tGPR:$dst), (ins tGPR:$src), > "rev16 $dst, $src", > - [(set GPR:$dst, > - (or (and (srl GPR:$src, 8), 0xFF), > - (or (and (shl GPR:$src, 8), 0xFF00), > - (or (and (srl GPR:$src, 8), 0xFF0000), > - (and (shl GPR:$src, 8), > 0xFF000000)))))]>, > + [(set tGPR:$dst, > + (or (and (srl tGPR:$src, 8), 0xFF), > + (or (and (shl tGPR:$src, 8), 0xFF00), > + (or (and (srl tGPR:$src, 8), 0xFF0000), > + (and (shl tGPR:$src, 8), > 0xFF000000)))))]>, > Requires<[IsThumb, HasV6]>; > > -def tREVSH : TI<(outs GPR:$dst), (ins GPR:$src), > +def tREVSH : TI<(outs tGPR:$dst), (ins tGPR:$src), > "revsh $dst, $src", > - [(set GPR:$dst, > + [(set tGPR:$dst, > (sext_inreg > - (or (srl (and GPR:$src, 0xFFFF), 8), > - (shl GPR:$src, 8)), i16))]>, > + (or (srl (and tGPR:$src, 0xFFFF), 8), > + (shl tGPR:$src, 8)), i16))]>, > Requires<[IsThumb, HasV6]>; > > -def tROR : TIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), > +def tROR : TIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), > "ror $dst, $rhs", > - [(set GPR:$dst, (rotr GPR:$lhs, GPR:$rhs))]>; > + [(set tGPR:$dst, (rotr tGPR:$lhs, tGPR:$rhs))]>; > > > // Subtract with carry > -def tSBC : TIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), > +def tSBC : TIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), > "sbc $dst, $rhs", > - [(set GPR:$dst, (sube GPR:$lhs, GPR:$rhs))]>; > + [(set tGPR:$dst, (sube tGPR:$lhs, tGPR:$rhs))]>; > > -def tSUBS : TI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), > +def tSUBS : TI<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), > "sub $dst, $lhs, $rhs", > - [(set GPR:$dst, (subc GPR:$lhs, GPR:$rhs))]>; > + [(set tGPR:$dst, (subc tGPR:$lhs, tGPR:$rhs))]>; > > > // TODO: A7-96: STMIA - store multiple. > > -def tSUBi3 : TI<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), > +def tSUBi3 : TI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), > "sub $dst, $lhs, $rhs", > - [(set GPR:$dst, (add GPR:$lhs, imm0_7_neg:$rhs))]>; > + [(set tGPR:$dst, (add tGPR:$lhs, imm0_7_neg:$rhs))]>; > > -def tSUBi8 : TIt<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), > +def tSUBi8 : TIt<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), > "sub $dst, $rhs", > - [(set GPR:$dst, (add GPR:$lhs, imm8_255_neg: > $rhs))]>; > + [(set tGPR:$dst, (add tGPR:$lhs, imm8_255_neg: > $rhs))]>; > > -def tSUBrr : TI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), > +def tSUBrr : TI<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), > "sub $dst, $lhs, $rhs", > - [(set GPR:$dst, (sub GPR:$lhs, GPR:$rhs))]>; > + [(set tGPR:$dst, (sub tGPR:$lhs, tGPR:$rhs))]>; > > -def tSUBspi : TIt<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), > +def tSUBspi : TIt<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), > "sub $dst, $rhs * 4", []>; > > -def tSXTB : TI<(outs GPR:$dst), (ins GPR:$src), > +def tSXTB : TI<(outs tGPR:$dst), (ins tGPR:$src), > "sxtb $dst, $src", > - [(set GPR:$dst, (sext_inreg GPR:$src, i8))]>, > + [(set tGPR:$dst, (sext_inreg tGPR:$src, i8))]>, > Requires<[IsThumb, HasV6]>; > -def tSXTH : TI<(outs GPR:$dst), (ins GPR:$src), > +def tSXTH : TI<(outs tGPR:$dst), (ins tGPR:$src), > "sxth $dst, $src", > - [(set GPR:$dst, (sext_inreg GPR:$src, i16))]>, > + [(set tGPR:$dst, (sext_inreg tGPR:$src, i16))]>, > Requires<[IsThumb, HasV6]>; > > > -def tUXTB : TI<(outs GPR:$dst), (ins GPR:$src), > +def tUXTB : TI<(outs tGPR:$dst), (ins tGPR:$src), > "uxtb $dst, $src", > - [(set GPR:$dst, (and GPR:$src, 0xFF))]>, > + [(set tGPR:$dst, (and tGPR:$src, 0xFF))]>, > Requires<[IsThumb, HasV6]>; > -def tUXTH : TI<(outs GPR:$dst), (ins GPR:$src), > +def tUXTH : TI<(outs tGPR:$dst), (ins tGPR:$src), > "uxth $dst, $src", > - [(set GPR:$dst, (and GPR:$src, 0xFFFF))]>, > + [(set tGPR:$dst, (and tGPR:$src, 0xFFFF))]>, > Requires<[IsThumb, HasV6]>; > > > @@ -483,20 +491,20 @@ > // Expanded by the scheduler into a branch sequence. > let usesCustomDAGSchedInserter = 1 in // Expanded by the scheduler. > def tMOVCCr : > - PseudoInst<(outs GPR:$dst), (ins GPR:$false, GPR:$true, pred:$cc), > + PseudoInst<(outs tGPR:$dst), (ins tGPR:$false, tGPR:$true, pred: > $cc), > "@ tMOVCCr $cc", > - [/*(set GPR:$dst, (ARMcmov GPR:$false, GPR:$true, imm: > $cc))*/]>; > + [/*(set tGPR:$dst, (ARMcmov tGPR:$false, tGPR:$true, > imm:$cc))*/]>; > > // tLEApcrel - Load a pc-relative address into a register without > offending the > // assembler. > -def tLEApcrel : TIx2<(outs GPR:$dst), (ins i32imm:$label), > +def tLEApcrel : TIx2<(outs tGPR:$dst), (ins i32imm:$label), > !strconcat(!strconcat(".set PCRELV${:uid}, > ($label-(", > "${:private}PCRELL${:uid} > +4))\n"), > !strconcat("\tmov $dst, #PCRELV${:uid} > \n", > "${:private}PCRELL${:uid}:\n\tadd > $dst, pc")), > []>; > > -def tLEApcrelJT : TIx2<(outs GPR:$dst), (ins i32imm:$label, i32imm: > $id), > +def tLEApcrelJT : TIx2<(outs tGPR:$dst), (ins i32imm:$label, i32imm: > $id), > !strconcat(!strconcat(".set PCRELV${:uid}, (${label}_$ > {id:no_hash}-(", > "${:private}PCRELL${:uid} > +4))\n"), > !strconcat("\tmov $dst, #PCRELV${:uid}\n", > @@ -532,7 +540,7 @@ > def : ThumbV5Pat<(ARMcall texternalsym:$func), (tBLXi texternalsym: > $func)>; > > // Indirect calls to ARM routines > -def : ThumbV5Pat<(ARMcall GPR:$dst), (tBLXr GPR:$dst)>; > +def : ThumbV5Pat<(ARMcall tGPR:$dst), (tBLXr tGPR:$dst)>; > > // zextload i1 -> zextload i8 > def : ThumbPat<(zextloadi1 t_addrmode_s1:$addr), > > Modified: llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp?rev=68545&r1=68544&r2=68545&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp (original) > +++ llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp Tue Apr 7 > 15:34:09 2009 > @@ -211,6 +211,22 @@ > } > } > > +const TargetRegisterClass* > +ARMRegisterInfo::getPhysicalRegisterRegClass(unsigned Reg, MVT VT) > const { > + if (STI.isThumb()) { > + if (isLowRegister(Reg)) > + return ARM::tGPRRegisterClass; > + switch (Reg) { > + default: > + break; > + case ARM::R8: case ARM::R9: case ARM::R10: case ARM::R11: > + case ARM::R12: case ARM::SP: case ARM::LR: case ARM::PC: > + return ARM::GPRRegisterClass; > + } > + } > + return TargetRegisterInfo::getPhysicalRegisterRegClass(Reg, VT); > +} > + > const unsigned* > ARMRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { > static const unsigned CalleeSavedRegs[] = { > @@ -244,7 +260,16 @@ > &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, > &ARM::DPRRegClass, > 0 > }; > - return CalleeSavedRegClasses; > + static const TargetRegisterClass * const > ThumbCalleeSavedRegClasses[] = { > + &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::GPRRegClass, > + &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::tGPRRegClass, > + &ARM::tGPRRegClass,&ARM::tGPRRegClass,&ARM::tGPRRegClass, > + > + &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, > &ARM::DPRRegClass, > + &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, > &ARM::DPRRegClass, > + 0 > + }; > + return STI.isThumb() ? ThumbCalleeSavedRegClasses : > CalleeSavedRegClasses; > } > > BitVector ARMRegisterInfo::getReservedRegs(const MachineFunction > &MF) const { > @@ -400,7 +425,7 @@ > if (DestReg == ARM::SP) { > assert(BaseReg == ARM::SP && "Unexpected!"); > LdReg = ARM::R3; > - BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), ARM::R12) > + BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVlor2hir), ARM::R12) > .addReg(ARM::R3, false, false, true); > } > > @@ -423,7 +448,7 @@ > else > MIB.addReg(LdReg).addReg(BaseReg, false, false, true); > if (DestReg == ARM::SP) > - BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), ARM::R3) > + BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVhir2lor), ARM::R3) > .addReg(ARM::R12, false, false, true); > } > > @@ -616,6 +641,7 @@ > unsigned findScratchRegister(RegScavenger *RS, const > TargetRegisterClass *RC, > ARMFunctionInfo *AFI) { > unsigned Reg = RS ? RS->FindUnusedReg(RC, true) : (unsigned) > ARM::R12; > + assert (!AFI->isThumbFunction()); > if (Reg == 0) > // Try a already spilled CS register. > Reg = RS->FindUnusedReg(RC, AFI->getSpilledCSRegisters()); > @@ -717,7 +743,7 @@ > > if (Offset == 0) { > // Turn it into a move. > - MI.setDesc(TII.get(ARM::tMOVr)); > + MI.setDesc(TII.get(ARM::tMOVhir2lor)); > MI.getOperand(i).ChangeToRegister(FrameReg, false); > MI.RemoveOperand(i+1); > return; > @@ -891,12 +917,12 @@ > unsigned TmpReg = ARM::R3; > bool UseRR = false; > if (ValReg == ARM::R3) { > - BuildMI(MBB, II, dl, TII.get(ARM::tMOVr), ARM::R12) > + BuildMI(MBB, II, dl, TII.get(ARM::tMOVlor2hir), ARM::R12) > .addReg(ARM::R2, false, false, true); > TmpReg = ARM::R2; > } > if (TmpReg == ARM::R3 && AFI->isR3LiveIn()) > - BuildMI(MBB, II, dl, TII.get(ARM::tMOVr), ARM::R12) > + BuildMI(MBB, II, dl, TII.get(ARM::tMOVlor2hir), ARM::R12) > .addReg(ARM::R3, false, false, true); > if (Opcode == ARM::tSpill) { > if (FrameReg == ARM::SP) > @@ -919,10 +945,10 @@ > > MachineBasicBlock::iterator NII = next(II); > if (ValReg == ARM::R3) > - BuildMI(MBB, NII, dl, TII.get(ARM::tMOVr), ARM::R2) > + BuildMI(MBB, NII, dl, TII.get(ARM::tMOVhir2lor), ARM::R2) > .addReg(ARM::R12, false, false, true); > if (TmpReg == ARM::R3 && AFI->isR3LiveIn()) > - BuildMI(MBB, NII, dl, TII.get(ARM::tMOVr), ARM::R3) > + BuildMI(MBB, NII, dl, TII.get(ARM::tMOVhir2lor), ARM::R3) > .addReg(ARM::R12, false, false, true); > } else > assert(false && "Unexpected opcode!"); > @@ -1401,7 +1427,8 @@ > emitThumbRegPlusImmediate(MBB, MBBI, ARM::SP, FramePtr, - > NumBytes, > TII, *this, dl); > else > - BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), > ARM::SP).addReg(FramePtr); > + BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVlor2hir), ARM::SP) > + .addReg(FramePtr); > } else { > if (MBBI->getOpcode() == ARM::tBX_RET && > &MBB.front() != MBBI && > > Modified: llvm/trunk/lib/Target/ARM/ARMRegisterInfo.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMRegisterInfo.h?rev=68545&r1=68544&r2=68545&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/ARM/ARMRegisterInfo.h (original) > +++ llvm/trunk/lib/Target/ARM/ARMRegisterInfo.h Tue Apr 7 15:34:09 > 2009 > @@ -54,6 +54,8 @@ > const TargetRegisterClass *getPointerRegClass() const; > > /// Code Generation virtual methods... > + const TargetRegisterClass * > + getPhysicalRegisterRegClass(unsigned Reg, MVT VT = MVT::Other) > const; > const unsigned *getCalleeSavedRegs(const MachineFunction *MF = 0) > const; > > const TargetRegisterClass* const* > > Modified: llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td?rev=68545&r1=68544&r2=68545&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td (original) > +++ llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td Tue Apr 7 15:34:09 > 2009 > @@ -130,17 +130,10 @@ > ARM::R8, ARM::R10,ARM::R11, > ARM::R7 }; > > - // FP is R7, only low registers available. > - static const unsigned THUMB_GPR_AO[] = { > - ARM::R2, ARM::R1, ARM::R0, > - ARM::R4, ARM::R5, ARM::R6, ARM::R7 }; > - > GPRClass::iterator > GPRClass::allocation_order_begin(const MachineFunction &MF) > const { > const TargetMachine &TM = MF.getTarget(); > const ARMSubtarget &Subtarget = TM.getSubtarget(); > - if (Subtarget.isThumb()) > - return THUMB_GPR_AO; > if (Subtarget.useThumbBacktraces()) { > if (Subtarget.isR9Reserved()) > return ARM_GPR_AO_4; > @@ -160,9 +153,8 @@ > const TargetRegisterInfo *RI = TM.getRegisterInfo(); > const ARMSubtarget &Subtarget = TM.getSubtarget(); > GPRClass::iterator I; > - if (Subtarget.isThumb()) > - I = THUMB_GPR_AO + (sizeof(THUMB_GPR_AO)/sizeof(unsigned)); > - else if (Subtarget.useThumbBacktraces()) { > + > + if (Subtarget.useThumbBacktraces()) { > if (Subtarget.isR9Reserved()) { > I = ARM_GPR_AO_4 + (sizeof(ARM_GPR_AO_4)/sizeof(unsigned)); > } else { > @@ -182,6 +174,40 @@ > }]; > } > > +// Thumb registers are R0-R7 normally. Some instructions can still > use > +// the general GPR register class above (MOV, e.g.) > +def tGPR : RegisterClass<"ARM", [i32], 32, [R0, R1, R2, R3, R4, R5, > R6, R7]> { > + let MethodProtos = [{ > + iterator allocation_order_begin(const MachineFunction &MF) const; > + iterator allocation_order_end(const MachineFunction &MF) const; > + }]; > + // FIXME: We are reserving r3 in Thumb mode in case the PEI needs > to use it > + // to generate large stack offset. Make it available once we have > register > + // scavenging. > + let MethodBodies = [{ > + static const unsigned THUMB_tGPR_AO[] = { > + ARM::R2, ARM::R1, ARM::R0, > + ARM::R4, ARM::R5, ARM::R6, ARM::R7 }; > + > + // FP is R7, only low registers available. > + tGPRClass::iterator > + tGPRClass::allocation_order_begin(const MachineFunction &MF) > const { > + return THUMB_tGPR_AO; > + } > + > + tGPRClass::iterator > + tGPRClass::allocation_order_end(const MachineFunction &MF) > const { > + const TargetMachine &TM = MF.getTarget(); > + const TargetRegisterInfo *RI = TM.getRegisterInfo(); > + const ARMSubtarget &Subtarget = TM.getSubtarget > (); > + tGPRClass::iterator I = > + THUMB_tGPR_AO + (sizeof(THUMB_tGPR_AO)/sizeof(unsigned)); > + // Mac OS X requires FP not to be clobbered for backtracing > purpose. > + return (Subtarget.isTargetDarwin() || RI->hasFP(MF)) ? I-1 : I; > + } > + }]; > +} > + > def SPR : RegisterClass<"ARM", [f32], 32, [S0, S1, S2, S3, S4, S5, > S6, S7, S8, > S9, S10, S11, S12, S13, S14, S15, S16, S17, S18, S19, S20, S21, S22, > S23, S24, S25, S26, S27, S28, S29, S30, S31]>; > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From dalej at apple.com Mon Apr 13 20:51:40 2009 From: dalej at apple.com (Dale Johannesen) Date: Tue, 14 Apr 2009 01:51:40 -0000 Subject: [llvm-commits] [llvm] r69018 - /llvm/trunk/test/CodeGen/ARM/2009-04-06-AsmModifier.ll Message-ID: <200904140151.n3E1peps024091@zion.cs.uiuc.edu> Author: johannes Date: Mon Apr 13 20:51:40 2009 New Revision: 69018 URL: http://llvm.org/viewvc/llvm-project?rev=69018&view=rev Log: Use the output of the asm so the optimizer won't delete it. Modified: llvm/trunk/test/CodeGen/ARM/2009-04-06-AsmModifier.ll Modified: llvm/trunk/test/CodeGen/ARM/2009-04-06-AsmModifier.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/2009-04-06-AsmModifier.ll?rev=69018&r1=69017&r2=69018&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/2009-04-06-AsmModifier.ll (original) +++ llvm/trunk/test/CodeGen/ARM/2009-04-06-AsmModifier.ll Mon Apr 13 20:51:40 2009 @@ -10,7 +10,8 @@ %fh = alloca i32 ; [#uses=1] %1 = load i32* %fh ; [#uses=1] %2 = load i32* %ptr ; [#uses=1] - %3 = call i32* asm "mov r0, $2; mov r1, $3; swi ${1:a}; mov $0, r0", "=r,i,r,r,~{r0},~{r1}"(i32 107, i32 %1, i32 %2) nounwind ; [#uses=0] + %3 = call i32 asm "mov r0, $2; mov r1, $3; swi ${1:a}; mov $0, r0", "=r,i,r,r,~{r0},~{r1}"(i32 107, i32 %1, i32 %2) nounwind ; [#uses=1] + store i32 %3, i32* %retval br label %return return: ; preds = %entry From evan.cheng at apple.com Mon Apr 13 20:24:33 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 13 Apr 2009 18:24:33 -0700 Subject: [llvm-commits] [llvm] r68545 - in /llvm/trunk: include/llvm/Target/TargetRegisterInfo.h lib/Target/ARM/ARMISelDAGToDAG.cpp lib/Target/ARM/ARMISelLowering.cpp lib/Target/ARM/ARMInstrInfo.cpp lib/Target/ARM/ARMInstrThumb.td lib/Target/ARM/ARMRegisterInfo.cpp lib/Target/ARM/ARMRegisterInfo.h lib/Target/ARM/ARMRegisterInfo.td In-Reply-To: <200904072034.n37KYAJU026667@zion.cs.uiuc.edu> References: <200904072034.n37KYAJU026667@zion.cs.uiuc.edu> Message-ID: <8A646114-F648-4815-9C05-94AB41FCC0A1@apple.com> Looks great. Thanks. Can you add some comments in ARMInstrThumb.td about tMOVhir2lor and friends? Evan On Apr 7, 2009, at 1:34 PM, Jim Grosbach wrote: > Author: grosbach > Date: Tue Apr 7 15:34:09 2009 > New Revision: 68545 > > URL: http://llvm.org/viewvc/llvm-project?rev=68545&view=rev > Log: > PR2985 / > > When compiling in Thumb mode, only the low (R0-R7) registers are > available > for most instructions. Breaking the low registers into a new > register class > handles this. Uses of R12, SP, etc, are handled explicitly where > needed > with copies inserted to move results into low registers where the > rest of > the code generator can deal with them. > > > Modified: > llvm/trunk/include/llvm/Target/TargetRegisterInfo.h > llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp > llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp > llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp > llvm/trunk/lib/Target/ARM/ARMInstrThumb.td > llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp > llvm/trunk/lib/Target/ARM/ARMRegisterInfo.h > llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td > > Modified: llvm/trunk/include/llvm/Target/TargetRegisterInfo.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetRegisterInfo.h?rev=68545&r1=68544&r2=68545&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/include/llvm/Target/TargetRegisterInfo.h (original) > +++ llvm/trunk/include/llvm/Target/TargetRegisterInfo.h Tue Apr 7 > 15:34:09 2009 > @@ -273,8 +273,8 @@ > /// getPhysicalRegisterRegClass - Returns the Register Class of a > physical > /// register of the given type. If type is MVT::Other, then just > return any > /// register class the register belongs to. > - const TargetRegisterClass *getPhysicalRegisterRegClass(unsigned > Reg, > - MVT VT = MVT::Other) const; > + virtual const TargetRegisterClass * > + getPhysicalRegisterRegClass(unsigned Reg, MVT VT = MVT::Other) > const; > > /// getAllocatableSet - Returns a bitset indexed by register number > /// indicating if a register is allocatable or not. If a register > class is > > Modified: llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp?rev=68545&r1=68544&r2=68545&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp (original) > +++ llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp Tue Apr 7 > 15:34:09 2009 > @@ -584,10 +584,10 @@ > // Selects to ADDri FI, 0 which in turn will become ADDri SP, imm. > int FI = cast(N)->getIndex(); > SDValue TFI = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); > - if (Subtarget->isThumb()) > + if (Subtarget->isThumb()) { > return CurDAG->SelectNodeTo(N, ARM::tADDrSPi, MVT::i32, TFI, > CurDAG->getTargetConstant(0, > MVT::i32)); > - else { > + } else { > SDValue Ops[] = { TFI, CurDAG->getTargetConstant(0, MVT::i32), > getAL(CurDAG), CurDAG->getRegister(0, > MVT::i32), > CurDAG->getRegister(0, MVT::i32) }; > @@ -607,7 +607,9 @@ > std::swap(LHSR, RHSR); > } > if (RHSR && RHSR->getReg() == ARM::SP) { > - return CurDAG->SelectNodeTo(N, ARM::tADDhirr, Op.getValueType > (), N0, N1); > + SDValue Val = SDValue(CurDAG->getTargetNode(ARM::tMOVlor2hir, > dl, > + Op.getValueType(), N0, N0), 0); > + return CurDAG->SelectNodeTo(N, ARM::tADDhirr, Op.getValueType > (), Val, N1); > } > break; > } > > Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=68545&r1=68544&r2=68545&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) > +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Tue Apr 7 > 15:34:09 2009 > @@ -117,7 +117,10 @@ > } > } > > - addRegisterClass(MVT::i32, ARM::GPRRegisterClass); > + if (Subtarget->isThumb()) > + addRegisterClass(MVT::i32, ARM::tGPRRegisterClass); > + else > + addRegisterClass(MVT::i32, ARM::GPRRegisterClass); > if (!UseSoftFloat && Subtarget->hasVFP2() && !Subtarget->isThumb > ()) { > addRegisterClass(MVT::f32, ARM::SPRRegisterClass); > addRegisterClass(MVT::f64, ARM::DPRRegisterClass); > @@ -937,6 +940,7 @@ > MVT ObjectVT = Op.getValue(ArgNo).getValueType(); > SDValue Root = Op.getOperand(0); > MachineRegisterInfo &RegInfo = MF.getRegInfo(); > + ARMFunctionInfo *AFI = MF.getInfo(); > > static const unsigned GPRArgRegs[] = { > ARM::R0, ARM::R1, ARM::R2, ARM::R3 > @@ -955,17 +959,28 @@ > > SDValue ArgValue; > if (ObjGPRs == 1) { > - unsigned VReg = RegInfo.createVirtualRegister(&ARM::GPRRegClass); > + unsigned VReg; > + if (AFI->isThumbFunction()) > + VReg = RegInfo.createVirtualRegister(ARM::tGPRRegisterClass); > + else > + VReg = RegInfo.createVirtualRegister(ARM::GPRRegisterClass); > RegInfo.addLiveIn(GPRArgRegs[NumGPRs], VReg); > ArgValue = DAG.getCopyFromReg(Root, dl, VReg, MVT::i32); > if (ObjectVT == MVT::f32) > ArgValue = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::f32, > ArgValue); > } else if (ObjGPRs == 2) { > - unsigned VReg = RegInfo.createVirtualRegister(&ARM::GPRRegClass); > + unsigned VReg; > + if (AFI->isThumbFunction()) > + VReg = RegInfo.createVirtualRegister(ARM::tGPRRegisterClass); > + else > + VReg = RegInfo.createVirtualRegister(ARM::GPRRegisterClass); > RegInfo.addLiveIn(GPRArgRegs[NumGPRs], VReg); > ArgValue = DAG.getCopyFromReg(Root, dl, VReg, MVT::i32); > > - VReg = RegInfo.createVirtualRegister(&ARM::GPRRegClass); > + if (AFI->isThumbFunction()) > + VReg = RegInfo.createVirtualRegister(ARM::tGPRRegisterClass); > + else > + VReg = RegInfo.createVirtualRegister(ARM::GPRRegisterClass); > RegInfo.addLiveIn(GPRArgRegs[NumGPRs+1], VReg); > SDValue ArgValue2 = DAG.getCopyFromReg(Root, dl, VReg, MVT::i32); > > @@ -1029,7 +1044,11 @@ > > SmallVector MemOps; > for (; NumGPRs < 4; ++NumGPRs) { > - unsigned VReg = RegInfo.createVirtualRegister > (&ARM::GPRRegClass); > + unsigned VReg; > + if (AFI->isThumbFunction()) > + VReg = RegInfo.createVirtualRegister > (ARM::tGPRRegisterClass); > + else > + VReg = RegInfo.createVirtualRegister > (ARM::GPRRegisterClass); > RegInfo.addLiveIn(GPRArgRegs[NumGPRs], VReg); > SDValue Val = DAG.getCopyFromReg(Root, dl, VReg, MVT::i32); > SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN, > NULL, 0); > @@ -1965,8 +1984,10 @@ > // GCC RS6000 Constraint Letters > switch (Constraint[0]) { > case 'l': > - // FIXME: in thumb mode, 'l' is only low-regs. > - // FALL THROUGH. > + if (Subtarget->isThumb()) > + return std::make_pair(0U, ARM::tGPRRegisterClass); > + else > + return std::make_pair(0U, ARM::GPRRegisterClass); > case 'r': > return std::make_pair(0U, ARM::GPRRegisterClass); > case 'w': > @@ -1989,6 +2010,9 @@ > switch (Constraint[0]) { // GCC ARM Constraint Letters > default: break; > case 'l': > + return make_vector(ARM::R0, ARM::R1, ARM::R2, ARM::R3, > + ARM::R4, ARM::R5, ARM::R6, ARM::R7, > + 0); > case 'r': > return make_vector(ARM::R0, ARM::R1, ARM::R2, ARM::R3, > ARM::R4, ARM::R5, ARM::R6, ARM::R7, > > Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp?rev=68545&r1=68544&r2=68545&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp (original) > +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp Tue Apr 7 15:34:09 > 2009 > @@ -64,6 +64,9 @@ > return true; > case ARM::MOVr: > case ARM::tMOVr: > + case ARM::tMOVhir2lor: > + case ARM::tMOVlor2hir: > + case ARM::tMOVhir2hir: > assert(MI.getDesc().getNumOperands() >= 2 && > MI.getOperand(0).isReg() && > MI.getOperand(1).isReg() && > @@ -483,23 +486,43 @@ > unsigned DestReg, unsigned SrcReg, > const TargetRegisterClass *DestRC, > const TargetRegisterClass *SrcRC) > const { > + MachineFunction &MF = *MBB.getParent(); > + ARMFunctionInfo *AFI = MF.getInfo(); > + DebugLoc DL = DebugLoc::getUnknownLoc(); > + if (I != MBB.end()) DL = I->getDebugLoc(); > + > + if (!AFI->isThumbFunction()) { > + if (DestRC == ARM::GPRRegisterClass) { > + AddDefaultCC(AddDefaultPred(BuildMI(MBB, I, DL, get > (ARM::MOVr), DestReg) > + .addReg(SrcReg))); > + return true; > + } > + } else { > + if (DestRC == ARM::GPRRegisterClass) { > + if (SrcRC == ARM::GPRRegisterClass) { > + BuildMI(MBB, I, DL, get(ARM::tMOVhir2hir), DestReg).addReg > (SrcReg); > + return true; > + } else if (SrcRC == ARM::tGPRRegisterClass) { > + BuildMI(MBB, I, DL, get(ARM::tMOVlor2hir), DestReg).addReg > (SrcReg); > + return true; > + } > + } else if (DestRC == ARM::tGPRRegisterClass) { > + if (SrcRC == ARM::GPRRegisterClass) { > + BuildMI(MBB, I, DL, get(ARM::tMOVhir2lor), DestReg).addReg > (SrcReg); > + return true; > + } else if (SrcRC == ARM::tGPRRegisterClass) { > + BuildMI(MBB, I, DL, get(ARM::tMOVr), DestReg).addReg(SrcReg); > + return true; > + } > + } > + } > if (DestRC != SrcRC) { > // Not yet supported! > return false; > } > > - DebugLoc DL = DebugLoc::getUnknownLoc(); > - if (I != MBB.end()) DL = I->getDebugLoc(); > > - if (DestRC == ARM::GPRRegisterClass) { > - MachineFunction &MF = *MBB.getParent(); > - ARMFunctionInfo *AFI = MF.getInfo(); > - if (AFI->isThumbFunction()) > - BuildMI(MBB, I, DL, get(ARM::tMOVr), DestReg).addReg(SrcReg); > - else > - AddDefaultCC(AddDefaultPred(BuildMI(MBB, I, DL, get > (ARM::MOVr), DestReg) > - .addReg(SrcReg))); > - } else if (DestRC == ARM::SPRRegisterClass) > + if (DestRC == ARM::SPRRegisterClass) > AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FCPYS), DestReg) > .addReg(SrcReg)); > else if (DestRC == ARM::DPRRegisterClass) > @@ -521,14 +544,17 @@ > if (RC == ARM::GPRRegisterClass) { > MachineFunction &MF = *MBB.getParent(); > ARMFunctionInfo *AFI = MF.getInfo(); > - if (AFI->isThumbFunction()) > - BuildMI(MBB, I, DL, get(ARM::tSpill)) > - .addReg(SrcReg, false, false, isKill) > - .addFrameIndex(FI).addImm(0); > - else > - AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::STR)) > - .addReg(SrcReg, false, false, isKill) > - .addFrameIndex(FI).addReg(0).addImm(0)); > + assert (!AFI->isThumbFunction()); > + AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::STR)) > + .addReg(SrcReg, false, false, isKill) > + .addFrameIndex(FI).addReg(0).addImm(0)); > + } else if (RC == ARM::tGPRRegisterClass) { > + MachineFunction &MF = *MBB.getParent(); > + ARMFunctionInfo *AFI = MF.getInfo(); > + assert (AFI->isThumbFunction()); > + BuildMI(MBB, I, DL, get(ARM::tSpill)) > + .addReg(SrcReg, false, false, isKill) > + .addFrameIndex(FI).addImm(0); > } else if (RC == ARM::DPRRegisterClass) { > AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FSTD)) > .addReg(SrcReg, false, false, isKill) > @@ -586,12 +612,15 @@ > if (RC == ARM::GPRRegisterClass) { > MachineFunction &MF = *MBB.getParent(); > ARMFunctionInfo *AFI = MF.getInfo(); > - if (AFI->isThumbFunction()) > - BuildMI(MBB, I, DL, get(ARM::tRestore), DestReg) > - .addFrameIndex(FI).addImm(0); > - else > - AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::LDR), DestReg) > - .addFrameIndex(FI).addReg(0).addImm(0)); > + assert (!AFI->isThumbFunction()); > + AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::LDR), DestReg) > + .addFrameIndex(FI).addReg(0).addImm(0)); > + } else if (RC == ARM::tGPRRegisterClass) { > + MachineFunction &MF = *MBB.getParent(); > + ARMFunctionInfo *AFI = MF.getInfo(); > + assert (AFI->isThumbFunction()); > + BuildMI(MBB, I, DL, get(ARM::tRestore), DestReg) > + .addFrameIndex(FI).addImm(0); > } else if (RC == ARM::DPRRegisterClass) { > AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FLDD), DestReg) > .addFrameIndex(FI).addImm(0)); > @@ -715,7 +744,10 @@ > } > break; > } > - case ARM::tMOVr: { > + case ARM::tMOVr: > + case ARM::tMOVlor2hir: > + case ARM::tMOVhir2lor: > + case ARM::tMOVhir2hir: { > if (OpNum == 0) { // move -> store > unsigned SrcReg = MI->getOperand(1).getReg(); > bool isKill = MI->getOperand(1).isKill(); > @@ -788,7 +820,10 @@ > case ARM::MOVr: > // If it is updating CPSR, then it cannot be folded. > return MI->getOperand(4).getReg() != ARM::CPSR; > - case ARM::tMOVr: { > + case ARM::tMOVr: > + case ARM::tMOVlor2hir: > + case ARM::tMOVhir2lor: > + case ARM::tMOVhir2hir: { > if (OpNum == 0) { // move -> store > unsigned SrcReg = MI->getOperand(1).getReg(); > if (RI.isPhysicalRegister(SrcReg) && !RI.isLowRegister(SrcReg)) > > Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb.td > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb.td?rev=68545&r1=68544&r2=68545&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/ARM/ARMInstrThumb.td (original) > +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb.td Tue Apr 7 15:34:09 > 2009 > @@ -73,7 +73,7 @@ > def t_addrmode_rr : Operand, > ComplexPattern []> { > let PrintMethod = "printThumbAddrModeRROperand"; > - let MIOperandInfo = (ops GPR:$base, GPR:$offsreg); > + let MIOperandInfo = (ops tGPR:$base, tGPR:$offsreg); > } > > // t_addrmode_s4 := reg + reg > @@ -82,7 +82,7 @@ > def t_addrmode_s4 : Operand, > ComplexPattern []> { > let PrintMethod = "printThumbAddrModeS4Operand"; > - let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm, GPR:$offsreg); > + let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm, tGPR: > $offsreg); > } > > // t_addrmode_s2 := reg + reg > @@ -91,7 +91,7 @@ > def t_addrmode_s2 : Operand, > ComplexPattern []> { > let PrintMethod = "printThumbAddrModeS2Operand"; > - let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm, GPR:$offsreg); > + let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm, tGPR: > $offsreg); > } > > // t_addrmode_s1 := reg + reg > @@ -100,7 +100,7 @@ > def t_addrmode_s1 : Operand, > ComplexPattern []> { > let PrintMethod = "printThumbAddrModeS1Operand"; > - let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm, GPR:$offsreg); > + let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm, tGPR: > $offsreg); > } > > // t_addrmode_sp := sp + imm8 * 4 > @@ -108,7 +108,7 @@ > def t_addrmode_sp : Operand, > ComplexPattern []> { > let PrintMethod = "printThumbAddrModeSPOperand"; > - let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm); > + let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm); > } > > // > = > = > = > ----------------------------------------------------------------------= > ==// > @@ -128,9 +128,9 @@ > } > > let isNotDuplicable = 1 in > -def tPICADD : TIt<(outs GPR:$dst), (ins GPR:$lhs, pclabel:$cp), > +def tPICADD : TIt<(outs tGPR:$dst), (ins tGPR:$lhs, pclabel:$cp), > "$cp:\n\tadd $dst, pc", > - [(set GPR:$dst, (ARMpic_add GPR:$lhs, imm:$cp))]>; > + [(set tGPR:$dst, (ARMpic_add tGPR:$lhs, imm:$cp))] > >; > > // > = > = > = > ----------------------------------------------------------------------= > ==// > // Control Flow Instructions. > @@ -139,7 +139,7 @@ > let isReturn = 1, isTerminator = 1 in { > def tBX_RET : TI<(outs), (ins), "bx lr", [(ARMretflag)]>; > // Alternative return instruction used by vararg functions. > - def tBX_RET_vararg : TI<(outs), (ins GPR:$target), "bx $target", > []>; > + def tBX_RET_vararg : TI<(outs), (ins tGPR:$target), "bx $target", > []>; > } > > // FIXME: remove when we have a way to marking a MI with these > properties. > @@ -157,13 +157,13 @@ > def tBLXi : TIx2<(outs), (ins i32imm:$func, variable_ops), > "blx ${func:call}", > [(ARMcall tglobaladdr:$func)]>, Requires<[HasV5T] > >; > - def tBLXr : TI<(outs), (ins GPR:$func, variable_ops), > + def tBLXr : TI<(outs), (ins tGPR:$func, variable_ops), > "blx $func", > - [(ARMtcall GPR:$func)]>, Requires<[HasV5T]>; > + [(ARMtcall tGPR:$func)]>, Requires<[HasV5T]>; > // ARMv4T > - def tBX : TIx2<(outs), (ins GPR:$func, variable_ops), > + def tBX : TIx2<(outs), (ins tGPR:$func, variable_ops), > "cpy lr, pc\n\tbx $func", > - [(ARMcall_nolink GPR:$func)]>; > + [(ARMcall_nolink tGPR:$func)]>; > } > > let isBranch = 1, isTerminator = 1 in { > @@ -176,9 +176,9 @@ > def tBfar : TIx2<(outs), (ins brtarget:$target), "bl $target\t@ > far jump",[]>; > > def tBR_JTr : TJTI<(outs), > - (ins GPR:$target, jtblock_operand:$jt, i32imm: > $id), > + (ins tGPR:$target, jtblock_operand:$jt, i32imm: > $id), > "cpy pc, $target \n\t.align\t2\n$jt", > - [(ARMbrjt GPR:$target, tjumptable:$jt, imm: > $id)]>; > + [(ARMbrjt tGPR:$target, tjumptable:$jt, imm: > $id)]>; > } > } > > @@ -193,68 +193,68 @@ > // > > let canFoldAsLoad = 1 in > -def tLDR : TI4<(outs GPR:$dst), (ins t_addrmode_s4:$addr), > +def tLDR : TI4<(outs tGPR:$dst), (ins t_addrmode_s4:$addr), > "ldr $dst, $addr", > - [(set GPR:$dst, (load t_addrmode_s4:$addr))]>; > + [(set tGPR:$dst, (load t_addrmode_s4:$addr))]>; > > -def tLDRB : TI1<(outs GPR:$dst), (ins t_addrmode_s1:$addr), > +def tLDRB : TI1<(outs tGPR:$dst), (ins t_addrmode_s1:$addr), > "ldrb $dst, $addr", > - [(set GPR:$dst, (zextloadi8 t_addrmode_s1:$addr))]>; > + [(set tGPR:$dst, (zextloadi8 t_addrmode_s1:$addr))]>; > > -def tLDRH : TI2<(outs GPR:$dst), (ins t_addrmode_s2:$addr), > +def tLDRH : TI2<(outs tGPR:$dst), (ins t_addrmode_s2:$addr), > "ldrh $dst, $addr", > - [(set GPR:$dst, (zextloadi16 t_addrmode_s2:$addr))]>; > + [(set tGPR:$dst, (zextloadi16 t_addrmode_s2:$addr))] > >; > > -def tLDRSB : TI1<(outs GPR:$dst), (ins t_addrmode_rr:$addr), > +def tLDRSB : TI1<(outs tGPR:$dst), (ins t_addrmode_rr:$addr), > "ldrsb $dst, $addr", > - [(set GPR:$dst, (sextloadi8 t_addrmode_rr:$addr))]>; > + [(set tGPR:$dst, (sextloadi8 t_addrmode_rr:$addr))] > >; > > -def tLDRSH : TI2<(outs GPR:$dst), (ins t_addrmode_rr:$addr), > +def tLDRSH : TI2<(outs tGPR:$dst), (ins t_addrmode_rr:$addr), > "ldrsh $dst, $addr", > - [(set GPR:$dst, (sextloadi16 t_addrmode_rr:$addr))] > >; > + [(set tGPR:$dst, (sextloadi16 t_addrmode_rr: > $addr))]>; > > let canFoldAsLoad = 1 in > -def tLDRspi : TIs<(outs GPR:$dst), (ins t_addrmode_sp:$addr), > +def tLDRspi : TIs<(outs tGPR:$dst), (ins t_addrmode_sp:$addr), > "ldr $dst, $addr", > - [(set GPR:$dst, (load t_addrmode_sp:$addr))]>; > + [(set tGPR:$dst, (load t_addrmode_sp:$addr))]>; > > // Special instruction for restore. It cannot clobber condition > register > // when it's expanded by eliminateCallFramePseudoInstr(). > let canFoldAsLoad = 1, mayLoad = 1 in > -def tRestore : TIs<(outs GPR:$dst), (ins t_addrmode_sp:$addr), > +def tRestore : TIs<(outs tGPR:$dst), (ins t_addrmode_sp:$addr), > "ldr $dst, $addr", []>; > > // Load tconstpool > let canFoldAsLoad = 1 in > -def tLDRpci : TIs<(outs GPR:$dst), (ins i32imm:$addr), > +def tLDRpci : TIs<(outs tGPR:$dst), (ins i32imm:$addr), > "ldr $dst, $addr", > - [(set GPR:$dst, (load (ARMWrapper tconstpool: > $addr)))]>; > + [(set tGPR:$dst, (load (ARMWrapper tconstpool: > $addr)))]>; > > // Special LDR for loads from non-pc-relative constpools. > let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1 in > -def tLDRcp : TIs<(outs GPR:$dst), (ins i32imm:$addr), > +def tLDRcp : TIs<(outs tGPR:$dst), (ins i32imm:$addr), > "ldr $dst, $addr", []>; > > -def tSTR : TI4<(outs), (ins GPR:$src, t_addrmode_s4:$addr), > +def tSTR : TI4<(outs), (ins tGPR:$src, t_addrmode_s4:$addr), > "str $src, $addr", > - [(store GPR:$src, t_addrmode_s4:$addr)]>; > + [(store tGPR:$src, t_addrmode_s4:$addr)]>; > > -def tSTRB : TI1<(outs), (ins GPR:$src, t_addrmode_s1:$addr), > +def tSTRB : TI1<(outs), (ins tGPR:$src, t_addrmode_s1:$addr), > "strb $src, $addr", > - [(truncstorei8 GPR:$src, t_addrmode_s1:$addr)]>; > + [(truncstorei8 tGPR:$src, t_addrmode_s1:$addr)]>; > > -def tSTRH : TI2<(outs), (ins GPR:$src, t_addrmode_s2:$addr), > +def tSTRH : TI2<(outs), (ins tGPR:$src, t_addrmode_s2:$addr), > "strh $src, $addr", > - [(truncstorei16 GPR:$src, t_addrmode_s2:$addr)]>; > + [(truncstorei16 tGPR:$src, t_addrmode_s2:$addr)]>; > > -def tSTRspi : TIs<(outs), (ins GPR:$src, t_addrmode_sp:$addr), > +def tSTRspi : TIs<(outs), (ins tGPR:$src, t_addrmode_sp:$addr), > "str $src, $addr", > - [(store GPR:$src, t_addrmode_sp:$addr)]>; > + [(store tGPR:$src, t_addrmode_sp:$addr)]>; > > let mayStore = 1 in { > // Special instruction for spill. It cannot clobber condition register > // when it's expanded by eliminateCallFramePseudoInstr(). > -def tSpill : TIs<(outs), (ins GPR:$src, t_addrmode_sp:$addr), > +def tSpill : TIs<(outs), (ins tGPR:$src, t_addrmode_sp:$addr), > "str $src, $addr", []>; > } > > @@ -277,205 +277,213 @@ > // > > // Add with carry > -def tADC : TIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), > +def tADC : TIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), > "adc $dst, $rhs", > - [(set GPR:$dst, (adde GPR:$lhs, GPR:$rhs))]>; > + [(set tGPR:$dst, (adde tGPR:$lhs, tGPR:$rhs))]>; > > -def tADDS : TI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), > +def tADDS : TI<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), > "add $dst, $lhs, $rhs", > - [(set GPR:$dst, (addc GPR:$lhs, GPR:$rhs))]>; > + [(set tGPR:$dst, (addc tGPR:$lhs, tGPR:$rhs))]>; > > > -def tADDi3 : TI<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), > +def tADDi3 : TI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), > "add $dst, $lhs, $rhs", > - [(set GPR:$dst, (add GPR:$lhs, imm0_7:$rhs))]>; > + [(set tGPR:$dst, (add tGPR:$lhs, imm0_7:$rhs))]>; > > -def tADDi8 : TIt<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), > +def tADDi8 : TIt<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), > "add $dst, $rhs", > - [(set GPR:$dst, (add GPR:$lhs, imm8_255:$rhs))]>; > + [(set tGPR:$dst, (add tGPR:$lhs, imm8_255:$rhs))]>; > > -def tADDrr : TI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), > +def tADDrr : TI<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), > "add $dst, $lhs, $rhs", > - [(set GPR:$dst, (add GPR:$lhs, GPR:$rhs))]>; > + [(set tGPR:$dst, (add tGPR:$lhs, tGPR:$rhs))]>; > > -def tADDhirr : TIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), > - "add $dst, $rhs", []>; > +def tADDhirr : TIt<(outs tGPR:$dst), (ins GPR:$lhs, GPR:$rhs), > + "add $dst, $rhs @ addhirr", []>; > > -def tADDrPCi : TI<(outs GPR:$dst), (ins i32imm:$rhs), > +def tADDrPCi : TI<(outs tGPR:$dst), (ins i32imm:$rhs), > "add $dst, pc, $rhs * 4", []>; > -def tADDrSPi : TI<(outs GPR:$dst), (ins GPR:$sp, i32imm:$rhs), > - "add $dst, $sp, $rhs * 4", []>; > -def tADDspi : TIt<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), > + > +def tADDrSPi : TI<(outs tGPR:$dst), (ins GPR:$sp, i32imm:$rhs), > + "add $dst, $sp, $rhs * 4 @ addrspi", []>; > + > +def tADDspi : TIt<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), > "add $dst, $rhs * 4", []>; > > -def tAND : TIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), > +def tAND : TIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), > "and $dst, $rhs", > - [(set GPR:$dst, (and GPR:$lhs, GPR:$rhs))]>; > + [(set tGPR:$dst, (and tGPR:$lhs, tGPR:$rhs))]>; > > -def tASRri : TI<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), > +def tASRri : TI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), > "asr $dst, $lhs, $rhs", > - [(set GPR:$dst, (sra GPR:$lhs, imm:$rhs))]>; > + [(set tGPR:$dst, (sra tGPR:$lhs, imm:$rhs))]>; > > -def tASRrr : TIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), > +def tASRrr : TIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), > "asr $dst, $rhs", > - [(set GPR:$dst, (sra GPR:$lhs, GPR:$rhs))]>; > + [(set tGPR:$dst, (sra tGPR:$lhs, tGPR:$rhs))]>; > > -def tBIC : TIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), > +def tBIC : TIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), > "bic $dst, $rhs", > - [(set GPR:$dst, (and GPR:$lhs, (not GPR:$rhs)))]>; > + [(set tGPR:$dst, (and tGPR:$lhs, (not tGPR:$rhs)))]>; > > > -def tCMN : TI<(outs), (ins GPR:$lhs, GPR:$rhs), > +def tCMN : TI<(outs), (ins tGPR:$lhs, tGPR:$rhs), > "cmn $lhs, $rhs", > - [(ARMcmp GPR:$lhs, (ineg GPR:$rhs))]>; > + [(ARMcmp tGPR:$lhs, (ineg tGPR:$rhs))]>; > > -def tCMPi8 : TI<(outs), (ins GPR:$lhs, i32imm:$rhs), > +def tCMPi8 : TI<(outs), (ins tGPR:$lhs, i32imm:$rhs), > "cmp $lhs, $rhs", > - [(ARMcmp GPR:$lhs, imm0_255:$rhs)]>; > + [(ARMcmp tGPR:$lhs, imm0_255:$rhs)]>; > > -def tCMPr : TI<(outs), (ins GPR:$lhs, GPR:$rhs), > +def tCMPr : TI<(outs), (ins tGPR:$lhs, tGPR:$rhs), > "cmp $lhs, $rhs", > - [(ARMcmp GPR:$lhs, GPR:$rhs)]>; > + [(ARMcmp tGPR:$lhs, tGPR:$rhs)]>; > > -def tTST : TI<(outs), (ins GPR:$lhs, GPR:$rhs), > +def tTST : TI<(outs), (ins tGPR:$lhs, tGPR:$rhs), > "tst $lhs, $rhs", > - [(ARMcmpNZ (and GPR:$lhs, GPR:$rhs), 0)]>; > + [(ARMcmpNZ (and tGPR:$lhs, tGPR:$rhs), 0)]>; > > -def tCMNNZ : TI<(outs), (ins GPR:$lhs, GPR:$rhs), > +def tCMNNZ : TI<(outs), (ins tGPR:$lhs, tGPR:$rhs), > "cmn $lhs, $rhs", > - [(ARMcmpNZ GPR:$lhs, (ineg GPR:$rhs))]>; > + [(ARMcmpNZ tGPR:$lhs, (ineg tGPR:$rhs))]>; > > -def tCMPNZi8 : TI<(outs), (ins GPR:$lhs, i32imm:$rhs), > +def tCMPNZi8 : TI<(outs), (ins tGPR:$lhs, i32imm:$rhs), > "cmp $lhs, $rhs", > - [(ARMcmpNZ GPR:$lhs, imm0_255:$rhs)]>; > + [(ARMcmpNZ tGPR:$lhs, imm0_255:$rhs)]>; > > -def tCMPNZr : TI<(outs), (ins GPR:$lhs, GPR:$rhs), > +def tCMPNZr : TI<(outs), (ins tGPR:$lhs, tGPR:$rhs), > "cmp $lhs, $rhs", > - [(ARMcmpNZ GPR:$lhs, GPR:$rhs)]>; > + [(ARMcmpNZ tGPR:$lhs, tGPR:$rhs)]>; > > // TODO: A7-37: CMP(3) - cmp hi regs > > -def tEOR : TIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), > +def tEOR : TIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), > "eor $dst, $rhs", > - [(set GPR:$dst, (xor GPR:$lhs, GPR:$rhs))]>; > + [(set tGPR:$dst, (xor tGPR:$lhs, tGPR:$rhs))]>; > > -def tLSLri : TI<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), > +def tLSLri : TI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), > "lsl $dst, $lhs, $rhs", > - [(set GPR:$dst, (shl GPR:$lhs, imm:$rhs))]>; > + [(set tGPR:$dst, (shl tGPR:$lhs, imm:$rhs))]>; > > -def tLSLrr : TIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), > +def tLSLrr : TIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), > "lsl $dst, $rhs", > - [(set GPR:$dst, (shl GPR:$lhs, GPR:$rhs))]>; > + [(set tGPR:$dst, (shl tGPR:$lhs, tGPR:$rhs))]>; > > -def tLSRri : TI<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), > +def tLSRri : TI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), > "lsr $dst, $lhs, $rhs", > - [(set GPR:$dst, (srl GPR:$lhs, imm:$rhs))]>; > + [(set tGPR:$dst, (srl tGPR:$lhs, imm:$rhs))]>; > > -def tLSRrr : TIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), > +def tLSRrr : TIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), > "lsr $dst, $rhs", > - [(set GPR:$dst, (srl GPR:$lhs, GPR:$rhs))]>; > + [(set tGPR:$dst, (srl tGPR:$lhs, tGPR:$rhs))]>; > > // FIXME: This is not rematerializable because mov changes the > condition code. > -def tMOVi8 : TI<(outs GPR:$dst), (ins i32imm:$src), > +def tMOVi8 : TI<(outs tGPR:$dst), (ins i32imm:$src), > "mov $dst, $src", > - [(set GPR:$dst, imm0_255:$src)]>; > + [(set tGPR:$dst, imm0_255:$src)]>; > > // TODO: A7-73: MOV(2) - mov setting flag. > > > // Note: MOV(2) of two low regs updates the flags, so we emit this > as 'cpy', > // which is MOV(3). This also supports high registers. > -def tMOVr : TI<(outs GPR:$dst), (ins GPR:$src), > - "cpy $dst, $src", []>; > +def tMOVr : TI<(outs tGPR:$dst), (ins tGPR:$src), > + "cpy $dst, $src", []>; > +def tMOVhir2lor : TI<(outs tGPR:$dst), (ins GPR:$src), > + "cpy $dst, $src\t@ hir2lor", []>; > +def tMOVlor2hir : TI<(outs GPR:$dst), (ins tGPR:$src), > + "cpy $dst, $src\t@ lor2hir", []>; > +def tMOVhir2hir : TI<(outs GPR:$dst), (ins GPR:$src), > + "cpy $dst, $src\t@ hir2hir", []>; > > -def tMUL : TIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), > +def tMUL : TIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), > "mul $dst, $rhs", > - [(set GPR:$dst, (mul GPR:$lhs, GPR:$rhs))]>; > + [(set tGPR:$dst, (mul tGPR:$lhs, tGPR:$rhs))]>; > > -def tMVN : TI<(outs GPR:$dst), (ins GPR:$src), > +def tMVN : TI<(outs tGPR:$dst), (ins tGPR:$src), > "mvn $dst, $src", > - [(set GPR:$dst, (not GPR:$src))]>; > + [(set tGPR:$dst, (not tGPR:$src))]>; > > -def tNEG : TI<(outs GPR:$dst), (ins GPR:$src), > +def tNEG : TI<(outs tGPR:$dst), (ins tGPR:$src), > "neg $dst, $src", > - [(set GPR:$dst, (ineg GPR:$src))]>; > + [(set tGPR:$dst, (ineg tGPR:$src))]>; > > -def tORR : TIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), > +def tORR : TIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), > "orr $dst, $rhs", > - [(set GPR:$dst, (or GPR:$lhs, GPR:$rhs))]>; > + [(set tGPR:$dst, (or tGPR:$lhs, tGPR:$rhs))]>; > > > -def tREV : TI<(outs GPR:$dst), (ins GPR:$src), > +def tREV : TI<(outs tGPR:$dst), (ins tGPR:$src), > "rev $dst, $src", > - [(set GPR:$dst, (bswap GPR:$src))]>, > + [(set tGPR:$dst, (bswap tGPR:$src))]>, > Requires<[IsThumb, HasV6]>; > > -def tREV16 : TI<(outs GPR:$dst), (ins GPR:$src), > +def tREV16 : TI<(outs tGPR:$dst), (ins tGPR:$src), > "rev16 $dst, $src", > - [(set GPR:$dst, > - (or (and (srl GPR:$src, 8), 0xFF), > - (or (and (shl GPR:$src, 8), 0xFF00), > - (or (and (srl GPR:$src, 8), 0xFF0000), > - (and (shl GPR:$src, 8), > 0xFF000000)))))]>, > + [(set tGPR:$dst, > + (or (and (srl tGPR:$src, 8), 0xFF), > + (or (and (shl tGPR:$src, 8), 0xFF00), > + (or (and (srl tGPR:$src, 8), 0xFF0000), > + (and (shl tGPR:$src, 8), > 0xFF000000)))))]>, > Requires<[IsThumb, HasV6]>; > > -def tREVSH : TI<(outs GPR:$dst), (ins GPR:$src), > +def tREVSH : TI<(outs tGPR:$dst), (ins tGPR:$src), > "revsh $dst, $src", > - [(set GPR:$dst, > + [(set tGPR:$dst, > (sext_inreg > - (or (srl (and GPR:$src, 0xFFFF), 8), > - (shl GPR:$src, 8)), i16))]>, > + (or (srl (and tGPR:$src, 0xFFFF), 8), > + (shl tGPR:$src, 8)), i16))]>, > Requires<[IsThumb, HasV6]>; > > -def tROR : TIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), > +def tROR : TIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), > "ror $dst, $rhs", > - [(set GPR:$dst, (rotr GPR:$lhs, GPR:$rhs))]>; > + [(set tGPR:$dst, (rotr tGPR:$lhs, tGPR:$rhs))]>; > > > // Subtract with carry > -def tSBC : TIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), > +def tSBC : TIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), > "sbc $dst, $rhs", > - [(set GPR:$dst, (sube GPR:$lhs, GPR:$rhs))]>; > + [(set tGPR:$dst, (sube tGPR:$lhs, tGPR:$rhs))]>; > > -def tSUBS : TI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), > +def tSUBS : TI<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), > "sub $dst, $lhs, $rhs", > - [(set GPR:$dst, (subc GPR:$lhs, GPR:$rhs))]>; > + [(set tGPR:$dst, (subc tGPR:$lhs, tGPR:$rhs))]>; > > > // TODO: A7-96: STMIA - store multiple. > > -def tSUBi3 : TI<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), > +def tSUBi3 : TI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), > "sub $dst, $lhs, $rhs", > - [(set GPR:$dst, (add GPR:$lhs, imm0_7_neg:$rhs))]>; > + [(set tGPR:$dst, (add tGPR:$lhs, imm0_7_neg:$rhs))]>; > > -def tSUBi8 : TIt<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), > +def tSUBi8 : TIt<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), > "sub $dst, $rhs", > - [(set GPR:$dst, (add GPR:$lhs, imm8_255_neg: > $rhs))]>; > + [(set tGPR:$dst, (add tGPR:$lhs, imm8_255_neg: > $rhs))]>; > > -def tSUBrr : TI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), > +def tSUBrr : TI<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), > "sub $dst, $lhs, $rhs", > - [(set GPR:$dst, (sub GPR:$lhs, GPR:$rhs))]>; > + [(set tGPR:$dst, (sub tGPR:$lhs, tGPR:$rhs))]>; > > -def tSUBspi : TIt<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), > +def tSUBspi : TIt<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), > "sub $dst, $rhs * 4", []>; > > -def tSXTB : TI<(outs GPR:$dst), (ins GPR:$src), > +def tSXTB : TI<(outs tGPR:$dst), (ins tGPR:$src), > "sxtb $dst, $src", > - [(set GPR:$dst, (sext_inreg GPR:$src, i8))]>, > + [(set tGPR:$dst, (sext_inreg tGPR:$src, i8))]>, > Requires<[IsThumb, HasV6]>; > -def tSXTH : TI<(outs GPR:$dst), (ins GPR:$src), > +def tSXTH : TI<(outs tGPR:$dst), (ins tGPR:$src), > "sxth $dst, $src", > - [(set GPR:$dst, (sext_inreg GPR:$src, i16))]>, > + [(set tGPR:$dst, (sext_inreg tGPR:$src, i16))]>, > Requires<[IsThumb, HasV6]>; > > > -def tUXTB : TI<(outs GPR:$dst), (ins GPR:$src), > +def tUXTB : TI<(outs tGPR:$dst), (ins tGPR:$src), > "uxtb $dst, $src", > - [(set GPR:$dst, (and GPR:$src, 0xFF))]>, > + [(set tGPR:$dst, (and tGPR:$src, 0xFF))]>, > Requires<[IsThumb, HasV6]>; > -def tUXTH : TI<(outs GPR:$dst), (ins GPR:$src), > +def tUXTH : TI<(outs tGPR:$dst), (ins tGPR:$src), > "uxth $dst, $src", > - [(set GPR:$dst, (and GPR:$src, 0xFFFF))]>, > + [(set tGPR:$dst, (and tGPR:$src, 0xFFFF))]>, > Requires<[IsThumb, HasV6]>; > > > @@ -483,20 +491,20 @@ > // Expanded by the scheduler into a branch sequence. > let usesCustomDAGSchedInserter = 1 in // Expanded by the scheduler. > def tMOVCCr : > - PseudoInst<(outs GPR:$dst), (ins GPR:$false, GPR:$true, pred:$cc), > + PseudoInst<(outs tGPR:$dst), (ins tGPR:$false, tGPR:$true, pred: > $cc), > "@ tMOVCCr $cc", > - [/*(set GPR:$dst, (ARMcmov GPR:$false, GPR:$true, imm: > $cc))*/]>; > + [/*(set tGPR:$dst, (ARMcmov tGPR:$false, tGPR:$true, > imm:$cc))*/]>; > > // tLEApcrel - Load a pc-relative address into a register without > offending the > // assembler. > -def tLEApcrel : TIx2<(outs GPR:$dst), (ins i32imm:$label), > +def tLEApcrel : TIx2<(outs tGPR:$dst), (ins i32imm:$label), > !strconcat(!strconcat(".set PCRELV${:uid}, > ($label-(", > "${:private}PCRELL${:uid} > +4))\n"), > !strconcat("\tmov $dst, #PCRELV${:uid} > \n", > "${:private}PCRELL${:uid}:\n\tadd > $dst, pc")), > []>; > > -def tLEApcrelJT : TIx2<(outs GPR:$dst), (ins i32imm:$label, i32imm: > $id), > +def tLEApcrelJT : TIx2<(outs tGPR:$dst), (ins i32imm:$label, i32imm: > $id), > !strconcat(!strconcat(".set PCRELV${:uid}, (${label}_$ > {id:no_hash}-(", > "${:private}PCRELL${:uid} > +4))\n"), > !strconcat("\tmov $dst, #PCRELV${:uid}\n", > @@ -532,7 +540,7 @@ > def : ThumbV5Pat<(ARMcall texternalsym:$func), (tBLXi texternalsym: > $func)>; > > // Indirect calls to ARM routines > -def : ThumbV5Pat<(ARMcall GPR:$dst), (tBLXr GPR:$dst)>; > +def : ThumbV5Pat<(ARMcall tGPR:$dst), (tBLXr tGPR:$dst)>; > > // zextload i1 -> zextload i8 > def : ThumbPat<(zextloadi1 t_addrmode_s1:$addr), > > Modified: llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp?rev=68545&r1=68544&r2=68545&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp (original) > +++ llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp Tue Apr 7 > 15:34:09 2009 > @@ -211,6 +211,22 @@ > } > } > > +const TargetRegisterClass* > +ARMRegisterInfo::getPhysicalRegisterRegClass(unsigned Reg, MVT VT) > const { > + if (STI.isThumb()) { > + if (isLowRegister(Reg)) > + return ARM::tGPRRegisterClass; > + switch (Reg) { > + default: > + break; > + case ARM::R8: case ARM::R9: case ARM::R10: case ARM::R11: > + case ARM::R12: case ARM::SP: case ARM::LR: case ARM::PC: > + return ARM::GPRRegisterClass; > + } > + } > + return TargetRegisterInfo::getPhysicalRegisterRegClass(Reg, VT); > +} > + > const unsigned* > ARMRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { > static const unsigned CalleeSavedRegs[] = { > @@ -244,7 +260,16 @@ > &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, > &ARM::DPRRegClass, > 0 > }; > - return CalleeSavedRegClasses; > + static const TargetRegisterClass * const > ThumbCalleeSavedRegClasses[] = { > + &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::GPRRegClass, > + &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::tGPRRegClass, > + &ARM::tGPRRegClass,&ARM::tGPRRegClass,&ARM::tGPRRegClass, > + > + &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, > &ARM::DPRRegClass, > + &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, > &ARM::DPRRegClass, > + 0 > + }; > + return STI.isThumb() ? ThumbCalleeSavedRegClasses : > CalleeSavedRegClasses; > } > > BitVector ARMRegisterInfo::getReservedRegs(const MachineFunction > &MF) const { > @@ -400,7 +425,7 @@ > if (DestReg == ARM::SP) { > assert(BaseReg == ARM::SP && "Unexpected!"); > LdReg = ARM::R3; > - BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), ARM::R12) > + BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVlor2hir), ARM::R12) > .addReg(ARM::R3, false, false, true); > } > > @@ -423,7 +448,7 @@ > else > MIB.addReg(LdReg).addReg(BaseReg, false, false, true); > if (DestReg == ARM::SP) > - BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), ARM::R3) > + BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVhir2lor), ARM::R3) > .addReg(ARM::R12, false, false, true); > } > > @@ -616,6 +641,7 @@ > unsigned findScratchRegister(RegScavenger *RS, const > TargetRegisterClass *RC, > ARMFunctionInfo *AFI) { > unsigned Reg = RS ? RS->FindUnusedReg(RC, true) : (unsigned) > ARM::R12; > + assert (!AFI->isThumbFunction()); > if (Reg == 0) > // Try a already spilled CS register. > Reg = RS->FindUnusedReg(RC, AFI->getSpilledCSRegisters()); > @@ -717,7 +743,7 @@ > > if (Offset == 0) { > // Turn it into a move. > - MI.setDesc(TII.get(ARM::tMOVr)); > + MI.setDesc(TII.get(ARM::tMOVhir2lor)); > MI.getOperand(i).ChangeToRegister(FrameReg, false); > MI.RemoveOperand(i+1); > return; > @@ -891,12 +917,12 @@ > unsigned TmpReg = ARM::R3; > bool UseRR = false; > if (ValReg == ARM::R3) { > - BuildMI(MBB, II, dl, TII.get(ARM::tMOVr), ARM::R12) > + BuildMI(MBB, II, dl, TII.get(ARM::tMOVlor2hir), ARM::R12) > .addReg(ARM::R2, false, false, true); > TmpReg = ARM::R2; > } > if (TmpReg == ARM::R3 && AFI->isR3LiveIn()) > - BuildMI(MBB, II, dl, TII.get(ARM::tMOVr), ARM::R12) > + BuildMI(MBB, II, dl, TII.get(ARM::tMOVlor2hir), ARM::R12) > .addReg(ARM::R3, false, false, true); > if (Opcode == ARM::tSpill) { > if (FrameReg == ARM::SP) > @@ -919,10 +945,10 @@ > > MachineBasicBlock::iterator NII = next(II); > if (ValReg == ARM::R3) > - BuildMI(MBB, NII, dl, TII.get(ARM::tMOVr), ARM::R2) > + BuildMI(MBB, NII, dl, TII.get(ARM::tMOVhir2lor), ARM::R2) > .addReg(ARM::R12, false, false, true); > if (TmpReg == ARM::R3 && AFI->isR3LiveIn()) > - BuildMI(MBB, NII, dl, TII.get(ARM::tMOVr), ARM::R3) > + BuildMI(MBB, NII, dl, TII.get(ARM::tMOVhir2lor), ARM::R3) > .addReg(ARM::R12, false, false, true); > } else > assert(false && "Unexpected opcode!"); > @@ -1401,7 +1427,8 @@ > emitThumbRegPlusImmediate(MBB, MBBI, ARM::SP, FramePtr, - > NumBytes, > TII, *this, dl); > else > - BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), > ARM::SP).addReg(FramePtr); > + BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVlor2hir), ARM::SP) > + .addReg(FramePtr); > } else { > if (MBBI->getOpcode() == ARM::tBX_RET && > &MBB.front() != MBBI && > > Modified: llvm/trunk/lib/Target/ARM/ARMRegisterInfo.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMRegisterInfo.h?rev=68545&r1=68544&r2=68545&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/ARM/ARMRegisterInfo.h (original) > +++ llvm/trunk/lib/Target/ARM/ARMRegisterInfo.h Tue Apr 7 15:34:09 > 2009 > @@ -54,6 +54,8 @@ > const TargetRegisterClass *getPointerRegClass() const; > > /// Code Generation virtual methods... > + const TargetRegisterClass * > + getPhysicalRegisterRegClass(unsigned Reg, MVT VT = MVT::Other) > const; > const unsigned *getCalleeSavedRegs(const MachineFunction *MF = 0) > const; > > const TargetRegisterClass* const* > > Modified: llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td?rev=68545&r1=68544&r2=68545&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td (original) > +++ llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td Tue Apr 7 15:34:09 > 2009 > @@ -130,17 +130,10 @@ > ARM::R8, ARM::R10,ARM::R11, > ARM::R7 }; > > - // FP is R7, only low registers available. > - static const unsigned THUMB_GPR_AO[] = { > - ARM::R2, ARM::R1, ARM::R0, > - ARM::R4, ARM::R5, ARM::R6, ARM::R7 }; > - > GPRClass::iterator > GPRClass::allocation_order_begin(const MachineFunction &MF) > const { > const TargetMachine &TM = MF.getTarget(); > const ARMSubtarget &Subtarget = TM.getSubtarget(); > - if (Subtarget.isThumb()) > - return THUMB_GPR_AO; > if (Subtarget.useThumbBacktraces()) { > if (Subtarget.isR9Reserved()) > return ARM_GPR_AO_4; > @@ -160,9 +153,8 @@ > const TargetRegisterInfo *RI = TM.getRegisterInfo(); > const ARMSubtarget &Subtarget = TM.getSubtarget(); > GPRClass::iterator I; > - if (Subtarget.isThumb()) > - I = THUMB_GPR_AO + (sizeof(THUMB_GPR_AO)/sizeof(unsigned)); > - else if (Subtarget.useThumbBacktraces()) { > + > + if (Subtarget.useThumbBacktraces()) { > if (Subtarget.isR9Reserved()) { > I = ARM_GPR_AO_4 + (sizeof(ARM_GPR_AO_4)/sizeof(unsigned)); > } else { > @@ -182,6 +174,40 @@ > }]; > } > > +// Thumb registers are R0-R7 normally. Some instructions can still > use > +// the general GPR register class above (MOV, e.g.) > +def tGPR : RegisterClass<"ARM", [i32], 32, [R0, R1, R2, R3, R4, R5, > R6, R7]> { > + let MethodProtos = [{ > + iterator allocation_order_begin(const MachineFunction &MF) const; > + iterator allocation_order_end(const MachineFunction &MF) const; > + }]; > + // FIXME: We are reserving r3 in Thumb mode in case the PEI needs > to use it > + // to generate large stack offset. Make it available once we have > register > + // scavenging. > + let MethodBodies = [{ > + static const unsigned THUMB_tGPR_AO[] = { > + ARM::R2, ARM::R1, ARM::R0, > + ARM::R4, ARM::R5, ARM::R6, ARM::R7 }; > + > + // FP is R7, only low registers available. > + tGPRClass::iterator > + tGPRClass::allocation_order_begin(const MachineFunction &MF) > const { > + return THUMB_tGPR_AO; > + } > + > + tGPRClass::iterator > + tGPRClass::allocation_order_end(const MachineFunction &MF) > const { > + const TargetMachine &TM = MF.getTarget(); > + const TargetRegisterInfo *RI = TM.getRegisterInfo(); > + const ARMSubtarget &Subtarget = TM.getSubtarget > (); > + tGPRClass::iterator I = > + THUMB_tGPR_AO + (sizeof(THUMB_tGPR_AO)/sizeof(unsigned)); > + // Mac OS X requires FP not to be clobbered for backtracing > purpose. > + return (Subtarget.isTargetDarwin() || RI->hasFP(MF)) ? I-1 : I; > + } > + }]; > +} > + > def SPR : RegisterClass<"ARM", [f32], 32, [S0, S1, S2, S3, S4, S5, > S6, S7, S8, > S9, S10, S11, S12, S13, S14, S15, S16, S17, S18, S19, S20, S21, S22, > S23, S24, S25, S26, S27, S28, S29, S30, S31]>; > > > _______________________________________________ > 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 Mon Apr 13 21:49:52 2009 From: sanjiv.gupta at microchip.com (Sanjiv Gupta) Date: Tue, 14 Apr 2009 02:49:52 -0000 Subject: [llvm-commits] [llvm] r69022 - in /llvm/trunk/lib/Target/PIC16: PIC16AsmPrinter.cpp PIC16ISelLowering.cpp PIC16ISelLowering.h PIC16InstrInfo.td Message-ID: <200904140249.n3E2nqSp026390@zion.cs.uiuc.edu> Author: sgupta Date: Mon Apr 13 21:49:52 2009 New Revision: 69022 URL: http://llvm.org/viewvc/llvm-project?rev=69022&view=rev Log: Handle aggregate type arguments to direct and indirect calls. Modified: llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.cpp llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.h llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.td Modified: llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.cpp?rev=69022&r1=69021&r2=69022&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.cpp Mon Apr 13 21:49:52 2009 @@ -227,6 +227,11 @@ std::string Name = Mang->getValueName(I); if (Name.compare("abort") == 0) continue; + + // If it is llvm intrinsic call then don't emit + if (Name.find("llvm.") != std::string::npos) + continue; + if (I->isDeclaration()) { O << "\textern " <GetTmpSize(); + if (TempSize > 0 ) + O << CurrentFnName << ".tmp RES " << TempSize <<"\n"; + // Emit the function variables. // In PIC16 all the function arguments and local variables are global. @@ -423,7 +433,4 @@ O << VarName << " RES " << Size << "\n"; } - int TempSize = PTLI->GetTmpSize(); - if (TempSize > 0 ) - O << CurrentFnName << ".tmp RES " << TempSize <<"\n"; } Modified: llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp?rev=69022&r1=69021&r2=69022&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp Mon Apr 13 21:49:52 2009 @@ -326,10 +326,14 @@ DebugLoc dl = FR->getDebugLoc(); int Index = FR->getIndex(); - SDValue FI[2]; - FI[0] = DAG.getTargetFrameIndex(Index, MVT::i8); - FI[1] = DAG.getTargetFrameIndex(Index + 1, MVT::i8); - return DAG.getNode(ISD::BUILD_PAIR, dl, N->getValueType(0), FI[0], FI[1]); + // Expand FrameIndex like GlobalAddress and ExternalSymbol + // Also use Offset field for lo and hi parts. The default + // offset is zero. + SDValue Offset = DAG.getConstant(0, MVT::i8); + SDValue FI = DAG.getTargetFrameIndex(Index, MVT::i8); + SDValue Lo = DAG.getNode(PIC16ISD::Lo, dl, MVT::i8, FI, Offset); + SDValue Hi = DAG.getNode(PIC16ISD::Hi, dl, MVT::i8, FI, Offset); + return DAG.getNode(ISD::BUILD_PAIR, dl, N->getValueType(0), Lo, Hi); } @@ -433,9 +437,9 @@ DebugLoc dl = ES->getDebugLoc(); SDValue TES = DAG.getTargetExternalSymbol(ES->getSymbol(), MVT::i8); - - SDValue Lo = DAG.getNode(PIC16ISD::Lo, dl, MVT::i8, TES); - SDValue Hi = DAG.getNode(PIC16ISD::Hi, dl, MVT::i8, TES); + SDValue Offset = DAG.getConstant(0, MVT::i8); + SDValue Lo = DAG.getNode(PIC16ISD::Lo, dl, MVT::i8, TES, Offset); + SDValue Hi = DAG.getNode(PIC16ISD::Hi, dl, MVT::i8, TES, Offset); return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i16, Lo, Hi); } @@ -449,8 +453,9 @@ SDValue TGA = DAG.getTargetGlobalAddress(G->getGlobal(), MVT::i8, G->getOffset()); - SDValue Lo = DAG.getNode(PIC16ISD::Lo, dl, MVT::i8, TGA); - SDValue Hi = DAG.getNode(PIC16ISD::Hi, dl, MVT::i8, TGA); + SDValue Offset = DAG.getConstant(0, MVT::i8); + SDValue Lo = DAG.getNode(PIC16ISD::Lo, dl, MVT::i8, TGA, Offset); + SDValue Hi = DAG.getNode(PIC16ISD::Hi, dl, MVT::i8, TGA, Offset); return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i16, Lo, Hi); } @@ -587,14 +592,16 @@ } } - if (Ptr.getOpcode() == ISD::BUILD_PAIR && - Ptr.getOperand(0).getOpcode() == ISD::TargetFrameIndex) { - - int FrameOffset; - LegalizeFrameIndex(Ptr.getOperand(0), DAG, Lo, FrameOffset); - Hi = DAG.getConstant(1, MVT::i8); - Offset += FrameOffset; - return; + // Expansion of FrameIndex has Lo/Hi parts + if (isDirectAddress(Ptr)) { + SDValue TFI = Ptr.getOperand(0).getOperand(0); + if (TFI.getOpcode() == ISD::TargetFrameIndex) { + int FrameOffset; + LegalizeFrameIndex(TFI, DAG, Lo, FrameOffset); + Hi = DAG.getConstant(1, MVT::i8); + Offset += FrameOffset; + return; + } } if (isDirectAddress(Ptr) && !isRomAddress(Ptr)) { @@ -884,6 +891,12 @@ for (unsigned i = 0, ArgOffset = RetVals; i < NumOps; i++) { // Get the arguments Arg = TheCall->getArg(i); + // If argument is FrameIndex then map it with temporary + if (Arg.getOpcode() == PIC16ISD::Lo || Arg.getOpcode() == PIC16ISD::Hi) { + if (Arg.getOperand(0).getOpcode() == ISD::TargetFrameIndex) { + Arg = LegalizeFrameArgument(Arg, dl, DAG); + } + } Ops.clear(); Ops.push_back(Chain); Ops.push_back(Arg); @@ -900,9 +913,39 @@ } return Chain; } - + +SDValue PIC16TargetLowering:: +LegalizeFrameArgument(SDValue Arg, DebugLoc dl, SelectionDAG &DAG) { + MachineFunction &MF = DAG.getMachineFunction(); + const Function *Func = MF.getFunction(); + MachineFrameInfo *MFI = MF.getFrameInfo(); + const std::string Name = Func->getName(); + + // Caller creates the stack storage to pass the aggregate type + // as argument. So it should be relative to tmp variable. + SDValue FI = Arg.getOperand(0); + char *tmpName = new char [strlen(Name.c_str()) + 8]; + sprintf(tmpName, "%s.tmp", Name.c_str()); + SDValue ES = DAG.getTargetExternalSymbol(tmpName, MVT::i8); + FrameIndexSDNode *FR = dyn_cast(FI); + + unsigned FIndex = FR->getIndex(); + // Reserve space in tmp variable for the aggregate type + int FrameOffset = GetTmpOffsetForFI(FIndex, MFI->getObjectSize(FIndex)); + + if (Arg.getOpcode() == PIC16ISD::Lo) { + // Lo part of frame index + SDValue FrameConst = DAG.getConstant(FrameOffset, MVT::i8); + return DAG.getNode(PIC16ISD::Lo, dl, MVT::i8, ES, FrameConst); + } else { + // Hi part of frame index + SDValue FrameConst = DAG.getConstant(FrameOffset + 1, MVT::i8); + return DAG.getNode(PIC16ISD::Hi, dl, MVT::i8, ES, FrameConst); + } +} + SDValue PIC16TargetLowering:: -LowerDirectCallArguments(SDValue Op, SDValue Chain, SDValue FrameAddress, +LowerDirectCallArguments(SDValue Op, SDValue Chain, SDValue ArgLabel, SDValue InFlag, SelectionDAG &DAG) { CallSDNode *TheCall = dyn_cast(Op); unsigned NumOps = TheCall->getNumArgs(); @@ -924,7 +967,7 @@ SDValue PtrLo, PtrHi; unsigned AddressOffset; int StoreOffset = 0; - LegalizeAddress(FrameAddress, DAG, PtrLo, PtrHi, AddressOffset, dl); + LegalizeAddress(ArgLabel, DAG, PtrLo, PtrHi, AddressOffset, dl); SDValue StoreRet; std::vector Ops; @@ -932,7 +975,12 @@ for (unsigned i=ArgCount, Offset = 0; igetArg(i); - + // If argument is FrameIndex then map it with temporary + if (Arg.getOpcode() == PIC16ISD::Lo || Arg.getOpcode() == PIC16ISD::Hi) { + if (Arg.getOperand(0).getOpcode() == ISD::TargetFrameIndex) { + Arg = LegalizeFrameArgument(Arg, dl, DAG); + } + } StoreOffset = (Offset + AddressOffset); // Store the argument on frame @@ -991,7 +1039,7 @@ } SDValue PIC16TargetLowering:: -LowerDirectCallReturn(SDValue Op, SDValue Chain, SDValue FrameAddress, +LowerDirectCallReturn(SDValue Op, SDValue Chain, SDValue RetLabel, SDValue InFlag, SelectionDAG &DAG) { CallSDNode *TheCall = dyn_cast(Op); DebugLoc dl = TheCall->getDebugLoc(); @@ -1010,7 +1058,7 @@ // Legalize the address before use SDValue LdLo, LdHi; unsigned LdOffset; - LegalizeAddress(FrameAddress, DAG, LdLo, LdHi, LdOffset, dl); + LegalizeAddress(RetLabel, DAG, LdLo, LdHi, LdOffset, dl); SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Other, MVT::Flag); SDValue LoadRet; @@ -1698,4 +1746,3 @@ Cmp.getValue(1)); } - Modified: llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.h?rev=69022&r1=69021&r2=69022&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.h (original) +++ llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.h Mon Apr 13 21:49:52 2009 @@ -168,6 +168,8 @@ void LegalizeFrameIndex(SDValue Op, SelectionDAG &DAG, SDValue &ES, int &Offset); + SDValue LegalizeFrameArgument(SDValue Arg, DebugLoc dl, SelectionDAG &DAG); + // CALL node should have all legal operands only. Legalize all non-legal // operands of CALL node and then return the new call will all operands // legal. Modified: llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.td?rev=69022&r1=69021&r2=69022&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.td (original) +++ llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.td Mon Apr 13 21:49:52 2009 @@ -72,10 +72,10 @@ [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; // Low 8-bits of GlobalAddress. -def PIC16Lo : SDNode<"PIC16ISD::Lo", SDTI8UnaryOp>; +def PIC16Lo : SDNode<"PIC16ISD::Lo", SDTI8BinOp>; // High 8-bits of GlobalAddress. -def PIC16Hi : SDNode<"PIC16ISD::Hi", SDTI8UnaryOp>; +def PIC16Hi : SDNode<"PIC16ISD::Hi", SDTI8BinOp>; // The MTHI and MTLO nodes are used only to match them in the incoming // DAG for replacement by corresponding set_fsrhi, set_fsrlo insntructions. @@ -187,14 +187,24 @@ [(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))]>; +def movlw_lo_1 : BitFormat<12, (outs GPR:$dst), (ins i8imm:$src, i8imm:$src2), + "movlw LOW(${src}) + ${src2}", + [(set GPR:$dst, (PIC16Lo tglobaladdr:$src, imm:$src2 ))]>; + +// Move a Lo(TES) to W. +def movlw_lo_2 : BitFormat<12, (outs GPR:$dst), (ins i8imm:$src, i8imm:$src2), + "movlw LOW(${src}) + ${src2}", + [(set GPR:$dst, (PIC16Lo texternalsym:$src, imm:$src2 ))]>; // 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))]>; +def movlw_hi_1 : BitFormat<12, (outs GPR:$dst), (ins i8imm:$src, i8imm:$src2), + "movlw HIGH(${src}) + ${src2}", + [(set GPR:$dst, (PIC16Hi tglobaladdr:$src, imm:$src2))]>; + +// Move a Hi(TES) to W. +def movlw_hi_2 : BitFormat<12, (outs GPR:$dst), (ins i8imm:$src, i8imm:$src2), + "movlw HIGH(${src}) + ${src2}", + [(set GPR:$dst, (PIC16Hi texternalsym:$src, imm:$src2))]>; } //------------------- From evan.cheng at apple.com Tue Apr 14 11:57:44 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 14 Apr 2009 16:57:44 -0000 Subject: [llvm-commits] [llvm] r69049 - in /llvm/trunk: lib/Target/X86/X86RegisterInfo.td test/CodeGen/X86/2009-04-14-IllegalRegs.ll Message-ID: <200904141657.n3EGvimA004475@zion.cs.uiuc.edu> Author: evancheng Date: Tue Apr 14 11:57:43 2009 New Revision: 69049 URL: http://llvm.org/viewvc/llvm-project?rev=69049&view=rev Log: Some of GR8_NOREX registers are only available in 64-bit mode. Added: llvm/trunk/test/CodeGen/X86/2009-04-14-IllegalRegs.ll 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=69049&r1=69048&r2=69049&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86RegisterInfo.td (original) +++ llvm/trunk/lib/Target/X86/X86RegisterInfo.td Tue Apr 14 11:57:43 2009 @@ -484,6 +484,54 @@ // of registers which do not by themselves require a REX prefix. def GR8_NOREX : RegisterClass<"X86", [i8], 8, [AL, CL, DL, SIL, DIL, BL, BPL, SPL]> { + let MethodProtos = [{ + iterator allocation_order_begin(const MachineFunction &MF) const; + iterator allocation_order_end(const MachineFunction &MF) const; + }]; + let MethodBodies = [{ + // Does the function dedicate RBP / EBP to being a frame ptr? + // If so, don't allocate SPL or BPL. + static const unsigned X86_GR8_NOREX_AO_64_fp[] = { + X86::AL, X86::CL, X86::DL, X86::SIL, X86::DIL, X86::BL + }; + // If not, just don't allocate SPL. + static const unsigned X86_GR8_NOREX_AO_64[] = { + X86::AL, X86::CL, X86::DL, X86::SIL, X86::DIL, X86::BL, X86::BPL + }; + // In 32-mode, none of the 8-bit registers aliases EBP or ESP. + static const unsigned X86_GR8_NOREX_AO_32[] = { + X86::AL, X86::CL, X86::DL, X86::BL + }; + + GR8_NOREXClass::iterator + GR8_NOREXClass::allocation_order_begin(const MachineFunction &MF) const { + const TargetMachine &TM = MF.getTarget(); + const TargetRegisterInfo *RI = TM.getRegisterInfo(); + const X86Subtarget &Subtarget = TM.getSubtarget(); + if (!Subtarget.is64Bit()) + return X86_GR8_NOREX_AO_32; + else if (RI->hasFP(MF)) + return X86_GR8_NOREX_AO_64_fp; + else + return X86_GR8_NOREX_AO_64; + } + + GR8_NOREXClass::iterator + GR8_NOREXClass::allocation_order_end(const MachineFunction &MF) const { + const TargetMachine &TM = MF.getTarget(); + const TargetRegisterInfo *RI = TM.getRegisterInfo(); + const X86Subtarget &Subtarget = TM.getSubtarget(); + if (!Subtarget.is64Bit()) + return X86_GR8_NOREX_AO_32 + + (sizeof(X86_GR8_NOREX_AO_32) / sizeof(unsigned)); + else if (RI->hasFP(MF)) + return X86_GR8_NOREX_AO_64_fp + + (sizeof(X86_GR8_NOREX_AO_64_fp) / sizeof(unsigned)); + else + return X86_GR8_NOREX_AO_64 + + (sizeof(X86_GR8_NOREX_AO_64) / sizeof(unsigned)); + } + }]; } def GR16_NOREX : RegisterClass<"X86", [i16], 16, [AX, CX, DX, SI, DI, BX, BP, SP]> { Added: llvm/trunk/test/CodeGen/X86/2009-04-14-IllegalRegs.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2009-04-14-IllegalRegs.ll?rev=69049&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/2009-04-14-IllegalRegs.ll (added) +++ llvm/trunk/test/CodeGen/X86/2009-04-14-IllegalRegs.ll Tue Apr 14 11:57:43 2009 @@ -0,0 +1,35 @@ +; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin -fast -regalloc=local | not grep sil +; rdar://6787136 + + %struct.X = type { i8, [32 x i8] } + at llvm.used = appending global [1 x i8*] [i8* bitcast (i32 ()* @z to i8*)], section "llvm.metadata" ; <[1 x i8*]*> [#uses=0] + +define i32 @z() nounwind ssp { +entry: + %retval = alloca i32 ; [#uses=2] + %xxx = alloca %struct.X ; <%struct.X*> [#uses=6] + %0 = alloca i32 ; [#uses=2] + %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] + %1 = getelementptr %struct.X* %xxx, i32 0, i32 1 ; <[32 x i8]*> [#uses=1] + %2 = getelementptr [32 x i8]* %1, i32 0, i32 31 ; [#uses=1] + store i8 48, i8* %2, align 1 + %3 = getelementptr %struct.X* %xxx, i32 0, i32 1 ; <[32 x i8]*> [#uses=1] + %4 = getelementptr [32 x i8]* %3, i32 0, i32 31 ; [#uses=1] + %5 = load i8* %4, align 1 ; [#uses=1] + %6 = getelementptr %struct.X* %xxx, i32 0, i32 1 ; <[32 x i8]*> [#uses=1] + %7 = getelementptr [32 x i8]* %6, i32 0, i32 0 ; [#uses=1] + store i8 %5, i8* %7, align 1 + %8 = getelementptr %struct.X* %xxx, i32 0, i32 0 ; [#uses=1] + store i8 15, i8* %8, align 1 + %9 = call i32 (...)* bitcast (i32 (%struct.X*, %struct.X*)* @f to i32 (...)*)(%struct.X* byval align 4 %xxx, %struct.X* byval align 4 %xxx) nounwind ; [#uses=1] + store i32 %9, i32* %0, align 4 + %10 = load i32* %0, align 4 ; [#uses=1] + store i32 %10, i32* %retval, align 4 + br label %return + +return: ; preds = %entry + %retval1 = load i32* %retval ; [#uses=1] + ret i32 %retval1 +} + +declare i32 @f(%struct.X* byval align 4, %struct.X* byval align 4) nounwind ssp From gohman at apple.com Tue Apr 14 12:11:02 2009 From: gohman at apple.com (Dan Gohman) Date: Tue, 14 Apr 2009 10:11:02 -0700 Subject: [llvm-commits] [llvm-gcc-4.2] r68848 - /llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp In-Reply-To: <81F7E9A5-859F-4384-880D-5457892664C8@apple.com> References: <200904110017.n3B0HseT009219@zion.cs.uiuc.edu> <6A75B539-DA9D-44E9-BC3F-E7808C47B9F9@apple.com> <81F7E9A5-859F-4384-880D-5457892664C8@apple.com> Message-ID: On Apr 13, 2009, at 1:05 PM, Devang Patel wrote: > > On Apr 13, 2009, at 12:59 PM, Dan Gohman wrote: > >> >> On Apr 10, 2009, at 5:17 PM, Devang Patel wrote: >> >>> Author: dpatel >>> Date: Fri Apr 10 19:17:54 2009 >>> New Revision: 68848 >>> >>> URL: http://llvm.org/viewvc/llvm-project?rev=68848&view=rev >>> Log: >>> If linkage name is not available then use function display name as >>> linkage name. >> >> Hi Devang, >> >> What does this fix? Why is a bogus linkage name better than no >> linkage name? > > > In C, linkage name is same as name. And in pretty much everything else, it can be different. > > This info is used during FastISel to decide whether we are at the > beginning of inlined subroutine or not. > > std::string SPName; > Subprogram.getLinkageName(SPName); > if (!SPName.empty() > && strcmp(SPName.c_str(), MF.getFunction()- >> getNameStart())) { Could this use Subprogram.getGV() == MF.getFunction() instead? Dan From dpatel at apple.com Tue Apr 14 12:27:14 2009 From: dpatel at apple.com (Devang Patel) Date: Tue, 14 Apr 2009 10:27:14 -0700 Subject: [llvm-commits] [llvm-gcc-4.2] r68848 - /llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp In-Reply-To: References: <200904110017.n3B0HseT009219@zion.cs.uiuc.edu> <6A75B539-DA9D-44E9-BC3F-E7808C47B9F9@apple.com> <81F7E9A5-859F-4384-880D-5457892664C8@apple.com> Message-ID: <95E5C588-819F-4F9B-869D-739ED00D2083@apple.com> On Apr 14, 2009, at 10:11 AM, Dan Gohman wrote: > On Apr 13, 2009, at 1:05 PM, Devang Patel wrote: > >> >> On Apr 13, 2009, at 12:59 PM, Dan Gohman wrote: >> >>> >>> On Apr 10, 2009, at 5:17 PM, Devang Patel wrote: >>> >>>> Author: dpatel >>>> Date: Fri Apr 10 19:17:54 2009 >>>> New Revision: 68848 >>>> >>>> URL: http://llvm.org/viewvc/llvm-project?rev=68848&view=rev >>>> Log: >>>> If linkage name is not available then use function display name as >>>> linkage name. >>> >>> Hi Devang, >>> >>> What does this fix? Why is a bogus linkage name better than no >>> linkage name? >> >> >> In C, linkage name is same as name. > > And in pretty much everything else, it can be different. And if it is different then gdb wants to know it. If linkage name is different then the FE should have found the linkage name. >> This info is used during FastISel to decide whether we are at the >> beginning of inlined subroutine or not. >> >> std::string SPName; >> Subprogram.getLinkageName(SPName); >> if (!SPName.empty() >> && strcmp(SPName.c_str(), MF.getFunction()- >>> getNameStart())) { > > Could this use > > Subprogram.getGV() == MF.getFunction() > > instead? It won't work. The Subprogram does not have actual Fn. It only carries information for function named "blah". - Devang -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20090414/a1bc13ec/attachment.html From dpatel at apple.com Tue Apr 14 13:59:21 2009 From: dpatel at apple.com (Devang Patel) Date: Tue, 14 Apr 2009 18:59:21 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r69067 - /llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp Message-ID: <200904141859.n3EIxLMo009247@zion.cs.uiuc.edu> Author: dpatel Date: Tue Apr 14 13:59:21 2009 New Revision: 69067 URL: http://llvm.org/viewvc/llvm-project?rev=69067&view=rev Log: Revert 68848. Modified: llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp?rev=69067&r1=69066&r2=69067&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp Tue Apr 14 13:59:21 2009 @@ -190,7 +190,7 @@ return IDENTIFIER_POINTER(DECL_ASSEMBLER_NAME(Node)); } } - return NULL; + return ""; } DebugInfo::DebugInfo(Module *m) @@ -211,11 +211,12 @@ // Gather location information. expanded_location Loc = GetNodeLocation(FnDecl, false); const char *LinkageName = getLinkageName(FnDecl); - const char *FnName = lang_hooks.dwarf_name(FnDecl, 0); + DISubprogram SP = DebugFactory.CreateSubprogram(findRegion(FnDecl), - FnName, FnName, - LinkageName ? LinkageName : FnName, + lang_hooks.dwarf_name(FnDecl, 0), + lang_hooks.dwarf_name(FnDecl, 0), + LinkageName, getOrCreateCompileUnit(Loc.file), CurLineNo, getOrCreateType(TREE_TYPE(FnDecl)), Fn->hasInternalLinkage(), @@ -344,11 +345,11 @@ if (IDENTIFIER_POINTER(DECL_NAME(decl))) DispName = IDENTIFIER_POINTER(DECL_NAME(decl)); } - const char *LinkageName = getLinkageName(decl); + DebugFactory.CreateGlobalVariable(getOrCreateCompileUnit(Loc.file), GV->getNameStr(), DispName, - LinkageName ? LinkageName : DispName, + getLinkageName(decl), getOrCreateCompileUnit(Loc.file), Loc.line, TyD, GV->hasInternalLinkage(), true/*definition*/, GV); @@ -667,7 +668,7 @@ DIType SPTy = getOrCreateType(TREE_TYPE(Member)); DISubprogram SP = DebugFactory.CreateSubprogram(findRegion(Member), MemberName, MemberName, - LinkageName ? LinkageName : MemberName, + LinkageName, getOrCreateCompileUnit(MemLoc.file), MemLoc.line, SPTy, false, false); EltTys.push_back(SP); From dpatel at apple.com Tue Apr 14 14:02:16 2009 From: dpatel at apple.com (Devang Patel) Date: Tue, 14 Apr 2009 12:02:16 -0700 Subject: [llvm-commits] [llvm-gcc-4.2] r68848 - /llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp In-Reply-To: <95E5C588-819F-4F9B-869D-739ED00D2083@apple.com> References: <200904110017.n3B0HseT009219@zion.cs.uiuc.edu> <6A75B539-DA9D-44E9-BC3F-E7808C47B9F9@apple.com> <81F7E9A5-859F-4384-880D-5457892664C8@apple.com> <95E5C588-819F-4F9B-869D-739ED00D2083@apple.com> Message-ID: On Apr 14, 2009, at 10:27 AM, Devang Patel wrote: >>> This info is used during FastISel to decide whether we are at the >>> beginning of inlined subroutine or not. >>> >>> std::string SPName; >>> Subprogram.getLinkageName(SPName); >>> if (!SPName.empty() >>> && strcmp(SPName.c_str(), MF.getFunction()- >>>> getNameStart())) { >> >> Could this use >> >> Subprogram.getGV() == MF.getFunction() >> >> instead? > > It won't work. The Subprogram does not have actual Fn. It only > carries information for function named "blah". OK, found another way to handle this. I reverted 68848. - Devang From daniel at zuster.org Tue Apr 14 14:59:54 2009 From: daniel at zuster.org (Daniel Dunbar) Date: Tue, 14 Apr 2009 19:59:54 -0000 Subject: [llvm-commits] [test-suite] r69068 - /test-suite/trunk/SingleSource/UnitTests/ObjC/parameter-passing.m Message-ID: <200904141959.n3EJxscn011594@zion.cs.uiuc.edu> Author: ddunbar Date: Tue Apr 14 14:59:52 2009 New Revision: 69068 URL: http://llvm.org/viewvc/llvm-project?rev=69068&view=rev Log: Add test case for various parts of Objective-C parameter passing. Added: test-suite/trunk/SingleSource/UnitTests/ObjC/parameter-passing.m Added: test-suite/trunk/SingleSource/UnitTests/ObjC/parameter-passing.m URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/SingleSource/UnitTests/ObjC/parameter-passing.m?rev=69068&view=auto ============================================================================== --- test-suite/trunk/SingleSource/UnitTests/ObjC/parameter-passing.m (added) +++ test-suite/trunk/SingleSource/UnitTests/ObjC/parameter-passing.m Tue Apr 14 14:59:52 2009 @@ -0,0 +1,263 @@ +#include +#include + +#define D(msg) printf("parameter-passing.m:%d -- %s\n\n", __LINE__, msg) + +typedef struct { + int first, second; +} IntPair; + +typedef struct { + float first, second; +} FloatPair; + + at interface A : NSObject { + int _i_ivar; + long long _ll_ivar; + float _f_ivar; + double _d_ivar; +#ifdef TEST_COMPLEX + _Complex int _i_complex_ivar; + _Complex float _f_complex_ivar; +#endif + IntPair _i_pair_ivar; + FloatPair _f_pair_ivar; +} + +// Synthesized property access + + at property (assign) int i_ivar; + at property (assign) long long ll_ivar; + at property (assign) float f_ivar; + at property (assign) double d_ivar; +#ifdef TEST_COMPLEX + at property (assign) _Complex int i_complex_ivar; + at property (assign) _Complex float f_complex_ivar; +#endif + at property (assign) IntPair i_pair_ivar; + at property (assign) FloatPair f_pair_ivar; + +// Method calls & return types + +-(void) nullary; +-(void) unary_i: (int) a0; +-(int) return_i; +-(void) unary_ll: (long long) a0; +-(long long) return_ll; +-(void) unary_f: (float) a0; +-(float) return_f; +-(void) unary_d: (double) a0; +-(double) return_d; +#ifdef TEST_COMPLEX +-(void) unary_i_complex: (_Complex int) a0; +-(_Complex int) return_i_complex; +-(void) unary_f_complex: (_Complex float) a0; +-(_Complex float) return_f_complex; +#endif +-(void) unary_i_pair: (IntPair) a0; +-(IntPair) return_i_pair; +-(void) unary_f_pair: (FloatPair) a0; +-(FloatPair) return_f_pair; + + at end + + at implementation A + at synthesize i_ivar = _i_ivar; + at synthesize ll_ivar = _ll_ivar; + at synthesize f_ivar = _f_ivar; + at synthesize d_ivar = _d_ivar; +#ifdef TEST_COMPLEX + at synthesize i_complex_ivar = _i_complex_ivar; + at synthesize f_complex_ivar = _f_complex_ivar; +#endif + at synthesize i_pair_ivar = _i_pair_ivar; + at synthesize f_pair_ivar = _f_pair_ivar; + +-(void) nullary { + D(__FUNCTION__); +} + +-(void) unary_i: (int) a0 { + D(__FUNCTION__); + printf("\ta0: %d\n", a0); + self.i_ivar = a0; +} + +-(int) return_i { + D(__FUNCTION__); + int rv = self.i_ivar; + printf("\t returning: %d\n", rv); + return rv; +} + +-(void) unary_ll: (long long) a0 { + D(__FUNCTION__); + printf("\ta0: %ld\n", a0); + self.ll_ivar = a0; +} + +-(long long) return_ll { + D(__FUNCTION__); + long long rv = self.ll_ivar; + printf("\t returning: %ld\n", rv); + return rv; +} + +-(void) unary_f: (float) a0 { + D(__FUNCTION__); + printf("\ta0: %f\n", a0); + self.f_ivar = a0; +} + +-(float) return_f { + D(__FUNCTION__); + float rv = self.f_ivar; + printf("\t returning: %f\n", rv); + return rv; +} + +-(void) unary_d: (double) a0 { + D(__FUNCTION__); + printf("\ta0: %f\n", a0); + self.d_ivar = a0; +} + +-(double) return_d { + D(__FUNCTION__); + double rv = self.d_ivar; + printf("\t returning: %f\n", rv); + return rv; +} + +#ifdef TEST_COMPLEX +-(void) unary_i_complex: (_Complex int) a0 { + D(__FUNCTION__); + printf("\ta0: %d + %dj\n", __real a0, __imag a0); + self.i_complex_ivar = a0; +} + +-(_Complex int) return_i_complex { + D(__FUNCTION__); + _Complex int rv = self.i_complex_ivar; + printf("\t returning: (%d, %d)\n", __real rv, __imag rv); + return rv; +} + +-(void) unary_f_complex: (_Complex float) a0 { + D(__FUNCTION__); + printf("\ta0: %f + %fj\n", __real a0, __imag a0); + self.f_complex_ivar = a0; +} + +-(_Complex float) return_f_complex { + D(__FUNCTION__); + _Complex float rv = self.f_complex_ivar; + printf("\t returning: (%f, %f)\n", __real rv, __imag rv); + return rv; +} +#endif + +-(void) unary_i_pair: (IntPair) a0 { + D(__FUNCTION__); + printf("\ta0: (%d, %d)\n", a0.first, a0.second); + self.i_pair_ivar = a0; +} + +-(IntPair) return_i_pair { + D(__FUNCTION__); + IntPair rv = self.i_pair_ivar; + printf("\t returning: (%d, %d)\n", rv.first, rv.second); + return rv; +} + +-(void) unary_f_pair: (FloatPair) a0 { + D(__FUNCTION__); + printf("\ta0: (%f, %f)\n", a0.first, a0.second); + self.f_pair_ivar = a0; +} + +-(FloatPair) return_f_pair { + D(__FUNCTION__); + FloatPair rv = self.f_pair_ivar; + printf("\t returning: (%f, %f)\n", rv.first, rv.second); + return rv; +} + + at end + +int main() { + NSAutoreleasePool *AP = [[NSAutoreleasePool alloc] init]; + + A *a = [[A alloc] init]; + + int i_test_var = 0xABCDABCD; + long long ll_test_var = 0xABCDABCDABCDABCDLL; + float f_test_var = 52.5; + double d_test_var = 25.2; +#ifdef TEST_COMPLEX + _Complex int i_complex_test_var = 123 + 456j; + _Complex float f_complex_test_var = 123.4 + 678.5j; +#endif + IntPair i_pair_test_var = { 0xABCDABCD, 0xDBCADBCA }; + FloatPair f_pair_test_var = { 25.2, 52.5 }; + + [a nullary]; + [a unary_i: i_test_var]; + [a unary_ll: ll_test_var]; + [a unary_f: f_test_var]; + [a unary_d: d_test_var]; +#ifdef TEST_COMPLEX + [a unary_i_complex: i_complex_test_var]; + [a unary_f_complex: f_complex_test_var]; +#endif + [a unary_i_pair: i_pair_test_var]; + [a unary_f_pair: f_pair_test_var]; + + { + int rv = [a return_i]; + printf("\tresult: %d\n\n", rv); + assert(rv == i_test_var); + } + { + long long rv = [a return_ll]; + printf("\tresult: %ld\n\n", rv); + assert(rv == ll_test_var); + } + { + float rv = [a return_f]; + printf("\tresult: %f\n\n", rv); + assert(rv == f_test_var); + } + { + double rv = [a return_d]; + printf("\tresult: %f\n\n", rv); + assert(rv == d_test_var); + } +#ifdef TEST_COMPLEX + { + _Complex int rv = [a return_i_complex]; + printf("\tresult: (%d, %d)\n\n", __real rv, __imag rv); + assert(rv == i_complex_test_var); + } + { + _Complex float rv = [a return_f_complex]; + printf("\tresult: (%f, %f)\n\n", __real rv, __imag rv); + assert(rv == f_complex_test_var); + } +#endif + { + IntPair rv = [a return_i_pair]; + printf("\tresult: (%d, %d)\n\n", rv.first, rv.second); + assert(memcmp(&rv, &i_pair_test_var, sizeof(rv)) == 0); + } + { + FloatPair rv = [a return_f_pair]; + printf("\tresult: (%f, %f)\n\n", rv.first, rv.second); + assert(memcmp(&rv, &f_pair_test_var, sizeof(rv)) == 0); + } + + [a release]; + + [AP release]; + return 0; +} From foldr at codedgers.com Tue Apr 14 16:31:14 2009 From: foldr at codedgers.com (Mikhail Glushenkov) Date: Tue, 14 Apr 2009 21:31:14 -0000 Subject: [llvm-commits] [llvm] r69081 - /llvm/trunk/lib/System/Win32/Program.inc Message-ID: <200904142131.n3ELVEUU015446@zion.cs.uiuc.edu> Author: foldr Date: Tue Apr 14 16:31:14 2009 New Revision: 69081 URL: http://llvm.org/viewvc/llvm-project?rev=69081&view=rev Log: Delete trailing whitespace. Modified: llvm/trunk/lib/System/Win32/Program.inc Modified: llvm/trunk/lib/System/Win32/Program.inc URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/System/Win32/Program.inc?rev=69081&r1=69080&r2=69081&view=diff ============================================================================== --- llvm/trunk/lib/System/Win32/Program.inc (original) +++ llvm/trunk/lib/System/Win32/Program.inc Tue Apr 14 16:31:14 2009 @@ -1,10 +1,10 @@ //===- Win32/Program.cpp - Win32 Program Implementation ------- -*- C++ -*-===// -// +// // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. -// +// //===----------------------------------------------------------------------===// // // This file provides the Win32 specific implementation of the Program class. @@ -18,7 +18,7 @@ #include //===----------------------------------------------------------------------===// -//=== WARNING: Implementation here must contain only Win32 specific code +//=== WARNING: Implementation here must contain only Win32 specific code //=== and must not be UNIX code //===----------------------------------------------------------------------===// @@ -77,7 +77,7 @@ 0, TRUE, DUPLICATE_SAME_ACCESS); return h; } - + const char *fname; if (path->isEmpty()) fname = "NUL"; @@ -108,9 +108,9 @@ LPVOID lpJobObjectInfo, DWORD cbJobObjectInfoLength); #endif - -int -Program::ExecuteAndWait(const Path& path, + +int +Program::ExecuteAndWait(const Path& path, const char** args, const char** envp, const Path** redirects, @@ -156,7 +156,7 @@ // The pointer to the environment block for the new process. char *envblock = 0; - + if (envp) { // An environment block consists of a null-terminated block of // null-terminated strings. Convert the array of environment variables to @@ -191,7 +191,7 @@ if (redirects) { si.dwFlags = STARTF_USESTDHANDLES; - + si.hStdInput = RedirectIO(redirects[0], 0, ErrMsg); if (si.hStdInput == INVALID_HANDLE_VALUE) { MakeErrMsg(ErrMsg, "can't redirect stdin"); @@ -220,7 +220,7 @@ } } } - + PROCESS_INFORMATION pi; memset(&pi, 0, sizeof(pi)); @@ -240,7 +240,7 @@ if (!rc) { SetLastError(err); - MakeErrMsg(ErrMsg, std::string("Couldn't execute program '") + + MakeErrMsg(ErrMsg, std::string("Couldn't execute program '") + path.toString() + "'"); return -1; } @@ -287,7 +287,7 @@ } WaitForSingleObject(pi.hProcess, INFINITE); } - + // Get its exit status. DWORD status; rc = GetExitCodeProcess(pi.hProcess, &status); @@ -295,7 +295,7 @@ if (!rc) { SetLastError(err); - MakeErrMsg(ErrMsg, std::string("Failed getting status for program '") + + MakeErrMsg(ErrMsg, std::string("Failed getting status for program '") + path.toString() + "'"); return -1; } From foldr at codedgers.com Tue Apr 14 16:31:36 2009 From: foldr at codedgers.com (Mikhail Glushenkov) Date: Tue, 14 Apr 2009 21:31:36 -0000 Subject: [llvm-commits] [llvm] r69082 - /llvm/trunk/lib/System/Win32/Program.inc Message-ID: <200904142131.n3ELVaki015472@zion.cs.uiuc.edu> Author: foldr Date: Tue Apr 14 16:31:36 2009 New Revision: 69082 URL: http://llvm.org/viewvc/llvm-project?rev=69082&view=rev Log: Call CreateProcess with bInheritHandles = TRUE. Makes llvmc show error messages printed by child processes when run from the Cygwin/MSYS shell. Since ExecuteAndWait does not return until the child program has finished execution, this change should be harmless. Modified: llvm/trunk/lib/System/Win32/Program.inc Modified: llvm/trunk/lib/System/Win32/Program.inc URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/System/Win32/Program.inc?rev=69082&r1=69081&r2=69082&view=diff ============================================================================== --- llvm/trunk/lib/System/Win32/Program.inc (original) +++ llvm/trunk/lib/System/Win32/Program.inc Tue Apr 14 16:31:36 2009 @@ -226,7 +226,7 @@ fflush(stdout); fflush(stderr); - BOOL rc = CreateProcess(path.c_str(), command, NULL, NULL, FALSE, 0, + BOOL rc = CreateProcess(path.c_str(), command, NULL, NULL, TRUE, 0, envblock, NULL, &si, &pi); DWORD err = GetLastError(); From gohman at apple.com Tue Apr 14 17:17:14 2009 From: gohman at apple.com (Dan Gohman) Date: Tue, 14 Apr 2009 22:17:14 -0000 Subject: [llvm-commits] [llvm] r69087 - in /llvm/trunk: lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp test/CodeGen/X86/h-registers-0.ll test/CodeGen/X86/h-registers-1.ll test/CodeGen/X86/h-registers.ll Message-ID: <200904142217.n3EMHENA017231@zion.cs.uiuc.edu> Author: djg Date: Tue Apr 14 17:17:14 2009 New Revision: 69087 URL: http://llvm.org/viewvc/llvm-project?rev=69087&view=rev Log: When the result of an EXTRACT_SUBREG, INSERT_SUBREG, or SUBREG_TO_REG operator is used by a CopyToReg to export the value to a different block, don't reuse the CopyToReg's register for the subreg operation result if the register isn't precisely the right class for the subreg operation. Also, rename the h-registers.ll test, now that there are more than one. Added: llvm/trunk/test/CodeGen/X86/h-registers-0.ll - copied unchanged from r69083, llvm/trunk/test/CodeGen/X86/h-registers.ll llvm/trunk/test/CodeGen/X86/h-registers-1.ll Removed: llvm/trunk/test/CodeGen/X86/h-registers.ll Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp?rev=69087&r1=69086&r2=69087&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp Tue Apr 14 17:17:14 2009 @@ -402,19 +402,16 @@ 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 || DRC->hasSubClass(SRC)) && - "Source subregister and destination must have the same class"); -#endif - } else { + // Figure out the register class to create for the destreg. + // Note that if we're going to directly use an existing register, + // it must be precisely the required class, and not a subclass + // thereof. + if (VRBase == 0 || SRC != MRI.getRegClass(VRBase)) { // 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); @@ -427,19 +424,21 @@ SDValue N2 = Node->getOperand(2); unsigned SubReg = getVR(N1, VRBaseMap); unsigned SubIdx = cast(N2)->getZExtValue(); - - + const TargetRegisterClass *TRC = MRI.getRegClass(SubReg); + const TargetRegisterClass *SRC = + getSuperRegisterRegClass(TRC, SubIdx, + Node->getValueType(0)); + // 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 + // Note that if we're going to directly use an existing register, + // it must be precisely the required class, and not a subclass + // thereof. + if (VRBase == 0 || SRC != MRI.getRegClass(VRBase)) { + // Create the reg + assert(SRC && "Couldn't find source register class"); + VRBase = MRI.createVirtualRegister(SRC); } - + // Create the insert_subreg or subreg_to_reg machine instruction. MachineInstr *MI = BuildMI(MF, Node->getDebugLoc(), TII->get(Opc)); MI->addOperand(MachineOperand::CreateReg(VRBase, true)); Added: llvm/trunk/test/CodeGen/X86/h-registers-1.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/h-registers-1.ll?rev=69087&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/h-registers-1.ll (added) +++ llvm/trunk/test/CodeGen/X86/h-registers-1.ll Tue Apr 14 17:17:14 2009 @@ -0,0 +1,39 @@ +; RUN: llvm-as < %s | llc -march=x86-64 > %t +; RUN: grep {movzbl %\[abcd\]h,} %t | count 8 +; RUN: grep {%\[abcd\]h} %t | not grep {%r\[\[:digit:\]\]*d} + +; LLVM creates virtual registers for values live across blocks +; based on the type of the value. Make sure that the extracts +; here use the GR64_NOREX register class for their result, +; instead of plain GR64. + +define i64 @foo(i64 %a, i64 %b, i64 %c, i64 %d, + i64 %e, i64 %f, i64 %g, i64 %h) { + %sa = lshr i64 %a, 8 + %A = and i64 %sa, 255 + %sb = lshr i64 %b, 8 + %B = and i64 %sb, 255 + %sc = lshr i64 %c, 8 + %C = and i64 %sc, 255 + %sd = lshr i64 %d, 8 + %D = and i64 %sd, 255 + %se = lshr i64 %e, 8 + %E = and i64 %se, 255 + %sf = lshr i64 %f, 8 + %F = and i64 %sf, 255 + %sg = lshr i64 %g, 8 + %G = and i64 %sg, 255 + %sh = lshr i64 %h, 8 + %H = and i64 %sh, 255 + br label %next + +next: + %u = add i64 %A, %B + %v = add i64 %C, %D + %w = add i64 %E, %F + %x = add i64 %G, %H + %y = add i64 %u, %v + %z = add i64 %w, %x + %t = add i64 %y, %z + ret i64 %t +} Removed: llvm/trunk/test/CodeGen/X86/h-registers.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/h-registers.ll?rev=69086&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/h-registers.ll (original) +++ llvm/trunk/test/CodeGen/X86/h-registers.ll (removed) @@ -1,48 +0,0 @@ -; RUN: llvm-as < %s | llc -march=x86-64 | grep {movzbl %\[abcd\]h,} | count 4 -; RUN: llvm-as < %s | llc -march=x86 > %t -; RUN: grep {incb %ah} %t | count 3 -; RUN: grep {movzbl %ah,} %t | count 3 - -; Use h registers. On x86-64, codegen doesn't support general allocation -; of h registers yet, due to x86 encoding complications. - -define void @bar64(i64 inreg %x, i8* inreg %p) nounwind { - %t0 = lshr i64 %x, 8 - %t1 = trunc i64 %t0 to i8 - %t2 = add i8 %t1, 1 - store i8 %t2, i8* %p - ret void -} - -define void @bar32(i32 inreg %x, i8* inreg %p) nounwind { - %t0 = lshr i32 %x, 8 - %t1 = trunc i32 %t0 to i8 - %t2 = add i8 %t1, 1 - store i8 %t2, i8* %p - ret void -} - -define void @bar16(i16 inreg %x, i8* inreg %p) nounwind { - %t0 = lshr i16 %x, 8 - %t1 = trunc i16 %t0 to i8 - %t2 = add i8 %t1, 1 - store i8 %t2, i8* %p - ret void -} - -define i64 @qux64(i64 inreg %x) nounwind { - %t0 = lshr i64 %x, 8 - %t1 = and i64 %t0, 255 - ret i64 %t1 -} - -define i32 @qux32(i32 inreg %x) nounwind { - %t0 = lshr i32 %x, 8 - %t1 = and i32 %t0, 255 - ret i32 %t1 -} - -define i16 @qux16(i16 inreg %x) nounwind { - %t0 = lshr i16 %x, 8 - ret i16 %t0 -} From evan.cheng at apple.com Tue Apr 14 17:32:00 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 14 Apr 2009 22:32:00 -0000 Subject: [llvm-commits] [llvm] r69090 - /llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp Message-ID: <200904142232.n3EMW0gD017820@zion.cs.uiuc.edu> Author: evancheng Date: Tue Apr 14 17:31:59 2009 New Revision: 69090 URL: http://llvm.org/viewvc/llvm-project?rev=69090&view=rev Log: Mac OS X 10.6 and above do not use key manager to register EH frames. Modified: llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp Modified: llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp?rev=69090&r1=69089&r2=69090&view=diff ============================================================================== --- llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp (original) +++ llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp Tue Apr 14 17:31:59 2009 @@ -86,7 +86,13 @@ extern "C" void __register_frame(void*); -#if defined(__APPLE__) +#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED <= 1050 +# define USE_KEYMGR 1 +#else +# define USE_KEYMGR 0 +#endif + +#if USE_KEYMGR namespace { @@ -224,7 +230,7 @@ // Register routine for informing unwinding runtime about new EH frames #if defined(__GNUC__) && !defined(__ARM_EABI__) -#if defined(__APPLE__) +#if USE_KEYMGR struct LibgccObjectInfo* LOI = (struct LibgccObjectInfo*) _keymgr_get_and_lock_processwide_ptr(KEYMGR_GCC3_DW2_OBJ_LIST); From gohman at apple.com Tue Apr 14 17:45:06 2009 From: gohman at apple.com (Dan Gohman) Date: Tue, 14 Apr 2009 22:45:06 -0000 Subject: [llvm-commits] [llvm] r69094 - in /llvm/trunk: lib/Target/X86/X86ISelDAGToDAG.cpp test/CodeGen/X86/h-registers-2.ll Message-ID: <200904142245.n3EMj6hd018353@zion.cs.uiuc.edu> Author: djg Date: Tue Apr 14 17:45:05 2009 New Revision: 69094 URL: http://llvm.org/viewvc/llvm-project?rev=69094&view=rev Log: For the h-register addressing-mode trick, use the correct value for any non-address uses of the address value. This fixes 186.crafty. Added: llvm/trunk/test/CodeGen/X86/h-registers-2.ll Modified: llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Modified: llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp?rev=69094&r1=69093&r2=69094&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Tue Apr 14 17:45:05 2009 @@ -1049,6 +1049,9 @@ X, Eight); SDValue And = CurDAG->getNode(ISD::AND, dl, N.getValueType(), Srl, Mask); + SDValue ShlCount = CurDAG->getConstant(ScaleLog, MVT::i8); + SDValue Shl = CurDAG->getNode(ISD::SHL, dl, N.getValueType(), + And, ShlCount); // Insert the new nodes into the topological ordering. if (Eight.getNode()->getNodeId() == -1 || @@ -1071,7 +1074,17 @@ CurDAG->RepositionNode(N.getNode(), And.getNode()); And.getNode()->setNodeId(N.getNode()->getNodeId()); } - CurDAG->ReplaceAllUsesWith(N, And); + if (ShlCount.getNode()->getNodeId() == -1 || + ShlCount.getNode()->getNodeId() > X.getNode()->getNodeId()) { + CurDAG->RepositionNode(X.getNode(), ShlCount.getNode()); + ShlCount.getNode()->setNodeId(N.getNode()->getNodeId()); + } + if (Shl.getNode()->getNodeId() == -1 || + Shl.getNode()->getNodeId() > N.getNode()->getNodeId()) { + CurDAG->RepositionNode(N.getNode(), Shl.getNode()); + Shl.getNode()->setNodeId(N.getNode()->getNodeId()); + } + CurDAG->ReplaceAllUsesWith(N, Shl); AM.IndexReg = And; AM.Scale = (1 << ScaleLog); return false; Added: llvm/trunk/test/CodeGen/X86/h-registers-2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/h-registers-2.ll?rev=69094&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/h-registers-2.ll (added) +++ llvm/trunk/test/CodeGen/X86/h-registers-2.ll Tue Apr 14 17:45:05 2009 @@ -0,0 +1,15 @@ +; RUN: llvm-as < %s | llc -march=x86 > %t +; grep {movzbl %\[abcd\]h,} %t | count 1 +; grep {shll \$3,} | count 1 + +; Use an h register, but don't omit the explicit shift for +; non-address use(s). + +define i32 @foo(i8* %x, i32 %y) nounwind { + %t0 = lshr i32 %y, 8 ; [#uses=1] + %t1 = and i32 %t0, 255 ; [#uses=2] + %t2 = shl i32 %t1, 3 + %t3 = getelementptr i8* %x, i32 %t2 ; [#uses=1] + store i8 77, i8* %t3, align 4 + ret i32 %t2 +} From gohman at apple.com Tue Apr 14 17:50:18 2009 From: gohman at apple.com (Dan Gohman) Date: Tue, 14 Apr 2009 22:50:18 -0000 Subject: [llvm-commits] [llvm] r69096 - /llvm/trunk/test/CodeGen/X86/h-registers-2.ll Message-ID: <200904142250.n3EMoIfw018551@zion.cs.uiuc.edu> Author: djg Date: Tue Apr 14 17:50:17 2009 New Revision: 69096 URL: http://llvm.org/viewvc/llvm-project?rev=69096&view=rev Log: Fix the RUN lines so that this test actually tests. Modified: llvm/trunk/test/CodeGen/X86/h-registers-2.ll Modified: llvm/trunk/test/CodeGen/X86/h-registers-2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/h-registers-2.ll?rev=69096&r1=69095&r2=69096&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/h-registers-2.ll (original) +++ llvm/trunk/test/CodeGen/X86/h-registers-2.ll Tue Apr 14 17:50:17 2009 @@ -1,6 +1,6 @@ ; RUN: llvm-as < %s | llc -march=x86 > %t -; grep {movzbl %\[abcd\]h,} %t | count 1 -; grep {shll \$3,} | count 1 +; RUN: grep {movzbl %\[abcd\]h,} %t | count 1 +; RUN: grep {shll \$3,} %t | count 1 ; Use an h register, but don't omit the explicit shift for ; non-address use(s). From evan.cheng at apple.com Tue Apr 14 18:40:03 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 14 Apr 2009 23:40:03 -0000 Subject: [llvm-commits] [llvm] r69102 - in /llvm/trunk: lib/Transforms/Scalar/CondPropagate.cpp test/Transforms/CondProp/phisimplify3.ll Message-ID: <200904142340.n3ENe4FD020265@zion.cs.uiuc.edu> Author: evancheng Date: Tue Apr 14 18:40:03 2009 New Revision: 69102 URL: http://llvm.org/viewvc/llvm-project?rev=69102&view=rev Log: Optimize conditional branch on i1 phis with non-constant inputs. This turns: eq: %3 = icmp eq i32 %1, %2 br label %join ne: %4 = icmp ne i32 %1, %2 br label %join join: %5 = phi i1 [%3, %eq], [%4, %ne] br i1 %5, label %yes, label %no => eq: %3 = icmp eq i32 %1, %2 br i1 %3, label %yes, label %no ne: %4 = icmp ne i32 %1, %2 br i1 %4, label %yes, label %no Added: llvm/trunk/test/Transforms/CondProp/phisimplify3.ll Modified: llvm/trunk/lib/Transforms/Scalar/CondPropagate.cpp Modified: llvm/trunk/lib/Transforms/Scalar/CondPropagate.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CondPropagate.cpp?rev=69102&r1=69101&r2=69102&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/CondPropagate.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/CondPropagate.cpp Tue Apr 14 18:40:03 2009 @@ -51,6 +51,7 @@ void SimplifyPredecessors(BranchInst *BI); void SimplifyPredecessors(SwitchInst *SI); void RevectorBlockTo(BasicBlock *FromBB, BasicBlock *ToBB); + bool RevectorBlockTo(BasicBlock *FromBB, Value *Cond, BranchInst *BI); }; } @@ -160,20 +161,19 @@ // Ok, we have this really simple case, walk the PHI operands, looking for // constants. Walk from the end to remove operands from the end when // possible, and to avoid invalidating "i". - for (unsigned i = PN->getNumIncomingValues(); i != 0; --i) - if (ConstantInt *CB = dyn_cast(PN->getIncomingValue(i-1))) { - // If we have a constant, forward the edge from its current to its - // ultimate destination. - RevectorBlockTo(PN->getIncomingBlock(i-1), - BI->getSuccessor(CB->isZero())); - ++NumBrThread; - - // If there were two predecessors before this simplification, or if the - // PHI node contained all the same value except for the one we just - // substituted, the PHI node may be deleted. Don't iterate through it the - // last time. - if (BI->getCondition() != PN) return; - } + for (unsigned i = PN->getNumIncomingValues(); i != 0; --i) { + Value *InVal = PN->getIncomingValue(i-1); + if (!RevectorBlockTo(PN->getIncomingBlock(i-1), InVal, BI)) + continue; + + ++NumBrThread; + + // If there were two predecessors before this simplification, or if the + // PHI node contained all the same value except for the one we just + // substituted, the PHI node may be deleted. Don't iterate through it the + // last time. + if (BI->getCondition() != PN) return; + } } // SimplifyPredecessors(switch) - We know that SI is switch based on a PHI node @@ -242,3 +242,44 @@ MadeChange = true; } + +bool CondProp::RevectorBlockTo(BasicBlock *FromBB, Value *Cond, BranchInst *BI){ + BranchInst *FromBr = cast(FromBB->getTerminator()); + if (!FromBr->isUnconditional()) + return false; + + // Get the old block we are threading through. + BasicBlock *OldSucc = FromBr->getSuccessor(0); + + // If the condition is a constant, simply revector the unconditional branch at + // the end of FromBB to one of the successors of its current successor. + if (ConstantInt *CB = dyn_cast(Cond)) { + BasicBlock *ToBB = BI->getSuccessor(CB->isZero()); + + // OldSucc had multiple successors. If ToBB has multiple predecessors, then + // the edge between them would be critical, which we already took care of. + // If ToBB has single operand PHI node then take care of it here. + FoldSingleEntryPHINodes(ToBB); + + // Update PHI nodes in OldSucc to know that FromBB no longer branches to it. + OldSucc->removePredecessor(FromBB); + + // Change FromBr to branch to the new destination. + FromBr->setSuccessor(0, ToBB); + } else { + // Insert the new conditional branch. + BranchInst::Create(BI->getSuccessor(0), BI->getSuccessor(1), Cond, FromBr); + + FoldSingleEntryPHINodes(BI->getSuccessor(0)); + FoldSingleEntryPHINodes(BI->getSuccessor(1)); + + // Update PHI nodes in OldSucc to know that FromBB no longer branches to it. + OldSucc->removePredecessor(FromBB); + + // Delete the old branch. + FromBr->eraseFromParent(); + } + + MadeChange = true; + return true; +} Added: llvm/trunk/test/Transforms/CondProp/phisimplify3.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/CondProp/phisimplify3.ll?rev=69102&view=auto ============================================================================== --- llvm/trunk/test/Transforms/CondProp/phisimplify3.ll (added) +++ llvm/trunk/test/Transforms/CondProp/phisimplify3.ll Tue Apr 14 18:40:03 2009 @@ -0,0 +1,26 @@ +; RUN: llvm-as < %s | opt -condprop | llvm-dis | not grep phi + +define i32 @foo(i1, i32, i32) { +prologue: + br i1 %0, label %eq, label %ne + +eq: ; preds = %prologue + store i32 0, i32* inttoptr (i32 10000 to i32*) + %3 = icmp eq i32 %1, %2 ; [#uses=1] + br label %join + +ne: ; preds = %prologue + %4 = icmp ne i32 %1, %2 ; [#uses=1] + br label %join + +join: ; preds = %ne, %eq + %5 = phi i1 [ %3, %eq ], [ %4, %ne ] ; [#uses=1] + br i1 %5, label %yes, label %no + +yes: ; preds = %join + store i32 0, i32* inttoptr (i32 20000 to i32*) + ret i32 5 + +no: ; preds = %join + ret i32 20 +} From isanbard at gmail.com Tue Apr 14 18:56:18 2009 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 14 Apr 2009 23:56:18 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r69104 - in /llvm-gcc-4.2/trunk/gcc: llvm-backend.cpp testsuite/llvm.objc/2009-04-14-AsmSection.m Message-ID: <200904142356.n3ENuIA8020769@zion.cs.uiuc.edu> Author: void Date: Tue Apr 14 18:56:18 2009 New Revision: 69104 URL: http://llvm.org/viewvc/llvm-project?rev=69104&view=rev Log: If we create a new global variable when resetting the initializer, then copy over the section. Added: llvm-gcc-4.2/trunk/gcc/testsuite/llvm.objc/2009-04-14-AsmSection.m Modified: llvm-gcc-4.2/trunk/gcc/llvm-backend.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=69104&r1=69103&r2=69104&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Tue Apr 14 18:56:18 2009 @@ -1198,6 +1198,7 @@ GV->getLinkage(), 0, GV->getName(), TheModule); NGV->setVisibility(GV->getVisibility()); + NGV->setSection(GV->getSection()); GV->replaceAllUsesWith(TheFolder->CreateBitCast(NGV, GV->getType())); changeLLVMConstant(GV, NGV); delete GV; Added: llvm-gcc-4.2/trunk/gcc/testsuite/llvm.objc/2009-04-14-AsmSection.m URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/llvm.objc/2009-04-14-AsmSection.m?rev=69104&view=auto ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/llvm.objc/2009-04-14-AsmSection.m (added) +++ llvm-gcc-4.2/trunk/gcc/testsuite/llvm.objc/2009-04-14-AsmSection.m Tue Apr 14 18:56:18 2009 @@ -0,0 +1,11 @@ +/* LLVM LOCAL file rdar://6763960 */ +/* { dg-do compile { target *-*-darwin* } } */ +/* { dg-options "-O0 -fobjc-abi-version=2" } */ + + at interface A + at end + + at implementation A + at end + +/* { dg-final { scan-assembler "OBJC_CLASS_$_A.*section.*__DATA, __objc_data" } } */ From gohman at apple.com Tue Apr 14 19:00:48 2009 From: gohman at apple.com (Dan Gohman) Date: Wed, 15 Apr 2009 00:00:48 -0000 Subject: [llvm-commits] [llvm] r69108 - /llvm/trunk/lib/Target/X86/X86RegisterInfo.td Message-ID: <200904150000.n3F00m24020978@zion.cs.uiuc.edu> Author: djg Date: Tue Apr 14 19:00:48 2009 New Revision: 69108 URL: http://llvm.org/viewvc/llvm-project?rev=69108&view=rev Log: GR8_NOREX can contain the H registers, since they don't require REX prefixes. 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=69108&r1=69107&r2=69108&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86RegisterInfo.td (original) +++ llvm/trunk/lib/Target/X86/X86RegisterInfo.td Tue Apr 14 19:00:48 2009 @@ -483,7 +483,8 @@ // On x86-64, GR64_NOREX, GR32_NOREX and GR16_NOREX are the classes // of registers which do not by themselves require a REX prefix. def GR8_NOREX : RegisterClass<"X86", [i8], 8, - [AL, CL, DL, SIL, DIL, BL, BPL, SPL]> { + [AL, CL, DL, BL, AH, CH, DH, BH, + SIL, DIL, BPL, SPL]> { let MethodProtos = [{ iterator allocation_order_begin(const MachineFunction &MF) const; iterator allocation_order_end(const MachineFunction &MF) const; @@ -500,7 +501,7 @@ }; // In 32-mode, none of the 8-bit registers aliases EBP or ESP. static const unsigned X86_GR8_NOREX_AO_32[] = { - X86::AL, X86::CL, X86::DL, X86::BL + X86::AL, X86::CL, X86::DL, X86::AH, X86::CH, X86::DH, X86::BL, X86::BH }; GR8_NOREXClass::iterator From isanbard at gmail.com Tue Apr 14 19:03:00 2009 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 15 Apr 2009 00:03:00 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r69109 - /llvm-gcc-4.2/trunk/gcc/testsuite/llvm.objc/2009-04-14-AsmSection.m Message-ID: <200904150003.n3F030pI021048@zion.cs.uiuc.edu> Author: void Date: Tue Apr 14 19:02:59 2009 New Revision: 69109 URL: http://llvm.org/viewvc/llvm-project?rev=69109&view=rev Log: Moving to LLVM regression tests. Removed: llvm-gcc-4.2/trunk/gcc/testsuite/llvm.objc/2009-04-14-AsmSection.m Removed: llvm-gcc-4.2/trunk/gcc/testsuite/llvm.objc/2009-04-14-AsmSection.m URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/llvm.objc/2009-04-14-AsmSection.m?rev=69108&view=auto ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/llvm.objc/2009-04-14-AsmSection.m (original) +++ llvm-gcc-4.2/trunk/gcc/testsuite/llvm.objc/2009-04-14-AsmSection.m (removed) @@ -1,11 +0,0 @@ -/* LLVM LOCAL file rdar://6763960 */ -/* { dg-do compile { target *-*-darwin* } } */ -/* { dg-options "-O0 -fobjc-abi-version=2" } */ - - at interface A - at end - - at implementation A - at end - -/* { dg-final { scan-assembler "OBJC_CLASS_$_A.*section.*__DATA, __objc_data" } } */ From isanbard at gmail.com Tue Apr 14 19:04:12 2009 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 15 Apr 2009 00:04:12 -0000 Subject: [llvm-commits] [llvm] r69110 - /llvm/trunk/test/FrontendObjC/2009-04-14-AsmSection.m Message-ID: <200904150004.n3F04CkG021094@zion.cs.uiuc.edu> Author: void Date: Tue Apr 14 19:04:11 2009 New Revision: 69110 URL: http://llvm.org/viewvc/llvm-project?rev=69110&view=rev Log: Testcase for r69104. Added: llvm/trunk/test/FrontendObjC/2009-04-14-AsmSection.m Added: llvm/trunk/test/FrontendObjC/2009-04-14-AsmSection.m URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/FrontendObjC/2009-04-14-AsmSection.m?rev=69110&view=auto ============================================================================== --- llvm/trunk/test/FrontendObjC/2009-04-14-AsmSection.m (added) +++ llvm/trunk/test/FrontendObjC/2009-04-14-AsmSection.m Tue Apr 14 19:04:11 2009 @@ -0,0 +1,8 @@ +// RUN: %llvmgcc -S %s -fobjc-abi-version=2 -emit-llvm -o - | grep {OBJC_CLASS_\$_A.*section.*__DATA, __objc_data} +// XTARGETS: darwin + + at interface A + at end + + at implementation A + at end From gohman at apple.com Tue Apr 14 19:04:24 2009 From: gohman at apple.com (Dan Gohman) Date: Wed, 15 Apr 2009 00:04:24 -0000 Subject: [llvm-commits] [llvm] r69111 - in /llvm/trunk/lib/Target/X86: X86InstrInfo.cpp X86InstrInfo.td Message-ID: <200904150004.n3F04OCL021115@zion.cs.uiuc.edu> Author: djg Date: Tue Apr 14 19:04:23 2009 New Revision: 69111 URL: http://llvm.org/viewvc/llvm-project?rev=69111&view=rev Log: Add a new MOV8rr_NOREX, and make X86's copyRegToReg use it when either the source or destination is a physical h register. This fixes sqlite3 with the post-RA scheduler enabled. Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp llvm/trunk/lib/Target/X86/X86InstrInfo.td Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=69111&r1=69110&r2=69111&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Tue Apr 14 19:04:23 2009 @@ -1641,6 +1641,11 @@ return Count; } +/// isHReg - Test if the given register is a physical h register. +static bool isHReg(unsigned Reg) { + return Reg == X86::AH || Reg == X86::BH || Reg == X86::CH || Reg == X86::DH; +} + bool X86InstrInfo::copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, unsigned SrcReg, @@ -1658,7 +1663,12 @@ } else if (DestRC == &X86::GR16RegClass) { Opc = X86::MOV16rr; } else if (DestRC == &X86::GR8RegClass) { - Opc = X86::MOV8rr; + // Copying two or from a physical H register requires a NOREX move. Otherwise + // use a normal move. + if (isHReg(DestReg) || isHReg(SrcReg)) + Opc = X86::MOV8rr_NOREX; + else + Opc = X86::MOV8rr; } else if (DestRC == &X86::GR64_RegClass) { Opc = X86::MOV64rr; } else if (DestRC == &X86::GR32_RegClass) { Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=69111&r1=69110&r2=69111&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Tue Apr 14 19:04:23 2009 @@ -783,10 +783,15 @@ "mov{l}\t{$src, $dst|$dst, $src}", [(store GR32:$src, addr:$dst)]>; -// A version of MOV8mr that uses i8mem_NOREX so that it can be used for -// storing h registers, which can't be encoded when a REX prefix is present. -def MOV8mr_NOREX : I<0x88, MRMDestMem, (outs), (ins i8mem_NOREX:$dst, GR8:$src), - "mov{b}\t{$src, $dst|$dst, $src} # NOREX", []>; +// Versions of MOV8rr and MOV8mr that use i8mem_NOREX and GR8_NOREX so that they +// can be used for copying and storing h registers, which can't be encoded when +// a REX prefix is present. +let neverHasSideEffects = 1 in +def MOV8rr_NOREX : I<0x88, MRMDestReg, (outs GR8_NOREX:$dst), (ins GR8_NOREX:$src), + "mov{b}\t{$src, $dst|$dst, $src} # NOREX", []>; +def MOV8mr_NOREX : I<0x88, MRMDestMem, + (outs), (ins i8mem_NOREX:$dst, GR8_NOREX:$src), + "mov{b}\t{$src, $dst|$dst, $src} # NOREX", []>; //===----------------------------------------------------------------------===// // Fixed-Register Multiplication and Division Instructions... From dpatel at apple.com Tue Apr 14 19:06:08 2009 From: dpatel at apple.com (Devang Patel) Date: Wed, 15 Apr 2009 00:06:08 -0000 Subject: [llvm-commits] [llvm] r69113 - in /llvm/trunk: include/llvm/Analysis/DebugInfo.h lib/Analysis/DebugInfo.cpp Message-ID: <200904150006.n3F068CW021197@zion.cs.uiuc.edu> Author: dpatel Date: Tue Apr 14 19:06:07 2009 New Revision: 69113 URL: http://llvm.org/viewvc/llvm-project?rev=69113&view=rev Log: Add a method to check that the subprogram holds debug info for the given Function or not. Modified: llvm/trunk/include/llvm/Analysis/DebugInfo.h llvm/trunk/lib/Analysis/DebugInfo.cpp Modified: llvm/trunk/include/llvm/Analysis/DebugInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/DebugInfo.h?rev=69113&r1=69112&r2=69113&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/DebugInfo.h (original) +++ llvm/trunk/include/llvm/Analysis/DebugInfo.h Tue Apr 14 19:06:07 2009 @@ -309,6 +309,10 @@ /// dump - print subprogram. void dump() const; + + /// describes - Return true if this subprogram provides debugging + /// information for the function F. + bool describes(const Function *F); }; /// DIGlobalVariable - This is a wrapper for a global variable. Modified: llvm/trunk/lib/Analysis/DebugInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/DebugInfo.cpp?rev=69113&r1=69112&r2=69113&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/DebugInfo.cpp (original) +++ llvm/trunk/lib/Analysis/DebugInfo.cpp Tue Apr 14 19:06:07 2009 @@ -291,6 +291,19 @@ return BT.getSizeInBits(); } +/// describes - Return true if this subprogram provides debugging +/// information for the function F. +bool DISubprogram::describes(const Function *F) { + assert (F && "Invalid function"); + std::string Name; + getLinkageName(Name); + if (Name.empty()) + getName(Name); + if (!Name.empty() && (strcmp(Name.c_str(), F->getNameStart()) == false)) + return true; + return false; +} + //===----------------------------------------------------------------------===// // DIFactory: Basic Helpers //===----------------------------------------------------------------------===// From dpatel at apple.com Tue Apr 14 19:07:36 2009 From: dpatel at apple.com (Devang Patel) Date: Tue, 14 Apr 2009 17:07:36 -0700 Subject: [llvm-commits] [llvm-gcc-4.2] r69109 - /llvm-gcc-4.2/trunk/gcc/testsuite/llvm.objc/2009-04-14-AsmSection.m In-Reply-To: <200904150003.n3F030pI021048@zion.cs.uiuc.edu> References: <200904150003.n3F030pI021048@zion.cs.uiuc.edu> Message-ID: <24DBAA7D-B314-483F-B063-9014A1DC0C22@apple.com> On Apr 14, 2009, at 5:03 PM, Bill Wendling wrote: > Author: void > Date: Tue Apr 14 19:02:59 2009 > New Revision: 69109 > > URL: http://llvm.org/viewvc/llvm-project?rev=69109&view=rev > Log: > Moving to LLVM regression tests. Long term we want to move in the other direction and move all FE tests into FE test suite. AFAIK, this is blocked by nightly tester's inability to build and test new llvm-gcc. - Devang > > > Removed: > llvm-gcc-4.2/trunk/gcc/testsuite/llvm.objc/2009-04-14-AsmSection.m > > Removed: llvm-gcc-4.2/trunk/gcc/testsuite/llvm.objc/2009-04-14- > AsmSection.m > URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/llvm.objc/2009-04-14-AsmSection.m?rev=69108&view=auto > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm-gcc-4.2/trunk/gcc/testsuite/llvm.objc/2009-04-14- > AsmSection.m (original) > +++ llvm-gcc-4.2/trunk/gcc/testsuite/llvm.objc/2009-04-14- > AsmSection.m (removed) > @@ -1,11 +0,0 @@ > -/* LLVM LOCAL file rdar://6763960 */ > -/* { dg-do compile { target *-*-darwin* } } */ > -/* { dg-options "-O0 -fobjc-abi-version=2" } */ > - > - at interface A > - at end > - > - at implementation A > - at end > - > -/* { dg-final { scan-assembler "OBJC_CLASS_$_A.*section.*__DATA, > __objc_data" } } */ > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From gohman at apple.com Tue Apr 14 19:10:16 2009 From: gohman at apple.com (Dan Gohman) Date: Wed, 15 Apr 2009 00:10:16 -0000 Subject: [llvm-commits] [llvm] r69115 - /llvm/trunk/lib/Target/X86/X86RegisterInfo.td Message-ID: <200904150010.n3F0AGTR021358@zion.cs.uiuc.edu> Author: djg Date: Tue Apr 14 19:10:16 2009 New Revision: 69115 URL: http://llvm.org/viewvc/llvm-project?rev=69115&view=rev Log: Do for GR16_NOREX what r69049 did for GR8_NOREX, to avoid trouble with the local register allocator. 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=69115&r1=69114&r2=69115&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86RegisterInfo.td (original) +++ llvm/trunk/lib/Target/X86/X86RegisterInfo.td Tue Apr 14 19:10:16 2009 @@ -537,6 +537,41 @@ def GR16_NOREX : RegisterClass<"X86", [i16], 16, [AX, CX, DX, SI, DI, BX, BP, SP]> { let SubRegClassList = [GR8_NOREX, GR8_NOREX]; + let MethodProtos = [{ + iterator allocation_order_begin(const MachineFunction &MF) const; + iterator allocation_order_end(const MachineFunction &MF) const; + }]; + let MethodBodies = [{ + // Does the function dedicate RBP / EBP to being a frame ptr? + // If so, don't allocate SP or BP. + static const unsigned X86_GR16_AO_fp[] = { + X86::AX, X86::CX, X86::DX, X86::SI, X86::DI, X86::BX + }; + // If not, just don't allocate SP. + static const unsigned X86_GR16_AO[] = { + X86::AX, X86::CX, X86::DX, X86::SI, X86::DI, X86::BX, X86::BP + }; + + GR16_NOREXClass::iterator + GR16_NOREXClass::allocation_order_begin(const MachineFunction &MF) const { + const TargetMachine &TM = MF.getTarget(); + const TargetRegisterInfo *RI = TM.getRegisterInfo(); + if (RI->hasFP(MF)) + return X86_GR16_AO_fp; + else + return X86_GR16_AO; + } + + GR16_NOREXClass::iterator + GR16_NOREXClass::allocation_order_end(const MachineFunction &MF) const { + const TargetMachine &TM = MF.getTarget(); + const TargetRegisterInfo *RI = TM.getRegisterInfo(); + if (RI->hasFP(MF)) + return X86_GR16_AO_fp+(sizeof(X86_GR16_AO_fp)/sizeof(unsigned)); + else + return X86_GR16_AO + (sizeof(X86_GR16_AO) / sizeof(unsigned)); + } + }]; } // GR32_NOREX - GR32 registers which do not require a REX prefix. def GR32_NOREX : RegisterClass<"X86", [i32], 32, From isanbard at gmail.com Tue Apr 14 19:10:24 2009 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 14 Apr 2009 17:10:24 -0700 Subject: [llvm-commits] [llvm-gcc-4.2] r69109 - /llvm-gcc-4.2/trunk/gcc/testsuite/llvm.objc/2009-04-14-AsmSection.m In-Reply-To: <24DBAA7D-B314-483F-B063-9014A1DC0C22@apple.com> References: <200904150003.n3F030pI021048@zion.cs.uiuc.edu> <24DBAA7D-B314-483F-B063-9014A1DC0C22@apple.com> Message-ID: <16e5fdf90904141710j11519a73h5469d55b7d66a0ec@mail.gmail.com> On Tue, Apr 14, 2009 at 5:07 PM, Devang Patel wrote: > > On Apr 14, 2009, at 5:03 PM, Bill Wendling wrote: > >> Author: void >> Date: Tue Apr 14 19:02:59 2009 >> New Revision: 69109 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=69109&view=rev >> Log: >> Moving to LLVM regression tests. > > Long term we want to move in the other direction and move all FE tests > into FE test suite. AFAIK, this is blocked by nightly tester's > inability to build and test new llvm-gcc. > Fair enough, though I wanted to check that the LLVM IR it generated was good...Either way works. And, yes, for the time being it's better to keep them in the regression suite. :) -bw From dpatel at apple.com Tue Apr 14 19:10:27 2009 From: dpatel at apple.com (Devang Patel) Date: Wed, 15 Apr 2009 00:10:27 -0000 Subject: [llvm-commits] [llvm] r69116 - in /llvm/trunk: include/llvm/CodeGen/DwarfWriter.h lib/CodeGen/AsmPrinter/AsmPrinter.cpp lib/CodeGen/AsmPrinter/DwarfWriter.cpp lib/CodeGen/SelectionDAG/FastISel.cpp Message-ID: <200904150010.n3F0ARFR021382@zion.cs.uiuc.edu> Author: dpatel Date: Tue Apr 14 19:10:26 2009 New Revision: 69116 URL: http://llvm.org/viewvc/llvm-project?rev=69116&view=rev Log: Construct and emit DW_TAG_inlined_subroutine DIEs for inlined subroutine scopes (only in FastISel mode). Modified: llvm/trunk/include/llvm/CodeGen/DwarfWriter.h llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp Modified: llvm/trunk/include/llvm/CodeGen/DwarfWriter.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/DwarfWriter.h?rev=69116&r1=69115&r2=69116&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/DwarfWriter.h (original) +++ llvm/trunk/include/llvm/CodeGen/DwarfWriter.h Tue Apr 14 19:10:26 2009 @@ -29,11 +29,15 @@ class DwarfException; class MachineModuleInfo; class MachineFunction; +class MachineInstr; class Value; class Module; class GlobalVariable; class TargetAsmInfo; class raw_ostream; +class Instruction; +class DISubprogram; +class DIVariable; //===----------------------------------------------------------------------===// // DwarfWriter - Emits Dwarf debug and exception handling directives. @@ -94,9 +98,6 @@ /// RecordRegionStart - Indicate the start of a region. unsigned RecordRegionStart(GlobalVariable *V); - /// RecordRegionStart - Indicate the start of a region. - unsigned RecordRegionStart(GlobalVariable *V, unsigned ID); - /// RecordRegionEnd - Indicate the end of a region. unsigned RecordRegionEnd(GlobalVariable *V); @@ -105,15 +106,23 @@ /// RecordVariable - Indicate the declaration of a local variable. /// - void RecordVariable(GlobalVariable *GV, unsigned FrameIndex); + void RecordVariable(GlobalVariable *GV, unsigned FrameIndex, + const MachineInstr *MI); /// ShouldEmitDwarfDebug - Returns true if Dwarf debugging declarations should /// be emitted. bool ShouldEmitDwarfDebug() const; - //// RecordInlineInfo - Global variable GV is inlined at the location marked - //// by LabelID label. - void RecordInlineInfo(GlobalVariable *GV, unsigned LabelID); + //// RecordInlinedFnStart - Indicate the start of a inlined function. + void RecordInlinedFnStart(Instruction *I, DISubprogram &SP, unsigned LabelID, + unsigned Src, unsigned Line, unsigned Col); + + /// RecordInlinedFnEnd - Indicate the end of inlined subroutine. + unsigned RecordInlinedFnEnd(DISubprogram &SP); + + /// RecordVariableScope - Record scope for the variable declared by + /// DeclareMI. DeclareMI must describe TargetInstrInfo::DECLARE. + void RecordVariableScope(DIVariable &DV, const MachineInstr *DeclareMI); }; Modified: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp?rev=69116&r1=69115&r2=69116&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Tue Apr 14 19:10:26 2009 @@ -1532,7 +1532,7 @@ void AsmPrinter::printDeclare(const MachineInstr *MI) const { unsigned FI = MI->getOperand(0).getIndex(); GlobalValue *GV = MI->getOperand(1).getGlobal(); - DW->RecordVariable(cast(GV), FI); + DW->RecordVariable(cast(GV), FI, MI); } /// PrintAsmOperand - Print the specified operand of MI, an INLINEASM Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp?rev=69116&r1=69115&r2=69116&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp Tue Apr 14 19:10:26 2009 @@ -1140,7 +1140,7 @@ DbgScope(DbgScope *P, DIDescriptor D) : Parent(P), Desc(D), StartLabelID(0), EndLabelID(0), Scopes(), Variables() {} - ~DbgScope() { + virtual ~DbgScope() { for (unsigned i = 0, N = Scopes.size(); i < N; ++i) delete Scopes[i]; for (unsigned j = 0, M = Variables.size(); j < M; ++j) delete Variables[j]; } @@ -1162,6 +1162,32 @@ /// AddVariable - Add a variable to the scope. /// void AddVariable(DbgVariable *V) { Variables.push_back(V); } + + virtual bool isInlinedSubroutine() { return false; } + virtual unsigned getLine() { assert ( 0 && "Unexpected scope!"); } + virtual unsigned getColumn() { assert ( 0 && "Unexpected scope!"); } + virtual unsigned getFile() { assert ( 0 && "Unexpected scope!"); } +}; + + +//===----------------------------------------------------------------------===// +/// DbgInlinedSubroutineScope - This class is used to track inlined subroutine +/// scope information. +/// +class DbgInlinedSubroutineScope : public DbgScope { + unsigned Src; + unsigned Line; + unsigned Col; +public: + DbgInlinedSubroutineScope(DbgScope *P, DIDescriptor D, + unsigned S, unsigned L, unsigned C) + : DbgScope(P, D), Src(S), Line(L), Col(C) + {} + + unsigned getLine() { return Line; } + unsigned getColumn() { return Col; } + unsigned getFile() { return Src; } + bool isInlinedSubroutine() { return true; } }; //===----------------------------------------------------------------------===// @@ -1252,10 +1278,17 @@ /// DbgScopeMap - Tracks the scopes in the current function. DenseMap DbgScopeMap; + /// DbgInlinedScopeMap - Tracks inlined scopes in the current function. + DenseMap > DbgInlinedScopeMap; + /// InlineInfo - Keep track of inlined functions and their location. /// This information is used to populate debug_inlined section. DenseMap > InlineInfo; + /// InlinedVariableScopes - Scopes information for the inlined subroutine + /// variables. + DenseMap InlinedVariableScopes; + /// DebugTimer - Timer for the Dwarf debug writer. Timer *DebugTimer; @@ -1469,7 +1502,7 @@ /// AddDelta - Add a label delta attribute data and value. /// void AddDelta(DIE *Die, unsigned Attribute, unsigned Form, - const DWLabel &Hi, const DWLabel &Lo) { + const DWLabel &Hi, const DWLabel &Lo) { FoldingSetNodeID ID; DIEDelta::Profile(ID, Hi, Lo); void *Where; @@ -1550,7 +1583,7 @@ /// AddAddress - Add an address attribute to a die based on the location /// provided. void AddAddress(DIE *Die, unsigned Attribute, - const MachineLocation &Location) { + const MachineLocation &Location) { unsigned Reg = RI->getDwarfRegNum(Location.getReg(), false); DIEBlock *Block = new DIEBlock(); @@ -1933,6 +1966,10 @@ if (!SP.isLocalToUnit()) AddUInt(SPDie, DW_AT_external, DW_FORM_flag, 1); + + // DW_TAG_inlined_subroutine may refer to this DIE. + DIE *&Slot = DW_Unit->getDieMapSlotFor(SP.getGV()); + Slot = SPDie; return SPDie; } @@ -1987,33 +2024,39 @@ DbgScope *&Slot = DbgScopeMap[V]; if (Slot) return Slot; - // FIXME - breaks down when the context is an inlined function. - DIDescriptor ParentDesc; - DIDescriptor Desc(V); - - if (Desc.getTag() == dwarf::DW_TAG_lexical_block) { - DIBlock Block(V); - ParentDesc = Block.getContext(); + DbgScope *Parent = NULL; + DIBlock Block(V); + if (!Block.isNull()) { + DIDescriptor ParentDesc = Block.getContext(); + Parent = + ParentDesc.isNull() ? NULL : getOrCreateScope(ParentDesc.getGV()); } + Slot = new DbgScope(Parent, DIDescriptor(V)); - DbgScope *Parent = ParentDesc.isNull() ? - NULL : getOrCreateScope(ParentDesc.getGV()); - Slot = new DbgScope(Parent, Desc); - - if (Parent) { + if (Parent) Parent->AddScope(Slot); - } else if (RootDbgScope) { - // FIXME - Add inlined function scopes to the root so we can delete them - // later. Long term, handle inlined functions properly. - RootDbgScope->AddScope(Slot); - } else { + else // First function is top level function. RootDbgScope = Slot; - } return Slot; } + /// createInlinedSubroutineScope - Returns the scope associated with the + /// inlined subroutine. + /// + DbgScope *createInlinedSubroutineScope(DISubprogram SP, unsigned Src, + unsigned Line, unsigned Col) { + DbgScope *Scope = + new DbgInlinedSubroutineScope(NULL, SP, Src, Line, Col); + + // FIXME - Add inlined function scopes to the root so we can delete them + // later. + assert (RootDbgScope && "Function scope info missing!"); + RootDbgScope->AddScope(Scope); + return Scope; + } + /// ConstructDbgScope - Construct the components of a scope. /// void ConstructDbgScope(DbgScope *ParentScope, @@ -2035,12 +2078,11 @@ unsigned StartID = MMI->MappedLabel(Scope->getStartLabelID()); unsigned EndID = MMI->MappedLabel(Scope->getEndLabelID()); - // Ignore empty scopes. + // Ignore empty scopes. + // Do not ignore inlined scope even if it does not have any + // variables or scopes. if (StartID == EndID && StartID != 0) continue; - - // Do not ignore inlined scope even if it is empty. Inlined scope - // does not have any parent. - if (Scope->getParent() + if (!Scope->isInlinedSubroutine() && Scope->getScopes().empty() && Scope->getVariables().empty()) continue; @@ -2048,27 +2090,37 @@ // Just add stuff to the parent scope. ConstructDbgScope(Scope, ParentStartID, ParentEndID, ParentDie, Unit); } else { - DIE *ScopeDie = new DIE(DW_TAG_lexical_block); - - // Add the scope bounds. - if (StartID) { - AddLabel(ScopeDie, DW_AT_low_pc, DW_FORM_addr, - DWLabel("label", StartID)); - } else { - AddLabel(ScopeDie, DW_AT_low_pc, DW_FORM_addr, - DWLabel("func_begin", SubprogramCount)); + DIE *ScopeDie = NULL; + if (MainCU && TAI->doesDwarfUsesInlineInfoSection()) { + ScopeDie = new DIE(DW_TAG_inlined_subroutine); + DIE *Origin = MainCU->getDieMapSlotFor(Scope->getDesc().getGV()); + AddDIEntry(ScopeDie, DW_AT_abstract_origin, DW_FORM_ref4, Origin); + AddUInt(ScopeDie, DW_AT_call_file, 0, Scope->getFile()); + AddUInt(ScopeDie, DW_AT_call_line, 0, Scope->getLine()); + AddUInt(ScopeDie, DW_AT_call_column, 0, Scope->getColumn()); } - if (EndID) { - AddLabel(ScopeDie, DW_AT_high_pc, DW_FORM_addr, - DWLabel("label", EndID)); - } else { - AddLabel(ScopeDie, DW_AT_high_pc, DW_FORM_addr, - DWLabel("func_end", SubprogramCount)); - } - - // Add the scope contents. - ConstructDbgScope(Scope, StartID, EndID, ScopeDie, Unit); - ParentDie->AddChild(ScopeDie); + else + ScopeDie = new DIE(DW_TAG_lexical_block); + + // Add the scope bounds. + if (StartID) { + AddLabel(ScopeDie, DW_AT_low_pc, DW_FORM_addr, + DWLabel("label", StartID)); + } else { + AddLabel(ScopeDie, DW_AT_low_pc, DW_FORM_addr, + DWLabel("func_begin", SubprogramCount)); + } + if (EndID) { + AddLabel(ScopeDie, DW_AT_high_pc, DW_FORM_addr, + DWLabel("label", EndID)); + } else { + AddLabel(ScopeDie, DW_AT_high_pc, DW_FORM_addr, + DWLabel("func_end", SubprogramCount)); + } + + // Add the scope contents. + ConstructDbgScope(Scope, StartID, EndID, ScopeDie, Unit); + ParentDie->AddChild(ScopeDie); } } } @@ -3286,6 +3338,8 @@ if (RootDbgScope) { delete RootDbgScope; DbgScopeMap.clear(); + DbgInlinedScopeMap.clear(); + InlinedVariableScopes.clear(); RootDbgScope = NULL; } @@ -3423,20 +3477,6 @@ return ID; } - /// RecordRegionStart - Indicate the start of a region. - unsigned RecordRegionStart(GlobalVariable *V, unsigned ID) { - if (TimePassesIsEnabled) - DebugTimer->startTimer(); - - DbgScope *Scope = getOrCreateScope(V); - if (!Scope->getStartLabelID()) Scope->setStartLabelID(ID); - - if (TimePassesIsEnabled) - DebugTimer->stopTimer(); - - return ID; - } - /// RecordRegionEnd - Indicate the end of a region. unsigned RecordRegionEnd(GlobalVariable *V) { if (TimePassesIsEnabled) @@ -3453,7 +3493,8 @@ } /// RecordVariable - Indicate the declaration of a local variable. - void RecordVariable(GlobalVariable *GV, unsigned FrameIndex) { + void RecordVariable(GlobalVariable *GV, unsigned FrameIndex, + const MachineInstr *MI) { if (TimePassesIsEnabled) DebugTimer->startTimer(); @@ -3465,9 +3506,16 @@ DIGlobalVariable DG(GV); Scope = getOrCreateScope(DG.getContext().getGV()); } else { + DenseMap::iterator + SI = InlinedVariableScopes.find(MI); + if (SI != InlinedVariableScopes.end()) { + // or GV is an inlined local variable. + Scope = SI->second; + } else { // or GV is a local variable. - DIVariable DV(GV); - Scope = getOrCreateScope(DV.getContext().getGV()); + DIVariable DV(GV); + Scope = getOrCreateScope(DV.getContext().getGV()); + } } assert(Scope && "Unable to find variable' scope"); @@ -3478,10 +3526,28 @@ DebugTimer->stopTimer(); } - //// RecordInlineInfo - Global variable GV is inlined at the location marked - //// by LabelID label. - void RecordInlineInfo(GlobalVariable *GV, unsigned LabelID) { + //// RecordInlinedFnStart - Indicate the start of inlined subroutine. + void RecordInlinedFnStart(Instruction *FSI, DISubprogram &SP, unsigned LabelID, + unsigned Src, unsigned Line, unsigned Col) { + if (!TAI->doesDwarfUsesInlineInfoSection()) + return; + + DbgScope *Scope = createInlinedSubroutineScope(SP, Src, Line, Col); + Scope->setStartLabelID(LabelID); MMI->RecordUsedDbgLabel(LabelID); + GlobalVariable *GV = SP.getGV(); + + DenseMap >::iterator + SI = DbgInlinedScopeMap.find(GV); + if (SI == DbgInlinedScopeMap.end()) { + SmallVector Scopes; + Scopes.push_back(Scope); + DbgInlinedScopeMap[GV] = Scopes; + } else { + SmallVector &Scopes = SI->second; + Scopes.push_back(Scope); + } + DenseMap >::iterator I = InlineInfo.find(GV); if (I == InlineInfo.end()) { @@ -3494,6 +3560,43 @@ SmallVector &Labels = I->second; Labels.push_back(LabelID); } + + /// RecordInlinedFnEnd - Indicate the end of inlined subroutine. + unsigned RecordInlinedFnEnd(DISubprogram &SP) { + if (!TAI->doesDwarfUsesInlineInfoSection()) + return 0; + + GlobalVariable *GV = SP.getGV(); + DenseMap >::iterator + I = DbgInlinedScopeMap.find(GV); + if (I == DbgInlinedScopeMap.end()) + return 0; + + SmallVector &Scopes = I->second; + DbgScope *Scope = Scopes.back(); Scopes.pop_back(); + unsigned ID = MMI->NextLabelID(); + MMI->RecordUsedDbgLabel(ID); + Scope->setEndLabelID(ID); + return ID; + } + + /// RecordVariableScope - Record scope for the variable declared by + /// DeclareMI. DeclareMI must describe TargetInstrInfo::DECLARE. + /// Record scopes for only inlined subroutine variables. Other + /// variables' scopes are determined during RecordVariable(). + void RecordVariableScope(DIVariable &DV, const MachineInstr *DeclareMI) { + DISubprogram SP(DV.getContext().getGV()); + if (SP.isNull()) + return; + DenseMap >::iterator + I = DbgInlinedScopeMap.find(SP.getGV()); + if (I == DbgInlinedScopeMap.end()) + return; + + SmallVector &Scopes = I->second; + InlinedVariableScopes[DeclareMI] = Scopes.back(); + } + }; //===----------------------------------------------------------------------===// @@ -4652,11 +4755,6 @@ return DD->RecordRegionStart(V); } -/// RecordRegionStart - Indicate the start of a region. -unsigned DwarfWriter::RecordRegionStart(GlobalVariable *V, unsigned ID) { - return DD->RecordRegionStart(V, ID); -} - /// RecordRegionEnd - Indicate the end of a region. unsigned DwarfWriter::RecordRegionEnd(GlobalVariable *V) { return DD->RecordRegionEnd(V); @@ -4669,8 +4767,9 @@ /// RecordVariable - Indicate the declaration of a local variable. /// -void DwarfWriter::RecordVariable(GlobalVariable *GV, unsigned FrameIndex) { - DD->RecordVariable(GV, FrameIndex); +void DwarfWriter::RecordVariable(GlobalVariable *GV, unsigned FrameIndex, + const MachineInstr *MI) { + DD->RecordVariable(GV, FrameIndex, MI); } /// ShouldEmitDwarfDebug - Returns true if Dwarf debugging declarations should @@ -4679,9 +4778,22 @@ return DD->ShouldEmitDwarfDebug(); } -//// RecordInlineInfo - Global variable GV is inlined at the location marked +//// RecordInlinedFnStart - Global variable GV is inlined at the location marked //// by LabelID label. -void DwarfWriter::RecordInlineInfo(GlobalVariable *GV, unsigned LabelID) { - DD->RecordInlineInfo(GV, LabelID); +void DwarfWriter::RecordInlinedFnStart(Instruction *I, DISubprogram &SP, + unsigned LabelID, unsigned Src, + unsigned Line, unsigned Col) { + DD->RecordInlinedFnStart(I, SP, LabelID, Src, Line, Col); +} + +/// RecordInlinedFnEnd - Indicate the end of inlined subroutine. +unsigned DwarfWriter::RecordInlinedFnEnd(DISubprogram &SP) { + return DD->RecordInlinedFnEnd(SP); +} + +/// RecordVariableScope - Record scope for the variable declared by +/// DeclareMI. DeclareMI must describe TargetInstrInfo::DECLARE. +void DwarfWriter::RecordVariableScope(DIVariable &DV, + const MachineInstr *DeclareMI) { + DD->RecordVariableScope(DV, DeclareMI); } - Modified: llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp?rev=69116&r1=69115&r2=69116&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp Tue Apr 14 19:10:26 2009 @@ -47,6 +47,7 @@ #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/DebugLoc.h" #include "llvm/CodeGen/DwarfWriter.h" #include "llvm/Analysis/DebugInfo.h" #include "llvm/Target/TargetData.h" @@ -354,10 +355,18 @@ case Intrinsic::dbg_region_end: { DbgRegionEndInst *REI = cast(I); if (DW && DW->ValidDebugInfo(REI->getContext(), true)) { - unsigned ID = - DW->RecordRegionEnd(cast(REI->getContext())); - const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL); - BuildMI(MBB, DL, II).addImm(ID); + unsigned ID = 0; + DISubprogram Subprogram(cast(REI->getContext())); + if (!Subprogram.describes(MF.getFunction())) { + // This is end of an inlined function. + const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL); + ID = DW->RecordInlinedFnEnd(Subprogram); + BuildMI(MBB, DL, II).addImm(ID); + } else { + const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL); + ID = DW->RecordRegionEnd(cast(REI->getContext())); + BuildMI(MBB, DL, II).addImm(ID); + } } return true; } @@ -369,6 +378,7 @@ if (DW->ValidDebugInfo(SP, true)) { // llvm.dbg.func.start implicitly defines a dbg_stoppoint which is what // (most?) gdb expects. + DebugLoc PrevLoc = DL; DISubprogram Subprogram(cast(SP)); DICompileUnit CompileUnit = Subprogram.getCompileUnit(); std::string Dir, FN; @@ -379,17 +389,15 @@ unsigned Line = Subprogram.getLineNumber(); unsigned LabelID = DW->RecordSourceLine(Line, 0, SrcFile); setCurDebugLoc(DebugLoc::get(MF.getOrCreateDebugLocID(SrcFile, Line, 0))); - - std::string SPName; - Subprogram.getLinkageName(SPName); - if (!SPName.empty() - && strcmp(SPName.c_str(), MF.getFunction()->getNameStart())) { - // This is a beginning of inlined function. - DW->RecordRegionStart(cast(FSI->getSubprogram()), - LabelID); + if (!Subprogram.describes(MF.getFunction())) { + // This is a beginning of an inlined function. const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL); BuildMI(MBB, DL, II).addImm(LabelID); - DW->RecordInlineInfo(Subprogram.getGV(), LabelID); + DebugLocTuple PrevLocTpl = MF.getDebugLocTuple(PrevLoc); + DW->RecordInlinedFnStart(FSI, Subprogram, LabelID, + PrevLocTpl.Src, + PrevLocTpl.Line, + PrevLocTpl.Col); } else { // llvm.dbg.func_start also defines beginning of function scope. DW->RecordRegionStart(cast(FSI->getSubprogram())); @@ -419,7 +427,13 @@ // Build the DECLARE instruction. const TargetInstrDesc &II = TII.get(TargetInstrInfo::DECLARE); - BuildMI(MBB, DL, II).addFrameIndex(FI).addGlobalAddress(GV); + MachineInstr *DeclareMI + = BuildMI(MBB, DL, II).addFrameIndex(FI).addGlobalAddress(GV); + DIVariable DV(cast(GV)); + if (!DV.isNull()) { + // This is a local variable + DW->RecordVariableScope(DV, DeclareMI); + } } return true; } From clattner at apple.com Tue Apr 14 19:14:35 2009 From: clattner at apple.com (Chris Lattner) Date: Tue, 14 Apr 2009 17:14:35 -0700 Subject: [llvm-commits] [llvm] r69102 - in /llvm/trunk: lib/Transforms/Scalar/CondPropagate.cpp test/Transforms/CondProp/phisimplify3.ll In-Reply-To: <200904142340.n3ENe4FD020265@zion.cs.uiuc.edu> References: <200904142340.n3ENe4FD020265@zion.cs.uiuc.edu> Message-ID: <8415EB33-DFD9-447C-AEDE-22F6E57FE63B@apple.com> On Apr 14, 2009, at 4:40 PM, Evan Cheng wrote: > Author: evancheng > Date: Tue Apr 14 18:40:03 2009 > New Revision: 69102 > > URL: http://llvm.org/viewvc/llvm-project?rev=69102&view=rev > Log: > Optimize conditional branch on i1 phis with non-constant inputs. > > This turns: > > eq: > %3 = icmp eq i32 %1, %2 > br label %join > > ne: > %4 = icmp ne i32 %1, %2 > br label %join > > join: > %5 = phi i1 [%3, %eq], [%4, %ne] > br i1 %5, label %yes, label %no Cool. I didn't scrutinize the code, but does this handle the case (or avoid transforming) when "yes" or "no" have phi nodes? This will add new preds, so phi nodes in them would need to be updated. -Chris > > > => > > eq: > %3 = icmp eq i32 %1, %2 > br i1 %3, label %yes, label %no > > ne: > %4 = icmp ne i32 %1, %2 > br i1 %4, label %yes, label %no > > Added: > llvm/trunk/test/Transforms/CondProp/phisimplify3.ll > Modified: > llvm/trunk/lib/Transforms/Scalar/CondPropagate.cpp > > Modified: llvm/trunk/lib/Transforms/Scalar/CondPropagate.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CondPropagate.cpp?rev=69102&r1=69101&r2=69102&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Transforms/Scalar/CondPropagate.cpp (original) > +++ llvm/trunk/lib/Transforms/Scalar/CondPropagate.cpp Tue Apr 14 > 18:40:03 2009 > @@ -51,6 +51,7 @@ > void SimplifyPredecessors(BranchInst *BI); > void SimplifyPredecessors(SwitchInst *SI); > void RevectorBlockTo(BasicBlock *FromBB, BasicBlock *ToBB); > + bool RevectorBlockTo(BasicBlock *FromBB, Value *Cond, > BranchInst *BI); > }; > } > > @@ -160,20 +161,19 @@ > // Ok, we have this really simple case, walk the PHI operands, > looking for > // constants. Walk from the end to remove operands from the end > when > // possible, and to avoid invalidating "i". > - for (unsigned i = PN->getNumIncomingValues(); i != 0; --i) > - if (ConstantInt *CB = dyn_cast(PN- > >getIncomingValue(i-1))) { > - // If we have a constant, forward the edge from its current > to its > - // ultimate destination. > - RevectorBlockTo(PN->getIncomingBlock(i-1), > - BI->getSuccessor(CB->isZero())); > - ++NumBrThread; > - > - // If there were two predecessors before this simplification, > or if the > - // PHI node contained all the same value except for the one > we just > - // substituted, the PHI node may be deleted. Don't iterate > through it the > - // last time. > - if (BI->getCondition() != PN) return; > - } > + for (unsigned i = PN->getNumIncomingValues(); i != 0; --i) { > + Value *InVal = PN->getIncomingValue(i-1); > + if (!RevectorBlockTo(PN->getIncomingBlock(i-1), InVal, BI)) > + continue; > + > + ++NumBrThread; > + > + // If there were two predecessors before this simplification, > or if the > + // PHI node contained all the same value except for the one we > just > + // substituted, the PHI node may be deleted. Don't iterate > through it the > + // last time. > + if (BI->getCondition() != PN) return; > + } > } > > // SimplifyPredecessors(switch) - We know that SI is switch based on > a PHI node > @@ -242,3 +242,44 @@ > > MadeChange = true; > } > + > +bool CondProp::RevectorBlockTo(BasicBlock *FromBB, Value *Cond, > BranchInst *BI){ > + BranchInst *FromBr = cast(FromBB->getTerminator()); > + if (!FromBr->isUnconditional()) > + return false; > + > + // Get the old block we are threading through. > + BasicBlock *OldSucc = FromBr->getSuccessor(0); > + > + // If the condition is a constant, simply revector the > unconditional branch at > + // the end of FromBB to one of the successors of its current > successor. > + if (ConstantInt *CB = dyn_cast(Cond)) { > + BasicBlock *ToBB = BI->getSuccessor(CB->isZero()); > + > + // OldSucc had multiple successors. If ToBB has multiple > predecessors, then > + // the edge between them would be critical, which we already > took care of. > + // If ToBB has single operand PHI node then take care of it here. > + FoldSingleEntryPHINodes(ToBB); > + > + // Update PHI nodes in OldSucc to know that FromBB no longer > branches to it. > + OldSucc->removePredecessor(FromBB); > + > + // Change FromBr to branch to the new destination. > + FromBr->setSuccessor(0, ToBB); > + } else { > + // Insert the new conditional branch. > + BranchInst::Create(BI->getSuccessor(0), BI->getSuccessor(1), > Cond, FromBr); > + > + FoldSingleEntryPHINodes(BI->getSuccessor(0)); > + FoldSingleEntryPHINodes(BI->getSuccessor(1)); > + > + // Update PHI nodes in OldSucc to know that FromBB no longer > branches to it. > + OldSucc->removePredecessor(FromBB); > + > + // Delete the old branch. > + FromBr->eraseFromParent(); > + } > + > + MadeChange = true; > + return true; > +} > > Added: llvm/trunk/test/Transforms/CondProp/phisimplify3.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/CondProp/phisimplify3.ll?rev=69102&view=auto > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/test/Transforms/CondProp/phisimplify3.ll (added) > +++ llvm/trunk/test/Transforms/CondProp/phisimplify3.ll Tue Apr 14 > 18:40:03 2009 > @@ -0,0 +1,26 @@ > +; RUN: llvm-as < %s | opt -condprop | llvm-dis | not grep phi > + > +define i32 @foo(i1, i32, i32) { > +prologue: > + br i1 %0, label %eq, label %ne > + > +eq: ; preds = %prologue > + store i32 0, i32* inttoptr (i32 10000 to i32*) > + %3 = icmp eq i32 %1, %2 ; [#uses=1] > + br label %join > + > +ne: ; preds = %prologue > + %4 = icmp ne i32 %1, %2 ; [#uses=1] > + br label %join > + > +join: ; preds = %ne, %eq > + %5 = phi i1 [ %3, %eq ], [ %4, %ne ] ; [#uses=1] > + br i1 %5, label %yes, label %no > + > +yes: ; preds = %join > + store i32 0, i32* inttoptr (i32 20000 to i32*) > + ret i32 5 > + > +no: ; preds = %join > + ret i32 20 > +} > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From sabre at nondot.org Tue Apr 14 19:16:05 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 15 Apr 2009 00:16:05 -0000 Subject: [llvm-commits] [llvm] r69117 - /llvm/trunk/examples/Kaleidoscope/toy.cpp Message-ID: <200904150016.n3F0G5Uo021592@zion.cs.uiuc.edu> Author: lattner Date: Tue Apr 14 19:16:05 2009 New Revision: 69117 URL: http://llvm.org/viewvc/llvm-project?rev=69117&view=rev Log: silence a warning. Modified: llvm/trunk/examples/Kaleidoscope/toy.cpp Modified: llvm/trunk/examples/Kaleidoscope/toy.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/Kaleidoscope/toy.cpp?rev=69117&r1=69116&r2=69117&view=diff ============================================================================== --- llvm/trunk/examples/Kaleidoscope/toy.cpp (original) +++ llvm/trunk/examples/Kaleidoscope/toy.cpp Tue Apr 14 19:16:05 2009 @@ -1033,7 +1033,7 @@ // Cast it to the right type (takes no arguments, returns a double) so we // can call it as a native function. - double (*FP)() = (double (*)())FPtr; + double (*FP)() = (double (*)())(intptr_t)FPtr; fprintf(stderr, "Evaluated to %f\n", FP()); } } else { From dpatel at apple.com Tue Apr 14 19:17:06 2009 From: dpatel at apple.com (Devang Patel) Date: Wed, 15 Apr 2009 00:17:06 -0000 Subject: [llvm-commits] [llvm] r69118 - in /llvm/trunk: lib/Transforms/Utils/CloneFunction.cpp lib/Transforms/Utils/InlineFunction.cpp test/Transforms/Inline/llvm.dbg.func.start.ll Message-ID: <200904150017.n3F0H6IV021636@zion.cs.uiuc.edu> Author: dpatel Date: Tue Apr 14 19:17:06 2009 New Revision: 69118 URL: http://llvm.org/viewvc/llvm-project?rev=69118&view=rev Log: While inlining, clone llvm.dbg.func.start intrinsic and adjust llvm.dbg.region.end instrinsic. This nested llvm.dbg.func.start/llvm.dbg.region.end pair now enables DW_TAG_inlined_subroutine support in code generator. Removed: llvm/trunk/test/Transforms/Inline/llvm.dbg.func.start.ll Modified: llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp Modified: llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp?rev=69118&r1=69117&r2=69118&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp Tue Apr 14 19:17:06 2009 @@ -24,6 +24,7 @@ #include "llvm/Support/Compiler.h" #include "llvm/Transforms/Utils/ValueMapper.h" #include "llvm/Analysis/ConstantFolding.h" +#include "llvm/Analysis/DebugInfo.h" #include "llvm/ADT/SmallVector.h" #include using namespace llvm; @@ -233,10 +234,13 @@ continue; } - // Do not clone llvm.dbg.func.start and corresponding llvm.dbg.region.end. + // Do not clone llvm.dbg.region.end. It will be adjusted by the inliner. if (const DbgFuncStartInst *DFSI = dyn_cast(II)) { - DbgFnStart = DFSI->getSubprogram(); - continue; + if (DbgFnStart == NULL) { + DISubprogram SP(cast(DFSI->getSubprogram())); + if (SP.describes(BB->getParent())) + DbgFnStart = DFSI->getSubprogram(); + } } if (const DbgRegionEndInst *DREIS = dyn_cast(II)) { if (DREIS->getContext() == DbgFnStart) Modified: llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp?rev=69118&r1=69117&r2=69118&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp Tue Apr 14 19:17:06 2009 @@ -17,9 +17,11 @@ #include "llvm/DerivedTypes.h" #include "llvm/Module.h" #include "llvm/Instructions.h" +#include "llvm/IntrinsicInst.h" #include "llvm/Intrinsics.h" #include "llvm/Attributes.h" #include "llvm/Analysis/CallGraph.h" +#include "llvm/Analysis/DebugInfo.h" #include "llvm/Target/TargetData.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" @@ -199,6 +201,31 @@ CallerNode->removeCallEdgeFor(CS); } +/// findFnRegionEndMarker - This is a utility routine that is used by +/// InlineFunction. Return llvm.dbg.region.end intrinsic that corresponds +/// to the llvm.dbg.func.start of the function F. Otherwise return NULL. +static const DbgRegionEndInst *findFnRegionEndMarker(const Function *F) { + + GlobalVariable *FnStart = NULL; + const DbgRegionEndInst *FnEnd = NULL; + for (Function::const_iterator FI = F->begin(), FE =F->end(); FI != FE; ++FI) + for (BasicBlock::const_iterator BI = FI->begin(), BE = FI->end(); BI != BE; + ++BI) { + if (FnStart == NULL) { + if (const DbgFuncStartInst *FSI = dyn_cast(BI)) { + DISubprogram SP(cast(FSI->getSubprogram())); + assert (SP.isNull() == false && "Invalid llvm.dbg.func.start"); + if (SP.describes(F)) + FnStart = SP.getGV(); + } + } else { + if (const DbgRegionEndInst *REI = dyn_cast(BI)) + if (REI->getContext() == FnStart) + FnEnd = REI; + } + } + return FnEnd; +} // InlineFunction - This function inlines the called function into the basic // block of the caller. This returns false if it is not possible to inline this @@ -320,6 +347,24 @@ ValueMap[I] = ActualArg; } + // Adjust llvm.dbg.region.end. If the CalledFunc has region end + // marker then clone that marker after next stop point at the + // call site. The function body cloner does not clone original + // region end marker from the CalledFunc. This will ensure that + // inlined function's scope ends at the right place. + const DbgRegionEndInst *DREI = findFnRegionEndMarker(CalledFunc); + if (DREI) { + for (BasicBlock::iterator BI = TheCall, + BE = TheCall->getParent()->end(); BI != BE; ++BI) { + if (DbgStopPointInst *DSPI = dyn_cast(BI)) { + if (DbgRegionEndInst *NewDREI = + dyn_cast(DREI->clone())) + NewDREI->insertAfter(DSPI); + break; + } + } + } + // We want the inliner to prune the code as it copies. We would LOVE to // have no dead or constant instructions leftover after inlining occurs // (which can happen, e.g., because an argument was constant), but we'll be Removed: llvm/trunk/test/Transforms/Inline/llvm.dbg.func.start.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/Inline/llvm.dbg.func.start.ll?rev=69117&view=auto ============================================================================== --- llvm/trunk/test/Transforms/Inline/llvm.dbg.func.start.ll (original) +++ llvm/trunk/test/Transforms/Inline/llvm.dbg.func.start.ll (removed) @@ -1,86 +0,0 @@ -; RUN: llvm-as < %s | opt -inline | llvm-dis | grep func.start | count 3 -; RUN: llvm-as < %s | opt -inline | llvm-dis | grep region.end | count 3 - %llvm.dbg.anchor.type = type { i32, i32 } - %llvm.dbg.basictype.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, i32 } - %llvm.dbg.compile_unit.type = type { i32, { }*, i32, i8*, i8*, i8*, i1, i1, i8* } - %llvm.dbg.composite.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, { }*, { }* } - %llvm.dbg.derivedtype.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, { }* } - %llvm.dbg.subprogram.type = type { i32, { }*, { }*, i8*, i8*, i8*, { }*, i32, { }*, i1, i1 } - %llvm.dbg.variable.type = type { i32, { }*, i8*, { }*, i32, { }* } - at llvm.dbg.compile_units = linkonce constant %llvm.dbg.anchor.type { i32 458752, i32 17 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1] - at .str = internal constant [4 x i8] c"a.c\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1] - at .str1 = internal constant [6 x i8] c"/tmp/\00", section "llvm.metadata" ; <[6 x i8]*> [#uses=1] - at .str2 = internal constant [55 x i8] c"4.2.1 (Based on Apple Inc. build 5636) (LLVM build 00)\00", section "llvm.metadata" ; <[55 x i8]*> [#uses=1] - at llvm.dbg.compile_unit = internal constant %llvm.dbg.compile_unit.type { i32 458769, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to { }*), i32 1, i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([6 x i8]* @.str1, i32 0, i32 0), i8* getelementptr ([55 x i8]* @.str2, i32 0, i32 0), i1 true, i1 false, i8* null }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1] - at .str3 = internal constant [4 x i8] c"int\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1] - at llvm.dbg.basictype = internal constant %llvm.dbg.basictype.type { i32 458788, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([4 x i8]* @.str3, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 32, i64 32, i64 0, i32 0, i32 5 }, section "llvm.metadata" ; <%llvm.dbg.basictype.type*> [#uses=1] - at .str4 = internal constant [5 x i8] c"char\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1] - at llvm.dbg.basictype5 = internal constant %llvm.dbg.basictype.type { i32 458788, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([5 x i8]* @.str4, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 8, i64 8, i64 0, i32 0, i32 6 }, section "llvm.metadata" ; <%llvm.dbg.basictype.type*> [#uses=1] - at llvm.dbg.derivedtype = internal constant %llvm.dbg.derivedtype.type { i32 458767, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 32, i64 32, i64 0, i32 0, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype5 to { }*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1] - at llvm.dbg.array = internal constant [2 x { }*] [ { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype to { }*) ], section "llvm.metadata" ; <[2 x { }*]*> [#uses=1] - at llvm.dbg.composite = internal constant %llvm.dbg.composite.type { i32 458773, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 0, i64 0, i64 0, i32 0, { }* null, { }* bitcast ([2 x { }*]* @llvm.dbg.array to { }*) }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1] - at llvm.dbg.subprograms = linkonce constant %llvm.dbg.anchor.type { i32 458752, i32 46 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1] - at .str6 = internal constant [4 x i8] c"bar\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1] - at llvm.dbg.subprogram = internal constant %llvm.dbg.subprogram.type { i32 458798, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([4 x i8]* @.str6, i32 0, i32 0), i8* getelementptr ([4 x i8]* @.str6, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 1, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite to { }*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1] - at .str7 = internal constant [2 x i8] c"c\00", section "llvm.metadata" ; <[2 x i8]*> [#uses=1] - at llvm.dbg.variable = internal constant %llvm.dbg.variable.type { i32 459009, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*), i8* getelementptr ([2 x i8]* @.str7, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 1, { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype to { }*) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1] - at llvm.dbg.array8 = internal constant [1 x { }*] [ { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*) ], section "llvm.metadata" ; <[1 x { }*]*> [#uses=1] - at llvm.dbg.composite9 = internal constant %llvm.dbg.composite.type { i32 458773, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 0, i64 0, i64 0, i32 0, { }* null, { }* bitcast ([1 x { }*]* @llvm.dbg.array8 to { }*) }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1] - at .str10 = internal constant [5 x i8] c"main\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1] - at llvm.dbg.subprogram11 = internal constant %llvm.dbg.subprogram.type { i32 458798, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([5 x i8]* @.str10, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str10, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 2, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite9 to { }*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1] -@"\01LC" = internal constant [3 x i8] c"hi\00" ; <[3 x i8]*> [#uses=1] - -define i32 @bar(i8* %c) nounwind { -entry: - %c_addr = alloca i8* ; [#uses=3] - %retval = alloca i32 ; [#uses=2] - %0 = alloca i32 ; [#uses=2] - %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] - call void @llvm.dbg.func.start({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*)) - %1 = bitcast i8** %c_addr to { }* ; <{ }*> [#uses=1] - call void @llvm.dbg.declare({ }* %1, { }* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable to { }*)) - store i8* %c, i8** %c_addr - call void @llvm.dbg.stoppoint(i32 1, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - %2 = load i8** %c_addr, align 4 ; [#uses=1] - %3 = load i8* %2, align 1 ; [#uses=1] - %4 = sext i8 %3 to i32 ; [#uses=1] - %5 = add i32 %4, 42 ; [#uses=1] - store i32 %5, i32* %0, align 4 - %6 = load i32* %0, align 4 ; [#uses=1] - store i32 %6, i32* %retval, align 4 - br label %return - -return: ; preds = %entry - %retval1 = load i32* %retval ; [#uses=1] - call void @llvm.dbg.stoppoint(i32 1, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - call void @llvm.dbg.region.end({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*)) - ret i32 %retval1 -} - -declare void @llvm.dbg.func.start({ }*) nounwind - -declare void @llvm.dbg.declare({ }*, { }*) nounwind - -declare void @llvm.dbg.stoppoint(i32, i32, { }*) nounwind - -declare void @llvm.dbg.region.end({ }*) nounwind - -define i32 @main() nounwind { -entry: - %retval = alloca i32 ; [#uses=2] - %0 = alloca i32 ; [#uses=2] - %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] - call void @llvm.dbg.func.start({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram11 to { }*)) - call void @llvm.dbg.stoppoint(i32 2, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - %1 = call i32 @bar(i8* getelementptr ([3 x i8]* @"\01LC", i32 0, i32 0)) nounwind ; [#uses=1] - store i32 %1, i32* %0, align 4 - %2 = load i32* %0, align 4 ; [#uses=1] - store i32 %2, i32* %retval, align 4 - br label %return - -return: ; preds = %entry - %retval1 = load i32* %retval ; [#uses=1] - call void @llvm.dbg.stoppoint(i32 2, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - call void @llvm.dbg.region.end({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram11 to { }*)) - ret i32 %retval1 -} From gohman at apple.com Tue Apr 14 19:32:45 2009 From: gohman at apple.com (Dan Gohman) Date: Wed, 15 Apr 2009 00:32:45 -0000 Subject: [llvm-commits] [test-suite] r69120 - /test-suite/trunk/External/HMMER/Makefile Message-ID: <200904150032.n3F0Wmvr022140@zion.cs.uiuc.edu> Author: djg Date: Tue Apr 14 19:32:41 2009 New Revision: 69120 URL: http://llvm.org/viewvc/llvm-project?rev=69120&view=rev Log: HMMER uses pthreads, so it needs -lpthread. Modified: test-suite/trunk/External/HMMER/Makefile Modified: test-suite/trunk/External/HMMER/Makefile URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/External/HMMER/Makefile?rev=69120&r1=69119&r2=69120&view=diff ============================================================================== --- test-suite/trunk/External/HMMER/Makefile (original) +++ test-suite/trunk/External/HMMER/Makefile Tue Apr 14 19:32:41 2009 @@ -6,6 +6,8 @@ SourceDir := $(HMMER_ROOT) CPPFLAGS = -DSSE2 +LIBS += -lpthread +LDFLAGS += -lpthread ifdef LARGE_PROBLEM_SIZE RUN_OPTIONS = --fixed 400 --cpu 1 --num 200000 --seed 1158818515 $(HMMER_ROOT)/globin.hmm From evan.cheng at apple.com Tue Apr 14 19:44:05 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 15 Apr 2009 00:44:05 -0000 Subject: [llvm-commits] [llvm] r69121 - /llvm/trunk/lib/Transforms/Scalar/CondPropagate.cpp Message-ID: <200904150044.n3F0iBu1022498@zion.cs.uiuc.edu> Author: evancheng Date: Tue Apr 14 19:43:54 2009 New Revision: 69121 URL: http://llvm.org/viewvc/llvm-project?rev=69121&view=rev Log: Avoid making the transformation enabled by my last patch if the new destinations have phi nodes. Modified: llvm/trunk/lib/Transforms/Scalar/CondPropagate.cpp Modified: llvm/trunk/lib/Transforms/Scalar/CondPropagate.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CondPropagate.cpp?rev=69121&r1=69120&r2=69121&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/CondPropagate.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/CondPropagate.cpp Tue Apr 14 19:43:54 2009 @@ -267,11 +267,21 @@ // Change FromBr to branch to the new destination. FromBr->setSuccessor(0, ToBB); } else { + BasicBlock *Succ0 = BI->getSuccessor(0); + // Do not perform transform if the new destination has PHI nodes. The + // transform will add new preds to the PHI's. + if (isa(Succ0->begin())) + return false; + + BasicBlock *Succ1 = BI->getSuccessor(1); + if (isa(Succ1->begin())) + return false; + // Insert the new conditional branch. - BranchInst::Create(BI->getSuccessor(0), BI->getSuccessor(1), Cond, FromBr); + BranchInst::Create(Succ0, Succ1, Cond, FromBr); - FoldSingleEntryPHINodes(BI->getSuccessor(0)); - FoldSingleEntryPHINodes(BI->getSuccessor(1)); + FoldSingleEntryPHINodes(Succ0); + FoldSingleEntryPHINodes(Succ1); // Update PHI nodes in OldSucc to know that FromBB no longer branches to it. OldSucc->removePredecessor(FromBB); From evan.cheng at apple.com Tue Apr 14 19:45:05 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 14 Apr 2009 17:45:05 -0700 Subject: [llvm-commits] [llvm] r69102 - in /llvm/trunk: lib/Transforms/Scalar/CondPropagate.cpp test/Transforms/CondProp/phisimplify3.ll In-Reply-To: <8415EB33-DFD9-447C-AEDE-22F6E57FE63B@apple.com> References: <200904142340.n3ENe4FD020265@zion.cs.uiuc.edu> <8415EB33-DFD9-447C-AEDE-22F6E57FE63B@apple.com> Message-ID: Thanks. Fixed. Evan On Apr 14, 2009, at 5:14 PM, Chris Lattner wrote: > > On Apr 14, 2009, at 4:40 PM, Evan Cheng wrote: > >> Author: evancheng >> Date: Tue Apr 14 18:40:03 2009 >> New Revision: 69102 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=69102&view=rev >> Log: >> Optimize conditional branch on i1 phis with non-constant inputs. >> >> This turns: >> >> eq: >> %3 = icmp eq i32 %1, %2 >> br label %join >> >> ne: >> %4 = icmp ne i32 %1, %2 >> br label %join >> >> join: >> %5 = phi i1 [%3, %eq], [%4, %ne] >> br i1 %5, label %yes, label %no > > Cool. I didn't scrutinize the code, but does this handle the case (or > avoid transforming) when "yes" or "no" have phi nodes? This will add > new preds, so phi nodes in them would need to be updated. > > -Chris > >> >> >> => >> >> eq: >> %3 = icmp eq i32 %1, %2 >> br i1 %3, label %yes, label %no >> >> ne: >> %4 = icmp ne i32 %1, %2 >> br i1 %4, label %yes, label %no >> >> Added: >> llvm/trunk/test/Transforms/CondProp/phisimplify3.ll >> Modified: >> llvm/trunk/lib/Transforms/Scalar/CondPropagate.cpp >> >> Modified: llvm/trunk/lib/Transforms/Scalar/CondPropagate.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CondPropagate.cpp?rev=69102&r1=69101&r2=69102&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm/trunk/lib/Transforms/Scalar/CondPropagate.cpp (original) >> +++ llvm/trunk/lib/Transforms/Scalar/CondPropagate.cpp Tue Apr 14 >> 18:40:03 2009 >> @@ -51,6 +51,7 @@ >> void SimplifyPredecessors(BranchInst *BI); >> void SimplifyPredecessors(SwitchInst *SI); >> void RevectorBlockTo(BasicBlock *FromBB, BasicBlock *ToBB); >> + bool RevectorBlockTo(BasicBlock *FromBB, Value *Cond, >> BranchInst *BI); >> }; >> } >> >> @@ -160,20 +161,19 @@ >> // Ok, we have this really simple case, walk the PHI operands, >> looking for >> // constants. Walk from the end to remove operands from the end >> when >> // possible, and to avoid invalidating "i". >> - for (unsigned i = PN->getNumIncomingValues(); i != 0; --i) >> - if (ConstantInt *CB = dyn_cast(PN- >>> getIncomingValue(i-1))) { >> - // If we have a constant, forward the edge from its current >> to its >> - // ultimate destination. >> - RevectorBlockTo(PN->getIncomingBlock(i-1), >> - BI->getSuccessor(CB->isZero())); >> - ++NumBrThread; >> - >> - // If there were two predecessors before this simplification, >> or if the >> - // PHI node contained all the same value except for the one >> we just >> - // substituted, the PHI node may be deleted. Don't iterate >> through it the >> - // last time. >> - if (BI->getCondition() != PN) return; >> - } >> + for (unsigned i = PN->getNumIncomingValues(); i != 0; --i) { >> + Value *InVal = PN->getIncomingValue(i-1); >> + if (!RevectorBlockTo(PN->getIncomingBlock(i-1), InVal, BI)) >> + continue; >> + >> + ++NumBrThread; >> + >> + // If there were two predecessors before this simplification, >> or if the >> + // PHI node contained all the same value except for the one we >> just >> + // substituted, the PHI node may be deleted. Don't iterate >> through it the >> + // last time. >> + if (BI->getCondition() != PN) return; >> + } >> } >> >> // SimplifyPredecessors(switch) - We know that SI is switch based on >> a PHI node >> @@ -242,3 +242,44 @@ >> >> MadeChange = true; >> } >> + >> +bool CondProp::RevectorBlockTo(BasicBlock *FromBB, Value *Cond, >> BranchInst *BI){ >> + BranchInst *FromBr = cast(FromBB->getTerminator()); >> + if (!FromBr->isUnconditional()) >> + return false; >> + >> + // Get the old block we are threading through. >> + BasicBlock *OldSucc = FromBr->getSuccessor(0); >> + >> + // If the condition is a constant, simply revector the >> unconditional branch at >> + // the end of FromBB to one of the successors of its current >> successor. >> + if (ConstantInt *CB = dyn_cast(Cond)) { >> + BasicBlock *ToBB = BI->getSuccessor(CB->isZero()); >> + >> + // OldSucc had multiple successors. If ToBB has multiple >> predecessors, then >> + // the edge between them would be critical, which we already >> took care of. >> + // If ToBB has single operand PHI node then take care of it >> here. >> + FoldSingleEntryPHINodes(ToBB); >> + >> + // Update PHI nodes in OldSucc to know that FromBB no longer >> branches to it. >> + OldSucc->removePredecessor(FromBB); >> + >> + // Change FromBr to branch to the new destination. >> + FromBr->setSuccessor(0, ToBB); >> + } else { >> + // Insert the new conditional branch. >> + BranchInst::Create(BI->getSuccessor(0), BI->getSuccessor(1), >> Cond, FromBr); >> + >> + FoldSingleEntryPHINodes(BI->getSuccessor(0)); >> + FoldSingleEntryPHINodes(BI->getSuccessor(1)); >> + >> + // Update PHI nodes in OldSucc to know that FromBB no longer >> branches to it. >> + OldSucc->removePredecessor(FromBB); >> + >> + // Delete the old branch. >> + FromBr->eraseFromParent(); >> + } >> + >> + MadeChange = true; >> + return true; >> +} >> >> Added: llvm/trunk/test/Transforms/CondProp/phisimplify3.ll >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/CondProp/phisimplify3.ll?rev=69102&view=auto >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm/trunk/test/Transforms/CondProp/phisimplify3.ll (added) >> +++ llvm/trunk/test/Transforms/CondProp/phisimplify3.ll Tue Apr 14 >> 18:40:03 2009 >> @@ -0,0 +1,26 @@ >> +; RUN: llvm-as < %s | opt -condprop | llvm-dis | not grep phi >> + >> +define i32 @foo(i1, i32, i32) { >> +prologue: >> + br i1 %0, label %eq, label %ne >> + >> +eq: ; preds = %prologue >> + store i32 0, i32* inttoptr (i32 10000 to i32*) >> + %3 = icmp eq i32 %1, %2 ; [#uses=1] >> + br label %join >> + >> +ne: ; preds = %prologue >> + %4 = icmp ne i32 %1, %2 ; [#uses=1] >> + br label %join >> + >> +join: ; preds = %ne, %eq >> + %5 = phi i1 [ %3, %eq ], [ %4, %ne ] ; [#uses=1] >> + br i1 %5, label %yes, label %no >> + >> +yes: ; preds = %join >> + store i32 0, i32* inttoptr (i32 20000 to i32*) >> + ret i32 5 >> + >> +no: ; preds = %join >> + ret i32 20 >> +} >> >> >> _______________________________________________ >> 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 dalej at apple.com Tue Apr 14 20:10:13 2009 From: dalej at apple.com (Dale Johannesen) Date: Wed, 15 Apr 2009 01:10:13 -0000 Subject: [llvm-commits] [llvm] r69123 - in /llvm/trunk: lib/Transforms/Scalar/IndVarSimplify.cpp test/Transforms/IndVarSimplify/2009-04-14-shorten_iv_vars.ll Message-ID: <200904150110.n3F1ADYj023372@zion.cs.uiuc.edu> Author: johannes Date: Tue Apr 14 20:10:12 2009 New Revision: 69123 URL: http://llvm.org/viewvc/llvm-project?rev=69123&view=rev Log: Enhance induction variable code to remove the sext around sext(shorter IV + constant), using a longer IV instead, when it can figure out the add can't overflow. This comes up a lot in subscripting; mainly affects 64 bit. Added: llvm/trunk/test/Transforms/IndVarSimplify/2009-04-14-shorten_iv_vars.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=69123&r1=69122&r2=69123&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp Tue Apr 14 20:10:12 2009 @@ -467,8 +467,12 @@ /// whether an induction variable in the same type that starts /// at 0 would undergo signed overflow. /// -/// In addition to setting the NoSignedWrap, and NoUnsignedWrap, -/// variables, return the PHI for this induction variable. +/// In addition to setting the NoSignedWrap and NoUnsignedWrap +/// variables to true when appropriate (they are not set to false here), +/// return the PHI for this induction variable. Also record the initial +/// and final values and the increment; these are not meaningful unless +/// either NoSignedWrap or NoUnsignedWrap is true, and are always meaningful +/// in that case, although the final value may be 0 indicating a nonconstant. /// /// TODO: This duplicates a fair amount of ScalarEvolution logic. /// Perhaps this can be merged with @@ -479,7 +483,10 @@ const BranchInst *BI, const Instruction *OrigCond, bool &NoSignedWrap, - bool &NoUnsignedWrap) { + bool &NoUnsignedWrap, + const ConstantInt* &InitialVal, + const ConstantInt* &IncrVal, + const ConstantInt* &LimitVal) { // Verify that the loop is sane and find the exit condition. const ICmpInst *Cmp = dyn_cast(OrigCond); if (!Cmp) return 0; @@ -542,31 +549,31 @@ // Get the increment instruction. Look past casts if we will // be able to prove that the original induction variable doesn't // undergo signed or unsigned overflow, respectively. - const Value *IncrVal = CmpLHS; + const Value *IncrInst = CmpLHS; if (isSigned) { if (const SExtInst *SI = dyn_cast(CmpLHS)) { if (!isa(CmpRHS) || !cast(CmpRHS)->getValue() - .isSignedIntN(IncrVal->getType()->getPrimitiveSizeInBits())) + .isSignedIntN(IncrInst->getType()->getPrimitiveSizeInBits())) return 0; - IncrVal = SI->getOperand(0); + IncrInst = SI->getOperand(0); } } else { if (const ZExtInst *ZI = dyn_cast(CmpLHS)) { if (!isa(CmpRHS) || !cast(CmpRHS)->getValue() - .isIntN(IncrVal->getType()->getPrimitiveSizeInBits())) + .isIntN(IncrInst->getType()->getPrimitiveSizeInBits())) return 0; - IncrVal = ZI->getOperand(0); + IncrInst = ZI->getOperand(0); } } // For now, only analyze induction variables that have simple increments. - const BinaryOperator *IncrOp = dyn_cast(IncrVal); - if (!IncrOp || - IncrOp->getOpcode() != Instruction::Add || - !isa(IncrOp->getOperand(1)) || - !cast(IncrOp->getOperand(1))->equalsInt(1)) + const BinaryOperator *IncrOp = dyn_cast(IncrInst); + if (!IncrOp || IncrOp->getOpcode() != Instruction::Add) + return 0; + IncrVal = dyn_cast(IncrOp->getOperand(1)); + if (!IncrVal) return 0; // Make sure the PHI looks like a normal IV. @@ -584,21 +591,78 @@ // For now, only analyze loops with a constant start value, so that // we can easily determine if the start value is not a maximum value // which would wrap on the first iteration. - const ConstantInt *InitialVal = - dyn_cast(PN->getIncomingValue(IncomingEdge)); + InitialVal = dyn_cast(PN->getIncomingValue(IncomingEdge)); if (!InitialVal) return 0; - // The original induction variable will start at some non-max value, - // it counts up by one, and the loop iterates only while it remans - // less than some value in the same type. As such, it will never wrap. + // The upper limit need not be a constant; we'll check later. + LimitVal = dyn_cast(CmpRHS); + + // We detect the impossibility of wrapping in two cases, both of + // which require starting with a non-max value: + // - The IV counts up by one, and the loop iterates only while it remains + // less than a limiting value (any) in the same type. + // - The IV counts up by a positive increment other than 1, and the + // constant limiting value + the increment is less than the max value + // (computed as max-increment to avoid overflow) if (isSigned && !InitialVal->getValue().isMaxSignedValue()) { - NoSignedWrap = true; - } else if (!isSigned && !InitialVal->getValue().isMaxValue()) - NoUnsignedWrap = true; + if (IncrVal->equalsInt(1)) + NoSignedWrap = true; // LimitVal need not be constant + else if (LimitVal) { + uint64_t numBits = LimitVal->getValue().getBitWidth(); + if (IncrVal->getValue().sgt(APInt::getNullValue(numBits)) && + (APInt::getSignedMaxValue(numBits) - IncrVal->getValue()) + .sgt(LimitVal->getValue())) + NoSignedWrap = true; + } + } else if (!isSigned && !InitialVal->getValue().isMaxValue()) { + if (IncrVal->equalsInt(1)) + NoUnsignedWrap = true; // LimitVal need not be constant + else if (LimitVal) { + uint64_t numBits = LimitVal->getValue().getBitWidth(); + if (IncrVal->getValue().ugt(APInt::getNullValue(numBits)) && + (APInt::getMaxValue(numBits) - IncrVal->getValue()) + .ugt(LimitVal->getValue())) + NoUnsignedWrap = true; + } + } return PN; } +static Value *getSignExtendedTruncVar(const SCEVAddRecExpr *AR, + ScalarEvolution *SE, + const Type *LargestType, Loop *L, + const Type *myType, + SCEVExpander &Rewriter, + BasicBlock::iterator InsertPt) { + SCEVHandle ExtendedStart = + SE->getSignExtendExpr(AR->getStart(), LargestType); + SCEVHandle ExtendedStep = + SE->getSignExtendExpr(AR->getStepRecurrence(*SE), LargestType); + SCEVHandle ExtendedAddRec = + SE->getAddRecExpr(ExtendedStart, ExtendedStep, L); + if (LargestType != myType) + ExtendedAddRec = SE->getTruncateExpr(ExtendedAddRec, myType); + return Rewriter.expandCodeFor(ExtendedAddRec, InsertPt); +} + +static Value *getZeroExtendedTruncVar(const SCEVAddRecExpr *AR, + ScalarEvolution *SE, + const Type *LargestType, Loop *L, + const Type *myType, + SCEVExpander &Rewriter, + BasicBlock::iterator InsertPt) { + SCEVHandle ExtendedStart = + SE->getZeroExtendExpr(AR->getStart(), LargestType); + SCEVHandle ExtendedStep = + SE->getZeroExtendExpr(AR->getStepRecurrence(*SE), LargestType); + SCEVHandle ExtendedAddRec = + SE->getAddRecExpr(ExtendedStart, ExtendedStep, L); + if (LargestType != myType) + ExtendedAddRec = SE->getTruncateExpr(ExtendedAddRec, myType); + return Rewriter.expandCodeFor(ExtendedAddRec, InsertPt); +} + bool IndVarSimplify::runOnLoop(Loop *L, LPPassManager &LPM) { LI = &getAnalysis(); SE = &getAnalysis(); @@ -680,6 +744,7 @@ // using it. We can currently only handle loops with a single exit. bool NoSignedWrap = false; bool NoUnsignedWrap = false; + const ConstantInt* InitialVal, * IncrVal, * LimitVal; const PHINode *OrigControllingPHI = 0; if (!isa(BackedgeTakenCount) && ExitingBlock) // Can't rewrite non-branch yet. @@ -688,7 +753,8 @@ // Determine if the OrigIV will ever undergo overflow. OrigControllingPHI = TestOrigIVForWrap(L, BI, OrigCond, - NoSignedWrap, NoUnsignedWrap); + NoSignedWrap, NoUnsignedWrap, + InitialVal, IncrVal, LimitVal); // We'll be replacing the original condition, so it'll be dead. DeadInsts.insert(OrigCond); @@ -733,29 +799,44 @@ for (Value::use_iterator UI = PN->use_begin(), UE = PN->use_end(); UI != UE; ++UI) { if (isa(UI) && NoSignedWrap) { - SCEVHandle ExtendedStart = - SE->getSignExtendExpr(AR->getStart(), LargestType); - SCEVHandle ExtendedStep = - SE->getSignExtendExpr(AR->getStepRecurrence(*SE), LargestType); - SCEVHandle ExtendedAddRec = - SE->getAddRecExpr(ExtendedStart, ExtendedStep, L); - if (LargestType != UI->getType()) - ExtendedAddRec = SE->getTruncateExpr(ExtendedAddRec, UI->getType()); - Value *TruncIndVar = Rewriter.expandCodeFor(ExtendedAddRec, InsertPt); + Value *TruncIndVar = getSignExtendedTruncVar(AR, SE, LargestType, L, + UI->getType(), Rewriter, InsertPt); UI->replaceAllUsesWith(TruncIndVar); if (Instruction *DeadUse = dyn_cast(*UI)) DeadInsts.insert(DeadUse); } + // See if we can figure out sext(i+constant) doesn't wrap, so we can + // use a larger add. This is common in subscripting. + Instruction *UInst = dyn_cast(*UI); + if (UInst && UInst->getOpcode()==Instruction::Add && + UInst->hasOneUse() && + isa(UInst->getOperand(1)) && + isa(UInst->use_begin()) && NoSignedWrap && LimitVal) { + uint64_t numBits = LimitVal->getValue().getBitWidth(); + ConstantInt* RHS = dyn_cast(UInst->getOperand(1)); + if (((APInt::getSignedMaxValue(numBits) - IncrVal->getValue()) - + RHS->getValue()).sgt(LimitVal->getValue())) { + SExtInst* oldSext = dyn_cast(UInst->use_begin()); + Value *TruncIndVar = getSignExtendedTruncVar(AR, SE, LargestType, L, + oldSext->getType(), Rewriter, + InsertPt); + APInt APcopy = APInt(RHS->getValue()); + ConstantInt* newRHS = + ConstantInt::get(APcopy.sext(oldSext->getType()-> + getPrimitiveSizeInBits())); + Value *NewAdd = BinaryOperator::CreateAdd(TruncIndVar, newRHS, + UInst->getName()+".nosex", + UInst); + oldSext->replaceAllUsesWith(NewAdd); + if (Instruction *DeadUse = dyn_cast(oldSext)) + DeadInsts.insert(DeadUse); + if (Instruction *DeadUse = dyn_cast(UInst)) + DeadInsts.insert(DeadUse); + } + } if (isa(UI) && NoUnsignedWrap) { - SCEVHandle ExtendedStart = - SE->getZeroExtendExpr(AR->getStart(), LargestType); - SCEVHandle ExtendedStep = - SE->getZeroExtendExpr(AR->getStepRecurrence(*SE), LargestType); - SCEVHandle ExtendedAddRec = - SE->getAddRecExpr(ExtendedStart, ExtendedStep, L); - if (LargestType != UI->getType()) - ExtendedAddRec = SE->getTruncateExpr(ExtendedAddRec, UI->getType()); - Value *TruncIndVar = Rewriter.expandCodeFor(ExtendedAddRec, InsertPt); + Value *TruncIndVar = getZeroExtendedTruncVar(AR, SE, LargestType, L, + UI->getType(), Rewriter, InsertPt); UI->replaceAllUsesWith(TruncIndVar); if (Instruction *DeadUse = dyn_cast(*UI)) DeadInsts.insert(DeadUse); Added: llvm/trunk/test/Transforms/IndVarSimplify/2009-04-14-shorten_iv_vars.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/IndVarSimplify/2009-04-14-shorten_iv_vars.ll?rev=69123&view=auto ============================================================================== --- llvm/trunk/test/Transforms/IndVarSimplify/2009-04-14-shorten_iv_vars.ll (added) +++ llvm/trunk/test/Transforms/IndVarSimplify/2009-04-14-shorten_iv_vars.ll Tue Apr 14 20:10:12 2009 @@ -0,0 +1,114 @@ +; RUN: llvm-as < %s | opt -indvars | llvm-dis | not grep {sext} +; ModuleID = '' +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" +target triple = "x86_64-apple-darwin9.6" + at a = external global i32* ; [#uses=3] + at b = external global i32* ; [#uses=3] + at c = external global i32* ; [#uses=3] + at d = external global i32* ; [#uses=3] + at e = external global i32* ; [#uses=3] + at f = external global i32* ; [#uses=3] + +define void @foo() nounwind { +bb1.thread: + br label %bb1 + +bb1: ; preds = %bb1, %bb1.thread + %i.0.reg2mem.0 = phi i32 [ 0, %bb1.thread ], [ %84, %bb1 ] ; [#uses=19] + %0 = load i32** @a, align 8 ; [#uses=1] + %1 = load i32** @b, align 8 ; [#uses=1] + %2 = sext i32 %i.0.reg2mem.0 to i64 ; [#uses=1] + %3 = getelementptr i32* %1, i64 %2 ; [#uses=1] + %4 = load i32* %3, align 1 ; [#uses=1] + %5 = load i32** @c, align 8 ; [#uses=1] + %6 = sext i32 %i.0.reg2mem.0 to i64 ; [#uses=1] + %7 = getelementptr i32* %5, i64 %6 ; [#uses=1] + %8 = load i32* %7, align 1 ; [#uses=1] + %9 = add i32 %8, %4 ; [#uses=1] + %10 = sext i32 %i.0.reg2mem.0 to i64 ; [#uses=1] + %11 = getelementptr i32* %0, i64 %10 ; [#uses=1] + store i32 %9, i32* %11, align 1 + %12 = load i32** @a, align 8 ; [#uses=1] + %13 = add i32 %i.0.reg2mem.0, 1 ; [#uses=1] + %14 = load i32** @b, align 8 ; [#uses=1] + %15 = add i32 %i.0.reg2mem.0, 1 ; [#uses=1] + %16 = sext i32 %15 to i64 ; [#uses=1] + %17 = getelementptr i32* %14, i64 %16 ; [#uses=1] + %18 = load i32* %17, align 1 ; [#uses=1] + %19 = load i32** @c, align 8 ; [#uses=1] + %20 = add i32 %i.0.reg2mem.0, 1 ; [#uses=1] + %21 = sext i32 %20 to i64 ; [#uses=1] + %22 = getelementptr i32* %19, i64 %21 ; [#uses=1] + %23 = load i32* %22, align 1 ; [#uses=1] + %24 = add i32 %23, %18 ; [#uses=1] + %25 = sext i32 %13 to i64 ; [#uses=1] + %26 = getelementptr i32* %12, i64 %25 ; [#uses=1] + store i32 %24, i32* %26, align 1 + %27 = load i32** @a, align 8 ; [#uses=1] + %28 = add i32 %i.0.reg2mem.0, 2 ; [#uses=1] + %29 = load i32** @b, align 8 ; [#uses=1] + %30 = add i32 %i.0.reg2mem.0, 2 ; [#uses=1] + %31 = sext i32 %30 to i64 ; [#uses=1] + %32 = getelementptr i32* %29, i64 %31 ; [#uses=1] + %33 = load i32* %32, align 1 ; [#uses=1] + %34 = load i32** @c, align 8 ; [#uses=1] + %35 = add i32 %i.0.reg2mem.0, 2 ; [#uses=1] + %36 = sext i32 %35 to i64 ; [#uses=1] + %37 = getelementptr i32* %34, i64 %36 ; [#uses=1] + %38 = load i32* %37, align 1 ; [#uses=1] + %39 = add i32 %38, %33 ; [#uses=1] + %40 = sext i32 %28 to i64 ; [#uses=1] + %41 = getelementptr i32* %27, i64 %40 ; [#uses=1] + store i32 %39, i32* %41, align 1 + %42 = load i32** @d, align 8 ; [#uses=1] + %43 = load i32** @e, align 8 ; [#uses=1] + %44 = sext i32 %i.0.reg2mem.0 to i64 ; [#uses=1] + %45 = getelementptr i32* %43, i64 %44 ; [#uses=1] + %46 = load i32* %45, align 1 ; [#uses=1] + %47 = load i32** @f, align 8 ; [#uses=1] + %48 = sext i32 %i.0.reg2mem.0 to i64 ; [#uses=1] + %49 = getelementptr i32* %47, i64 %48 ; [#uses=1] + %50 = load i32* %49, align 1 ; [#uses=1] + %51 = add i32 %50, %46 ; [#uses=1] + %52 = sext i32 %i.0.reg2mem.0 to i64 ; [#uses=1] + %53 = getelementptr i32* %42, i64 %52 ; [#uses=1] + store i32 %51, i32* %53, align 1 + %54 = load i32** @d, align 8 ; [#uses=1] + %55 = add i32 %i.0.reg2mem.0, 1 ; [#uses=1] + %56 = load i32** @e, align 8 ; [#uses=1] + %57 = add i32 %i.0.reg2mem.0, 1 ; [#uses=1] + %58 = sext i32 %57 to i64 ; [#uses=1] + %59 = getelementptr i32* %56, i64 %58 ; [#uses=1] + %60 = load i32* %59, align 1 ; [#uses=1] + %61 = load i32** @f, align 8 ; [#uses=1] + %62 = add i32 %i.0.reg2mem.0, 1 ; [#uses=1] + %63 = sext i32 %62 to i64 ; [#uses=1] + %64 = getelementptr i32* %61, i64 %63 ; [#uses=1] + %65 = load i32* %64, align 1 ; [#uses=1] + %66 = add i32 %65, %60 ; [#uses=1] + %67 = sext i32 %55 to i64 ; [#uses=1] + %68 = getelementptr i32* %54, i64 %67 ; [#uses=1] + store i32 %66, i32* %68, align 1 + %69 = load i32** @d, align 8 ; [#uses=1] + %70 = add i32 %i.0.reg2mem.0, 2 ; [#uses=1] + %71 = load i32** @e, align 8 ; [#uses=1] + %72 = add i32 %i.0.reg2mem.0, 2 ; [#uses=1] + %73 = sext i32 %72 to i64 ; [#uses=1] + %74 = getelementptr i32* %71, i64 %73 ; [#uses=1] + %75 = load i32* %74, align 1 ; [#uses=1] + %76 = load i32** @f, align 8 ; [#uses=1] + %77 = add i32 %i.0.reg2mem.0, 2 ; [#uses=1] + %78 = sext i32 %77 to i64 ; [#uses=1] + %79 = getelementptr i32* %76, i64 %78 ; [#uses=1] + %80 = load i32* %79, align 1 ; [#uses=1] + %81 = add i32 %80, %75 ; [#uses=1] + %82 = sext i32 %70 to i64 ; [#uses=1] + %83 = getelementptr i32* %69, i64 %82 ; [#uses=1] + store i32 %81, i32* %83, align 1 + %84 = add i32 %i.0.reg2mem.0, 1 ; [#uses=2] + %85 = icmp sgt i32 %84, 23646 ; [#uses=1] + br i1 %85, label %return, label %bb1 + +return: ; preds = %bb1 + ret void +} From gohman at apple.com Tue Apr 14 20:17:39 2009 From: gohman at apple.com (Dan Gohman) Date: Wed, 15 Apr 2009 01:17:39 -0000 Subject: [llvm-commits] [llvm] r69124 - in /llvm/trunk: include/llvm/CodeGen/MachineOperand.h lib/CodeGen/MachineInstr.cpp Message-ID: <200904150117.n3F1Hd2A023573@zion.cs.uiuc.edu> Author: djg Date: Tue Apr 14 20:17:37 2009 New Revision: 69124 URL: http://llvm.org/viewvc/llvm-project?rev=69124&view=rev Log: Give RemoveRegOperandFromRegInfo a comment and move the code out of line. Modified: llvm/trunk/include/llvm/CodeGen/MachineOperand.h llvm/trunk/lib/CodeGen/MachineInstr.cpp Modified: llvm/trunk/include/llvm/CodeGen/MachineOperand.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineOperand.h?rev=69124&r1=69123&r2=69124&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/MachineOperand.h (original) +++ llvm/trunk/include/llvm/CodeGen/MachineOperand.h Tue Apr 14 20:17:37 2009 @@ -427,18 +427,9 @@ /// explicitly nulled out. void AddRegOperandToRegInfo(MachineRegisterInfo *RegInfo); - void RemoveRegOperandFromRegInfo() { - assert(isOnRegUseList() && "Reg operand is not on a use list"); - // Unlink this from the doubly linked list of operands. - MachineOperand *NextOp = Contents.Reg.Next; - *Contents.Reg.Prev = NextOp; - if (NextOp) { - assert(NextOp->getReg() == getReg() && "Corrupt reg use/def chain!"); - NextOp->Contents.Reg.Prev = Contents.Reg.Prev; - } - Contents.Reg.Prev = 0; - Contents.Reg.Next = 0; - } + /// RemoveRegOperandFromRegInfo - Remove this register operand from the + /// MachineRegisterInfo it is linked with. + void RemoveRegOperandFromRegInfo(); }; inline std::ostream &operator<<(std::ostream &OS, const MachineOperand &MO) { Modified: llvm/trunk/lib/CodeGen/MachineInstr.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineInstr.cpp?rev=69124&r1=69123&r2=69124&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineInstr.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineInstr.cpp Tue Apr 14 20:17:37 2009 @@ -68,6 +68,21 @@ *Head = this; } +/// RemoveRegOperandFromRegInfo - Remove this register operand from the +/// MachineRegisterInfo it is linked with. +void MachineOperand::RemoveRegOperandFromRegInfo() { + assert(isOnRegUseList() && "Reg operand is not on a use list"); + // Unlink this from the doubly linked list of operands. + MachineOperand *NextOp = Contents.Reg.Next; + *Contents.Reg.Prev = NextOp; + if (NextOp) { + assert(NextOp->getReg() == getReg() && "Corrupt reg use/def chain!"); + NextOp->Contents.Reg.Prev = Contents.Reg.Prev; + } + Contents.Reg.Prev = 0; + Contents.Reg.Next = 0; +} + void MachineOperand::setReg(unsigned Reg) { if (getReg() == Reg) return; // No change. From gohman at apple.com Tue Apr 14 20:18:49 2009 From: gohman at apple.com (Dan Gohman) Date: Wed, 15 Apr 2009 01:18:49 -0000 Subject: [llvm-commits] [llvm] r69125 - in /llvm/trunk: include/llvm/CodeGen/MachineJumpTableInfo.h lib/CodeGen/MachineFunction.cpp Message-ID: <200904150118.n3F1Inhc023614@zion.cs.uiuc.edu> Author: djg Date: Tue Apr 14 20:18:49 2009 New Revision: 69125 URL: http://llvm.org/viewvc/llvm-project?rev=69125&view=rev Log: Move MachineJumpTableInfo::ReplaceMBBInJumpTables out of line. Modified: llvm/trunk/include/llvm/CodeGen/MachineJumpTableInfo.h llvm/trunk/lib/CodeGen/MachineFunction.cpp Modified: llvm/trunk/include/llvm/CodeGen/MachineJumpTableInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineJumpTableInfo.h?rev=69125&r1=69124&r2=69125&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/MachineJumpTableInfo.h (original) +++ llvm/trunk/include/llvm/CodeGen/MachineJumpTableInfo.h Tue Apr 14 20:18:49 2009 @@ -67,20 +67,8 @@ /// ReplaceMBBInJumpTables - If Old is the target of any jump tables, update /// the jump tables to branch to New instead. - bool ReplaceMBBInJumpTables(MachineBasicBlock *Old, MachineBasicBlock *New) { - assert(Old != New && "Not making a change?"); - bool MadeChange = false; - for (size_t i = 0, e = JumpTables.size(); i != e; ++i) { - MachineJumpTableEntry &JTE = JumpTables[i]; - for (size_t j = 0, e = JTE.MBBs.size(); j != e; ++j) - if (JTE.MBBs[j] == Old) { - JTE.MBBs[j] = New; - MadeChange = true; - } - } - return MadeChange; - } - + bool ReplaceMBBInJumpTables(MachineBasicBlock *Old, MachineBasicBlock *New); + /// getEntrySize - Returns the size of an individual field in a jump table. /// unsigned getEntrySize() const { return EntrySize; } Modified: llvm/trunk/lib/CodeGen/MachineFunction.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineFunction.cpp?rev=69125&r1=69124&r2=69125&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineFunction.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineFunction.cpp Tue Apr 14 20:18:49 2009 @@ -486,6 +486,23 @@ return JumpTables.size()-1; } +/// ReplaceMBBInJumpTables - If Old is the target of any jump tables, update +/// the jump tables to branch to New instead. +bool +MachineJumpTableInfo::ReplaceMBBInJumpTables(MachineBasicBlock *Old, + MachineBasicBlock *New) { + assert(Old != New && "Not making a change?"); + bool MadeChange = false; + for (size_t i = 0, e = JumpTables.size(); i != e; ++i) { + MachineJumpTableEntry &JTE = JumpTables[i]; + for (size_t j = 0, e = JTE.MBBs.size(); j != e; ++j) + if (JTE.MBBs[j] == Old) { + JTE.MBBs[j] = New; + MadeChange = true; + } + } + return MadeChange; +} void MachineJumpTableInfo::print(std::ostream &OS) const { // FIXME: this is lame, maybe we could print out the MBB numbers or something From gohman at apple.com Tue Apr 14 20:19:35 2009 From: gohman at apple.com (Dan Gohman) Date: Wed, 15 Apr 2009 01:19:35 -0000 Subject: [llvm-commits] [llvm] r69126 - in /llvm/trunk: include/llvm/CodeGen/MachineRegisterInfo.h lib/CodeGen/MachineRegisterInfo.cpp Message-ID: <200904150119.n3F1JZe0023657@zion.cs.uiuc.edu> Author: djg Date: Tue Apr 14 20:19:35 2009 New Revision: 69126 URL: http://llvm.org/viewvc/llvm-project?rev=69126&view=rev Log: Move MachineRegisterInfo::setRegClass out of line. Modified: llvm/trunk/include/llvm/CodeGen/MachineRegisterInfo.h llvm/trunk/lib/CodeGen/MachineRegisterInfo.cpp Modified: llvm/trunk/include/llvm/CodeGen/MachineRegisterInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineRegisterInfo.h?rev=69126&r1=69125&r2=69126&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/MachineRegisterInfo.h (original) +++ llvm/trunk/include/llvm/CodeGen/MachineRegisterInfo.h Tue Apr 14 20:19:35 2009 @@ -152,23 +152,8 @@ /// setRegClass - Set the register class of the specified virtual register. /// - void setRegClass(unsigned Reg, const TargetRegisterClass *RC) { - unsigned VR = Reg; - Reg -= TargetRegisterInfo::FirstVirtualRegister; - assert(Reg < VRegInfo.size() && "Invalid vreg!"); - const TargetRegisterClass *OldRC = VRegInfo[Reg].first; - VRegInfo[Reg].first = RC; - - // Remove from old register class's vregs list. This may be slow but - // fortunately this operation is rarely needed. - std::vector &VRegs = RegClass2VRegMap[OldRC->getID()]; - std::vector::iterator I=std::find(VRegs.begin(), VRegs.end(), VR); - VRegs.erase(I); + void setRegClass(unsigned Reg, const TargetRegisterClass *RC); - // Add to new register class's vregs list. - RegClass2VRegMap[RC->getID()].push_back(VR); - } - /// createVirtualRegister - Create and return a new virtual register in the /// function with the specified register class. /// Modified: llvm/trunk/lib/CodeGen/MachineRegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineRegisterInfo.cpp?rev=69126&r1=69125&r2=69126&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineRegisterInfo.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineRegisterInfo.cpp Tue Apr 14 20:19:35 2009 @@ -35,6 +35,26 @@ delete [] PhysRegUseDefLists; } +/// setRegClass - Set the register class of the specified virtual register. +/// +void +MachineRegisterInfo::setRegClass(unsigned Reg, const TargetRegisterClass *RC) { + unsigned VR = Reg; + Reg -= TargetRegisterInfo::FirstVirtualRegister; + assert(Reg < VRegInfo.size() && "Invalid vreg!"); + const TargetRegisterClass *OldRC = VRegInfo[Reg].first; + VRegInfo[Reg].first = RC; + + // Remove from old register class's vregs list. This may be slow but + // fortunately this operation is rarely needed. + std::vector &VRegs = RegClass2VRegMap[OldRC->getID()]; + std::vector::iterator I=std::find(VRegs.begin(), VRegs.end(), VR); + VRegs.erase(I); + + // Add to new register class's vregs list. + RegClass2VRegMap[RC->getID()].push_back(VR); +} + /// createVirtualRegister - Create and return a new virtual register in the /// function with the specified register class. /// From gohman at apple.com Tue Apr 14 20:20:18 2009 From: gohman at apple.com (Dan Gohman) Date: Wed, 15 Apr 2009 01:20:18 -0000 Subject: [llvm-commits] [llvm] r69127 - /llvm/trunk/lib/Target/X86/X86MachineFunctionInfo.h Message-ID: <200904150120.n3F1KItm023701@zion.cs.uiuc.edu> Author: djg Date: Tue Apr 14 20:20:18 2009 New Revision: 69127 URL: http://llvm.org/viewvc/llvm-project?rev=69127&view=rev Log: Fix X86MachineFunctionInfo's doxygen comment. Modified: llvm/trunk/lib/Target/X86/X86MachineFunctionInfo.h Modified: llvm/trunk/lib/Target/X86/X86MachineFunctionInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86MachineFunctionInfo.h?rev=69127&r1=69126&r2=69127&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86MachineFunctionInfo.h (original) +++ llvm/trunk/lib/Target/X86/X86MachineFunctionInfo.h Tue Apr 14 20:20:18 2009 @@ -24,8 +24,8 @@ FastCall }; -/// X86MachineFunctionInfo - This class is derived from MachineFunction private -/// X86 target-specific information for each MachineFunction. +/// X86MachineFunctionInfo - This class is derived from MachineFunction and +/// contains private X86 target-specific information for each MachineFunction. class X86MachineFunctionInfo : public MachineFunctionInfo { /// ForceFramePointer - True if the function is required to use of frame /// pointer for reasons other than it containing dynamic allocation or @@ -106,6 +106,7 @@ unsigned getGlobalBaseReg() const { return GlobalBaseReg; } void setGlobalBaseReg(unsigned Reg) { GlobalBaseReg = Reg; } }; + } // End llvm namespace #endif From gohman at apple.com Tue Apr 14 20:44:07 2009 From: gohman at apple.com (Dan Gohman) Date: Wed, 15 Apr 2009 01:44:07 -0000 Subject: [llvm-commits] [llvm] r69128 - /llvm/trunk/include/llvm/Target/TargetJITInfo.h Message-ID: <200904150144.n3F1i7aM024413@zion.cs.uiuc.edu> Author: djg Date: Tue Apr 14 20:44:07 2009 New Revision: 69128 URL: http://llvm.org/viewvc/llvm-project?rev=69128&view=rev Log: Fix doxygen comment syntax. Modified: llvm/trunk/include/llvm/Target/TargetJITInfo.h Modified: llvm/trunk/include/llvm/Target/TargetJITInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetJITInfo.h?rev=69128&r1=69127&r2=69128&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetJITInfo.h (original) +++ llvm/trunk/include/llvm/Target/TargetJITInfo.h Tue Apr 14 20:44:07 2009 @@ -112,7 +112,7 @@ } /// needsGOT - Allows a target to specify that it would like the - // JIT to manage a GOT for it. + /// JIT to manage a GOT for it. bool needsGOT() const { return useGOT; } /// hasCustomConstantPool - Allows a target to specify that constant From gohman at apple.com Tue Apr 14 20:47:03 2009 From: gohman at apple.com (Dan Gohman) Date: Wed, 15 Apr 2009 01:47:03 -0000 Subject: [llvm-commits] [llvm] r69129 - /llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h Message-ID: <200904150147.n3F1l3l5024508@zion.cs.uiuc.edu> Author: djg Date: Tue Apr 14 20:47:03 2009 New Revision: 69129 URL: http://llvm.org/viewvc/llvm-project?rev=69129&view=rev Log: Don't use "protected:" in classes that aren't intended to be subclassed. 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=69129&r1=69128&r2=69129&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h (original) +++ llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h Tue Apr 14 20:47:03 2009 @@ -1703,7 +1703,6 @@ class ConstantSDNode : public SDNode { const ConstantInt *Value; -protected: friend class SelectionDAG; ConstantSDNode(bool isTarget, const ConstantInt *val, MVT VT) : SDNode(isTarget ? ISD::TargetConstant : ISD::Constant, @@ -1728,7 +1727,6 @@ class ConstantFPSDNode : public SDNode { const ConstantFP *Value; -protected: friend class SelectionDAG; ConstantFPSDNode(bool isTarget, const ConstantFP *val, MVT VT) : SDNode(isTarget ? ISD::TargetConstantFP : ISD::ConstantFP, @@ -1771,7 +1769,6 @@ class GlobalAddressSDNode : public SDNode { GlobalValue *TheGlobal; int64_t Offset; -protected: friend class SelectionDAG; GlobalAddressSDNode(bool isTarget, const GlobalValue *GA, MVT VT, int64_t o = 0); @@ -1791,7 +1788,6 @@ class FrameIndexSDNode : public SDNode { int FI; -protected: friend class SelectionDAG; FrameIndexSDNode(int fi, MVT VT, bool isTarg) : SDNode(isTarg ? ISD::TargetFrameIndex : ISD::FrameIndex, @@ -1810,7 +1806,6 @@ class JumpTableSDNode : public SDNode { int JTI; -protected: friend class SelectionDAG; JumpTableSDNode(int jti, MVT VT, bool isTarg) : SDNode(isTarg ? ISD::TargetJumpTable : ISD::JumpTable, @@ -1834,7 +1829,6 @@ } Val; int Offset; // It's a MachineConstantPoolValue if top bit is set. unsigned Alignment; // Minimum alignment requirement of CP (not log2 value). -protected: friend class SelectionDAG; ConstantPoolSDNode(bool isTarget, Constant *c, MVT VT, int o=0) : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool, @@ -1903,7 +1897,6 @@ class BasicBlockSDNode : public SDNode { MachineBasicBlock *MBB; -protected: friend class SelectionDAG; /// Debug info is meaningful and potentially useful here, but we create /// blocks out of order when they're jumped to, which makes it a bit @@ -1957,7 +1950,6 @@ /// class SrcValueSDNode : public SDNode { const Value *V; -protected: friend class SelectionDAG; /// Create a SrcValue for a general value. explicit SrcValueSDNode(const Value *v) @@ -1980,7 +1972,6 @@ /// and ISD::STORE have been lowered. /// class MemOperandSDNode : public SDNode { -protected: friend class SelectionDAG; /// Create a MachineMemOperand node explicit MemOperandSDNode(const MachineMemOperand &mo) @@ -2000,7 +1991,6 @@ class RegisterSDNode : public SDNode { unsigned Reg; -protected: friend class SelectionDAG; RegisterSDNode(unsigned reg, MVT VT) : SDNode(ISD::Register, DebugLoc::getUnknownLoc(), @@ -2021,7 +2011,6 @@ unsigned Line; unsigned Column; Value *CU; -protected: friend class SelectionDAG; DbgStopPointSDNode(SDValue ch, unsigned l, unsigned c, Value *cu) @@ -2043,7 +2032,6 @@ class LabelSDNode : public SDNode { SDUse Chain; unsigned LabelID; -protected: friend class SelectionDAG; LabelSDNode(unsigned NodeTy, DebugLoc dl, SDValue ch, unsigned id) : SDNode(NodeTy, dl, getSDVTList(MVT::Other)), LabelID(id) { @@ -2061,7 +2049,6 @@ class ExternalSymbolSDNode : public SDNode { const char *Symbol; -protected: friend class SelectionDAG; ExternalSymbolSDNode(bool isTarget, const char *Sym, MVT VT) : SDNode(isTarget ? ISD::TargetExternalSymbol : ISD::ExternalSymbol, @@ -2081,7 +2068,6 @@ class CondCodeSDNode : public SDNode { ISD::CondCode Condition; -protected: friend class SelectionDAG; explicit CondCodeSDNode(ISD::CondCode Cond) : SDNode(ISD::CONDCODE, DebugLoc::getUnknownLoc(), @@ -2101,7 +2087,6 @@ /// future and most targets don't support it. class CvtRndSatSDNode : public SDNode { ISD::CvtCode CvtCode; -protected: friend class SelectionDAG; explicit CvtRndSatSDNode(MVT VT, DebugLoc dl, const SDValue *Ops, unsigned NumOps, ISD::CvtCode Code) @@ -2206,7 +2191,6 @@ /// ARG_FLAGSSDNode - Leaf node holding parameter flags. class ARG_FLAGSSDNode : public SDNode { ISD::ArgFlagsTy TheFlags; -protected: friend class SelectionDAG; explicit ARG_FLAGSSDNode(ISD::ArgFlagsTy Flags) : SDNode(ISD::ARG_FLAGS, DebugLoc::getUnknownLoc(), @@ -2230,7 +2214,6 @@ // will expand the size of the representation. At the moment we only // need Inreg. bool Inreg; -protected: friend class SelectionDAG; CallSDNode(unsigned cc, DebugLoc dl, bool isvararg, bool istailcall, bool isinreg, SDVTList VTs, const SDValue *Operands, @@ -2275,7 +2258,6 @@ /// to parameterize some operations. class VTSDNode : public SDNode { MVT ValueType; -protected: friend class SelectionDAG; explicit VTSDNode(MVT VT) : SDNode(ISD::VALUETYPE, DebugLoc::getUnknownLoc(), @@ -2294,7 +2276,6 @@ /// LSBaseSDNode - Base class for LoadSDNode and StoreSDNode /// class LSBaseSDNode : public MemSDNode { -protected: //! Operand array for load and store /*! \note Moving this array to the base class captures more @@ -2341,7 +2322,6 @@ /// LoadSDNode - This class is used to represent ISD::LOAD nodes. /// class LoadSDNode : public LSBaseSDNode { -protected: friend class SelectionDAG; LoadSDNode(SDValue *ChainPtrOff, DebugLoc dl, SDVTList VTs, ISD::MemIndexedMode AM, ISD::LoadExtType ETy, MVT LVT, @@ -2371,7 +2351,6 @@ /// StoreSDNode - This class is used to represent ISD::STORE nodes. /// class StoreSDNode : public LSBaseSDNode { -protected: friend class SelectionDAG; StoreSDNode(SDValue *ChainValuePtrOff, DebugLoc dl, SDVTList VTs, ISD::MemIndexedMode AM, bool isTrunc, MVT SVT, From isanbard at gmail.com Tue Apr 14 21:12:38 2009 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 15 Apr 2009 02:12:38 -0000 Subject: [llvm-commits] [llvm] r69130 - /llvm/trunk/docs/CodeGenerator.html Message-ID: <200904150212.n3F2Cc6X025332@zion.cs.uiuc.edu> Author: void Date: Tue Apr 14 21:12:37 2009 New Revision: 69130 URL: http://llvm.org/viewvc/llvm-project?rev=69130&view=rev Log: More obsessive reformatting. Fixed some validation errors. Modified: llvm/trunk/docs/CodeGenerator.html Modified: llvm/trunk/docs/CodeGenerator.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/CodeGenerator.html?rev=69130&r1=69129&r2=69130&view=diff ============================================================================== --- llvm/trunk/docs/CodeGenerator.html (original) +++ llvm/trunk/docs/CodeGenerator.html Tue Apr 14 21:12:37 2009 @@ -119,52 +119,51 @@

The LLVM target-independent code generator is a framework that provides a -suite of reusable components for translating the LLVM internal representation to -the machine code for a specified target—either in assembly form (suitable -for a static compiler) or in binary machine code format (usable for a JIT -compiler). The LLVM target-independent code generator consists of five main -components:

+ suite of reusable components for translating the LLVM internal representation + to the machine code for a specified target—either in assembly form + (suitable for a static compiler) or in binary machine code format (usable for + a JIT compiler). The LLVM target-independent code generator consists of five + main components:

    -
  1. Abstract target description interfaces which -capture important properties about various aspects of the machine, independently -of how they will be used. These interfaces are defined in -include/llvm/Target/.
  2. - -
  3. Classes used to represent the machine code being -generated for a target. These classes are intended to be abstract enough to -represent the machine code for any target machine. These classes are -defined in include/llvm/CodeGen/.
  4. - -
  5. Target-independent algorithms used to implement -various phases of native code generation (register allocation, scheduling, stack -frame representation, etc). This code lives in lib/CodeGen/.
  6. - -
  7. Implementations of the abstract target description -interfaces for particular targets. These machine descriptions make use of -the components provided by LLVM, and can optionally provide custom -target-specific passes, to build complete code generators for a specific target. -Target descriptions live in lib/Target/.
  8. - -
  9. The target-independent JIT components. The LLVM JIT is -completely target independent (it uses the TargetJITInfo structure to -interface for target-specific issues. The code for the target-independent -JIT lives in lib/ExecutionEngine/JIT.
  10. - +
  11. Abstract target description interfaces which + capture important properties about various aspects of the machine, + independently of how they will be used. These interfaces are defined in + include/llvm/Target/.
  12. + +
  13. Classes used to represent the machine code + being generated for a target. These classes are intended to be abstract + enough to represent the machine code for any target machine. These + classes are defined in include/llvm/CodeGen/.
  14. + +
  15. Target-independent algorithms used to implement + various phases of native code generation (register allocation, scheduling, + stack frame representation, etc). This code lives + in lib/CodeGen/.
  16. + +
  17. Implementations of the abstract target description + interfaces for particular targets. These machine descriptions make + use of the components provided by LLVM, and can optionally provide custom + target-specific passes, to build complete code generators for a specific + target. Target descriptions live in lib/Target/.
  18. + +
  19. The target-independent JIT components. The LLVM JIT is + completely target independent (it uses the TargetJITInfo + structure to interface for target-specific issues. The code for the + target-independent JIT lives in lib/ExecutionEngine/JIT.
-

-Depending on which part of the code generator you are interested in working on, -different pieces of this will be useful to you. In any case, you should be -familiar with the target description and machine code representation classes. If you want to add -a backend for a new target, you will need to implement the -target description classes for your new target and understand the LLVM code representation. If you are interested in -implementing a new code generation algorithm, it -should only depend on the target-description and machine code representation -classes, ensuring that it is portable. -

+

Depending on which part of the code generator you are interested in working + on, different pieces of this will be useful to you. In any case, you should + be familiar with the target description + and machine code representation classes. If you + want to add a backend for a new target, you will need + to implement the target description classes for + your new target and understand the LLVM code + representation. If you are interested in implementing a + new code generation algorithm, it should only + depend on the target-description and machine code representation classes, + ensuring that it is portable.

@@ -176,27 +175,27 @@

The two pieces of the LLVM code generator are the high-level interface to the -code generator and the set of reusable components that can be used to build -target-specific backends. The two most important interfaces (TargetMachine and TargetData) are the only ones that are -required to be defined for a backend to fit into the LLVM system, but the others -must be defined if the reusable code generator components are going to be -used.

+ code generator and the set of reusable components that can be used to build + target-specific backends. The two most important interfaces + (TargetMachine + and TargetData) are the only ones that are + required to be defined for a backend to fit into the LLVM system, but the + others must be defined if the reusable code generator components are going to + be used.

This design has two important implications. The first is that LLVM can -support completely non-traditional code generation targets. For example, the C -backend does not require register allocation, instruction selection, or any of -the other standard components provided by the system. As such, it only -implements these two interfaces, and does its own thing. Another example of a -code generator like this is a (purely hypothetical) backend that converts LLVM -to the GCC RTL form and uses GCC to emit machine code for a target.

- -

This design also implies that it is possible to design and -implement radically different code generators in the LLVM system that do not -make use of any of the built-in components. Doing so is not recommended at all, -but could be required for radically different targets that do not fit into the -LLVM machine description model: FPGAs for example.

+ support completely non-traditional code generation targets. For example, the + C backend does not require register allocation, instruction selection, or any + of the other standard components provided by the system. As such, it only + implements these two interfaces, and does its own thing. Another example of + a code generator like this is a (purely hypothetical) backend that converts + LLVM to the GCC RTL form and uses GCC to emit machine code for a target.

+ +

This design also implies that it is possible to design and implement + radically different code generators in the LLVM system that do not make use + of any of the built-in components. Doing so is not recommended at all, but + could be required for radically different targets that do not fit into the + LLVM machine description model: FPGAs for example.

@@ -207,75 +206,73 @@
-

The LLVM target-independent code generator is designed to support efficient and -quality code generation for standard register-based microprocessors. Code -generation in this model is divided into the following stages:

+

The LLVM target-independent code generator is designed to support efficient + and quality code generation for standard register-based microprocessors. + Code generation in this model is divided into the following stages:

    -
  1. Instruction Selection - This phase -determines an efficient way to express the input LLVM code in the target -instruction set. -This stage produces the initial code for the program in the target instruction -set, then makes use of virtual registers in SSA form and physical registers that -represent any required register assignments due to target constraints or calling -conventions. This step turns the LLVM code into a DAG of target -instructions.
  2. - -
  3. Scheduling and Formation - This -phase takes the DAG of target instructions produced by the instruction selection -phase, determines an ordering of the instructions, then emits the instructions -as MachineInstrs with that ordering. Note -that we describe this in the instruction selection -section because it operates on a SelectionDAG. -
  4. - -
  5. SSA-based Machine Code Optimizations - This -optional stage consists of a series of machine-code optimizations that -operate on the SSA-form produced by the instruction selector. Optimizations -like modulo-scheduling or peephole optimization work here. -
  6. - -
  7. Register Allocation - The -target code is transformed from an infinite virtual register file in SSA form -to the concrete register file used by the target. This phase introduces spill -code and eliminates all virtual register references from the program.
  8. - -
  9. Prolog/Epilog Code Insertion - Once the -machine code has been generated for the function and the amount of stack space -required is known (used for LLVM alloca's and spill slots), the prolog and -epilog code for the function can be inserted and "abstract stack location -references" can be eliminated. This stage is responsible for implementing -optimizations like frame-pointer elimination and stack packing.
  10. - -
  11. Late Machine Code Optimizations - Optimizations -that operate on "final" machine code can go here, such as spill code scheduling -and peephole optimizations.
  12. - -
  13. Code Emission - The final stage actually -puts out the code for the current function, either in the target assembler -format or in machine code.
  14. - +
  15. Instruction Selection — This phase + determines an efficient way to express the input LLVM code in the target + instruction set. This stage produces the initial code for the program in + the target instruction set, then makes use of virtual registers in SSA + form and physical registers that represent any required register + assignments due to target constraints or calling conventions. This step + turns the LLVM code into a DAG of target instructions.
  16. + +
  17. Scheduling and Formation — + This phase takes the DAG of target instructions produced by the + instruction selection phase, determines an ordering of the instructions, + then emits the instructions + as MachineInstrs with that ordering. + Note that we describe this in the instruction + selection section because it operates on + a SelectionDAG.
  18. + +
  19. SSA-based Machine Code Optimizations — + This optional stage consists of a series of machine-code optimizations + that operate on the SSA-form produced by the instruction selector. + Optimizations like modulo-scheduling or peephole optimization work + here.
  20. + +
  21. Register Allocation — The target code + is transformed from an infinite virtual register file in SSA form to the + concrete register file used by the target. This phase introduces spill + code and eliminates all virtual register references from the program.
  22. + +
  23. Prolog/Epilog Code Insertion — Once + the machine code has been generated for the function and the amount of + stack space required is known (used for LLVM alloca's and spill slots), + the prolog and epilog code for the function can be inserted and "abstract + stack location references" can be eliminated. This stage is responsible + for implementing optimizations like frame-pointer elimination and stack + packing.
  24. + +
  25. Late Machine Code Optimizations — + Optimizations that operate on "final" machine code can go here, such as + spill code scheduling and peephole optimizations.
  26. + +
  27. Code Emission — The final stage + actually puts out the code for the current function, either in the target + assembler format or in machine code.

The code generator is based on the assumption that the instruction selector -will use an optimal pattern matching selector to create high-quality sequences of -native instructions. Alternative code generator designs based on pattern -expansion and aggressive iterative peephole optimization are much slower. This -design permits efficient compilation (important for JIT environments) and -aggressive optimization (used when generating code offline) by allowing -components of varying levels of sophistication to be used for any step of -compilation.

+ will use an optimal pattern matching selector to create high-quality + sequences of native instructions. Alternative code generator designs based + on pattern expansion and aggressive iterative peephole optimization are much + slower. This design permits efficient compilation (important for JIT + environments) and aggressive optimization (used when generating code offline) + by allowing components of varying levels of sophistication to be used for any + step of compilation.

In addition to these stages, target implementations can insert arbitrary -target-specific passes into the flow. For example, the X86 target uses a -special pass to handle the 80x87 floating point stack architecture. Other -targets with unusual requirements can be supported with custom passes as -needed.

+ target-specific passes into the flow. For example, the X86 target uses a + special pass to handle the 80x87 floating point stack architecture. Other + targets with unusual requirements can be supported with custom passes as + needed.

-
Using TableGen for target description @@ -284,24 +281,23 @@

The target description classes require a detailed description of the target -architecture. These target descriptions often have a large amount of common -information (e.g., an add instruction is almost identical to a -sub instruction). -In order to allow the maximum amount of commonality to be factored out, the LLVM -code generator uses the TableGen tool to -describe big chunks of the target machine, which allows the use of -domain-specific and target-specific abstractions to reduce the amount of -repetition.

+ architecture. These target descriptions often have a large amount of common + information (e.g., an add instruction is almost identical to a + sub instruction). In order to allow the maximum amount of + commonality to be factored out, the LLVM code generator uses + the TableGen tool to describe big + chunks of the target machine, which allows the use of domain-specific and + target-specific abstractions to reduce the amount of repetition.

As LLVM continues to be developed and refined, we plan to move more and more -of the target description to the .td form. Doing so gives us a -number of advantages. The most important is that it makes it easier to port -LLVM because it reduces the amount of C++ code that has to be written, and the -surface area of the code generator that needs to be understood before someone -can get something working. Second, it makes it easier to change things. In -particular, if tables and other things are all emitted by tblgen, we -only need a change in one place (tblgen) to update all of the targets -to a new interface.

+ of the target description to the .td form. Doing so gives us a + number of advantages. The most important is that it makes it easier to port + LLVM because it reduces the amount of C++ code that has to be written, and + the surface area of the code generator that needs to be understood before + someone can get something working. Second, it makes it easier to change + things. In particular, if tables and other things are all emitted + by tblgen, we only need a change in one place (tblgen) to + update all of the targets to a new interface.

@@ -314,18 +310,18 @@

The LLVM target description classes (located in the -include/llvm/Target directory) provide an abstract description of the -target machine independent of any particular client. These classes are -designed to capture the abstract properties of the target (such as the -instructions and registers it has), and do not incorporate any particular pieces -of code generation algorithms.

- -

All of the target description classes (except the TargetData class) are designed to be subclassed by -the concrete target implementation, and have virtual methods implemented. To -get to these implementations, the TargetMachine class provides accessors that -should be implemented by the target.

+ include/llvm/Target directory) provide an abstract description of + the target machine independent of any particular client. These classes are + designed to capture the abstract properties of the target (such as the + instructions and registers it has), and do not incorporate any particular + pieces of code generation algorithms.

+ +

All of the target description classes (except the + TargetData class) are designed to be + subclassed by the concrete target implementation, and have virtual methods + implemented. To get to these implementations, the + TargetMachine class provides accessors + that should be implemented by the target.

@@ -337,19 +333,18 @@

The TargetMachine class provides virtual methods that are used to -access the target-specific implementations of the various target description -classes via the get*Info methods (getInstrInfo, -getRegisterInfo, getFrameInfo, etc.). This class is -designed to be specialized by -a concrete target implementation (e.g., X86TargetMachine) which -implements the various virtual methods. The only required target description -class is the TargetData class, but if the -code generator components are to be used, the other interfaces should be -implemented as well.

+ access the target-specific implementations of the various target description + classes via the get*Info methods (getInstrInfo, + getRegisterInfo, getFrameInfo, etc.). This class is + designed to be specialized by a concrete target implementation + (e.g., X86TargetMachine) which implements the various virtual + methods. The only required target description class is + the TargetData class, but if the code + generator components are to be used, the other interfaces should be + implemented as well.

-
The TargetData class @@ -358,11 +353,11 @@

The TargetData class is the only required target description class, -and it is the only class that is not extensible (you cannot derived a new -class from it). TargetData specifies information about how the target -lays out memory for structures, the alignment requirements for various data -types, the size of pointers in the target, and whether the target is -little-endian or big-endian.

+ and it is the only class that is not extensible (you cannot derived a new + class from it). TargetData specifies information about how the + target lays out memory for structures, the alignment requirements for various + data types, the size of pointers in the target, and whether the target is + little-endian or big-endian.

@@ -374,14 +369,18 @@

The TargetLowering class is used by SelectionDAG based instruction -selectors primarily to describe how LLVM code should be lowered to SelectionDAG -operations. Among other things, this class indicates:

+ selectors primarily to describe how LLVM code should be lowered to + SelectionDAG operations. Among other things, this class indicates:

    -
  • an initial register class to use for various ValueTypes
  • -
  • which operations are natively supported by the target machine
  • -
  • the return type of setcc operations
  • -
  • the type to use for shift amounts
  • +
  • an initial register class to use for various ValueTypes,
  • + +
  • which operations are natively supported by the target machine,
  • + +
  • the return type of setcc operations,
  • + +
  • the type to use for shift amounts, and
  • +
  • various high-level characteristics, like whether it is profitable to turn division by a constant into a multiplication sequence
@@ -395,32 +394,30 @@
-

The TargetRegisterInfo class is used to describe the register -file of the target and any interactions between the registers.

+

The TargetRegisterInfo class is used to describe the register file + of the target and any interactions between the registers.

Registers in the code generator are represented in the code generator by -unsigned integers. Physical registers (those that actually exist in the target -description) are unique small numbers, and virtual registers are generally -large. Note that register #0 is reserved as a flag value.

+ unsigned integers. Physical registers (those that actually exist in the + target description) are unique small numbers, and virtual registers are + generally large. Note that register #0 is reserved as a flag value.

Each register in the processor description has an associated -TargetRegisterDesc entry, which provides a textual name for the -register (used for assembly output and debugging dumps) and a set of aliases -(used to indicate whether one register overlaps with another). -

+ TargetRegisterDesc entry, which provides a textual name for the + register (used for assembly output and debugging dumps) and a set of aliases + (used to indicate whether one register overlaps with another).

In addition to the per-register description, the TargetRegisterInfo -class exposes a set of processor specific register classes (instances of the -TargetRegisterClass class). Each register class contains sets of -registers that have the same properties (for example, they are all 32-bit -integer registers). Each SSA virtual register created by the instruction -selector has an associated register class. When the register allocator runs, it -replaces virtual registers with a physical register in the set.

- -

-The target-specific implementations of these classes is auto-generated from a TableGen description of the register file. -

+ class exposes a set of processor specific register classes (instances of the + TargetRegisterClass class). Each register class contains sets of + registers that have the same properties (for example, they are all 32-bit + integer registers). Each SSA virtual register created by the instruction + selector has an associated register class. When the register allocator runs, + it replaces virtual registers with a physical register in the set.

+ +

The target-specific implementations of these classes is auto-generated from + a TableGen description of the + register file.

@@ -430,14 +427,16 @@
-

The TargetInstrInfo class is used to describe the machine - instructions supported by the target. It is essentially an array of - TargetInstrDescriptor objects, each of which describes one - instruction the target supports. Descriptors define things like the mnemonic - for the opcode, the number of operands, the list of implicit register uses - and defs, whether the instruction has certain target-independent properties - (accesses memory, is commutable, etc), and holds any target-specific - flags.

+ +

The TargetInstrInfo class is used to describe the machine + instructions supported by the target. It is essentially an array of + TargetInstrDescriptor objects, each of which describes one + instruction the target supports. Descriptors define things like the mnemonic + for the opcode, the number of operands, the list of implicit register uses + and defs, whether the instruction has certain target-independent properties + (accesses memory, is commutable, etc), and holds any target-specific + flags.

+
@@ -446,12 +445,14 @@
-

The TargetFrameInfo class is used to provide information about the - stack frame layout of the target. It holds the direction of stack growth, - the known stack alignment on entry to each function, and the offset to the - local area. The offset to the local area is the offset from the stack - pointer on function entry to the first location where function data (local - variables, spill locations) can be stored.

+ +

The TargetFrameInfo class is used to provide information about the + stack frame layout of the target. It holds the direction of stack growth, the + known stack alignment on entry to each function, and the offset to the local + area. The offset to the local area is the offset from the stack pointer on + function entry to the first location where function data (local variables, + spill locations) can be stored.

+
@@ -460,11 +461,13 @@
-

The TargetSubtarget class is used to provide information about the - specific chip set being targeted. A sub-target informs code generation of - which instructions are supported, instruction latencies and instruction - execution itinerary; i.e., which processing units are used, in what order, and - for how long.

+ +

The TargetSubtarget class is used to provide information about the + specific chip set being targeted. A sub-target informs code generation of + which instructions are supported, instruction latencies and instruction + execution itinerary; i.e., which processing units are used, in what order, + and for how long.

+
@@ -474,11 +477,13 @@
-

The TargetJITInfo class exposes an abstract interface used by the - Just-In-Time code generator to perform target-specific activities, such as - emitting stubs. If a TargetMachine supports JIT code generation, it - should provide one of these objects through the getJITInfo - method.

+ +

The TargetJITInfo class exposes an abstract interface used by the + Just-In-Time code generator to perform target-specific activities, such as + emitting stubs. If a TargetMachine supports JIT code generation, it + should provide one of these objects through the getJITInfo + method.

+
@@ -490,15 +495,15 @@

At the high-level, LLVM code is translated to a machine specific -representation formed out of -MachineFunction, -MachineBasicBlock, and MachineInstr instances -(defined in include/llvm/CodeGen). This representation is completely -target agnostic, representing instructions in their most abstract form: an -opcode and a series of operands. This representation is designed to support -both an SSA representation for machine code, as well as a register allocated, -non-SSA form.

+ representation formed out of + MachineFunction, + MachineBasicBlock, + and MachineInstr instances (defined + in include/llvm/CodeGen). This representation is completely target + agnostic, representing instructions in their most abstract form: an opcode + and a series of operands. This representation is designed to support both an + SSA representation for machine code, as well as a register allocated, non-SSA + form.

@@ -510,34 +515,34 @@

Target machine instructions are represented as instances of the -MachineInstr class. This class is an extremely abstract way of -representing machine instructions. In particular, it only keeps track of -an opcode number and a set of operands.

- -

The opcode number is a simple unsigned integer that only has meaning to a -specific backend. All of the instructions for a target should be defined in -the *InstrInfo.td file for the target. The opcode enum values -are auto-generated from this description. The MachineInstr class does -not have any information about how to interpret the instruction (i.e., what the -semantics of the instruction are); for that you must refer to the -TargetInstrInfo class.

- -

The operands of a machine instruction can be of several different types: -a register reference, a constant integer, a basic block reference, etc. In -addition, a machine operand should be marked as a def or a use of the value -(though only registers are allowed to be defs).

+ MachineInstr class. This class is an extremely abstract way of + representing machine instructions. In particular, it only keeps track of an + opcode number and a set of operands.

+ +

The opcode number is a simple unsigned integer that only has meaning to a + specific backend. All of the instructions for a target should be defined in + the *InstrInfo.td file for the target. The opcode enum values are + auto-generated from this description. The MachineInstr class does + not have any information about how to interpret the instruction (i.e., what + the semantics of the instruction are); for that you must refer to the + TargetInstrInfo class.

+ +

The operands of a machine instruction can be of several different types: a + register reference, a constant integer, a basic block reference, etc. In + addition, a machine operand should be marked as a def or a use of the value + (though only registers are allowed to be defs).

By convention, the LLVM code generator orders instruction operands so that -all register definitions come before the register uses, even on architectures -that are normally printed in other orders. For example, the SPARC add -instruction: "add %i1, %i2, %i3" adds the "%i1", and "%i2" registers -and stores the result into the "%i3" register. In the LLVM code generator, -the operands should be stored as "%i3, %i1, %i2": with the destination -first.

- -

Keeping destination (definition) operands at the beginning of the operand -list has several advantages. In particular, the debugging printer will print -the instruction like this:

+ all register definitions come before the register uses, even on architectures + that are normally printed in other orders. For example, the SPARC add + instruction: "add %i1, %i2, %i3" adds the "%i1", and "%i2" registers + and stores the result into the "%i3" register. In the LLVM code generator, + the operands should be stored as "%i3, %i1, %i2": with the + destination first.

+ +

Keeping destination (definition) operands at the beginning of the operand + list has several advantages. In particular, the debugging printer will print + the instruction like this:

@@ -545,9 +550,8 @@
 
-

Also if the first operand is a def, it is easier to create instructions whose only def is the first -operand.

+

Also if the first operand is a def, it is easier to create + instructions whose only def is the first operand.

@@ -559,9 +563,9 @@

Machine instructions are created by using the BuildMI functions, -located in the include/llvm/CodeGen/MachineInstrBuilder.h file. The -BuildMI functions make it easy to build arbitrary machine -instructions. Usage of the BuildMI functions look like this:

+ located in the include/llvm/CodeGen/MachineInstrBuilder.h file. The + BuildMI functions make it easy to build arbitrary machine + instructions. Usage of the BuildMI functions look like this:

@@ -588,11 +592,11 @@
 

The key thing to remember with the BuildMI functions is that you -have to specify the number of operands that the machine instruction will take. -This allows for efficient memory allocation. You also need to specify if -operands default to be uses of values, not definitions. If you need to add a -definition operand (other than the optional destination register), you must -explicitly mark it as such:

+ have to specify the number of operands that the machine instruction will + take. This allows for efficient memory allocation. You also need to specify + if operands default to be uses of values, not definitions. If you need to + add a definition operand (other than the optional destination register), you + must explicitly mark it as such:

@@ -610,13 +614,14 @@
 

One important issue that the code generator needs to be aware of is the -presence of fixed registers. In particular, there are often places in the -instruction stream where the register allocator must arrange for a -particular value to be in a particular register. This can occur due to -limitations of the instruction set (e.g., the X86 can only do a 32-bit divide -with the EAX/EDX registers), or external factors like calling -conventions. In any case, the instruction selector should emit code that -copies a virtual register into or out of a physical register when needed.

+ presence of fixed registers. In particular, there are often places in the + instruction stream where the register allocator must arrange for a + particular value to be in a particular register. This can occur due to + limitations of the instruction set (e.g., the X86 can only do a 32-bit divide + with the EAX/EDX registers), or external factors like + calling conventions. In any case, the instruction selector should emit code + that copies a virtual register into or out of a physical register when + needed.

For example, consider this simple LLVM example:

@@ -630,8 +635,8 @@

The X86 instruction selector produces this machine code for the div -and ret (use -"llc X.bc -march=x86 -print-machineinstrs" to get this):

+ and ret (use "llc X.bc -march=x86 -print-machineinstrs" to + get this):

@@ -648,9 +653,9 @@
 
-

By the end of code generation, the register allocator has coalesced -the registers and deleted the resultant identity moves producing the -following code:

+

By the end of code generation, the register allocator has coalesced the + registers and deleted the resultant identity moves producing the following + code:

@@ -662,14 +667,14 @@
 
-

This approach is extremely general (if it can handle the X86 architecture, -it can handle anything!) and allows all of the target specific -knowledge about the instruction stream to be isolated in the instruction -selector. Note that physical registers should have a short lifetime for good -code generation, and all physical registers are assumed dead on entry to and -exit from basic blocks (before register allocation). Thus, if you need a value -to be live across basic block boundaries, it must live in a virtual -register.

+

This approach is extremely general (if it can handle the X86 architecture, it + can handle anything!) and allows all of the target specific knowledge about + the instruction stream to be isolated in the instruction selector. Note that + physical registers should have a short lifetime for good code generation, and + all physical registers are assumed dead on entry to and exit from basic + blocks (before register allocation). Thus, if you need a value to be live + across basic block boundaries, it must live in a virtual + register.

@@ -680,14 +685,14 @@
-

MachineInstr's are initially selected in SSA-form, and -are maintained in SSA-form until register allocation happens. For the most -part, this is trivially simple since LLVM is already in SSA form; LLVM PHI nodes -become machine code PHI nodes, and virtual registers are only allowed to have a -single definition.

+

MachineInstr's are initially selected in SSA-form, and are + maintained in SSA-form until register allocation happens. For the most part, + this is trivially simple since LLVM is already in SSA form; LLVM PHI nodes + become machine code PHI nodes, and virtual registers are only allowed to have + a single definition.

-

After register allocation, machine code is no longer in SSA-form because there -are no virtual registers left in the code.

+

After register allocation, machine code is no longer in SSA-form because + there are no virtual registers left in the code.

@@ -699,12 +704,12 @@

The MachineBasicBlock class contains a list of machine instructions -(MachineInstr instances). It roughly -corresponds to the LLVM code input to the instruction selector, but there can be -a one-to-many mapping (i.e. one LLVM basic block can map to multiple machine -basic blocks). The MachineBasicBlock class has a -"getBasicBlock" method, which returns the LLVM basic block that it -comes from.

+ (MachineInstr instances). It roughly + corresponds to the LLVM code input to the instruction selector, but there can + be a one-to-many mapping (i.e. one LLVM basic block can map to multiple + machine basic blocks). The MachineBasicBlock class has a + "getBasicBlock" method, which returns the LLVM basic block that it + comes from.

@@ -716,12 +721,13 @@

The MachineFunction class contains a list of machine basic blocks -(MachineBasicBlock instances). It -corresponds one-to-one with the LLVM function input to the instruction selector. -In addition to a list of basic blocks, the MachineFunction contains a -a MachineConstantPool, a MachineFrameInfo, a -MachineFunctionInfo, and a MachineRegisterInfo. See -include/llvm/CodeGen/MachineFunction.h for more information.

+ (MachineBasicBlock instances). It + corresponds one-to-one with the LLVM function input to the instruction + selector. In addition to a list of basic blocks, + the MachineFunction contains a a MachineConstantPool, + a MachineFrameInfo, a MachineFunctionInfo, and a + MachineRegisterInfo. See + include/llvm/CodeGen/MachineFunction.h for more information.

@@ -733,9 +739,9 @@
-

This section documents the phases described in the high-level design of the code generator. It -explains how they work and some of the rationale behind their design.

+

This section documents the phases described in the + high-level design of the code generator. + It explains how they work and some of the rationale behind their design.

@@ -745,17 +751,17 @@
-

-Instruction Selection is the process of translating LLVM code presented to the -code generator into target-specific machine instructions. There are several -well-known ways to do this in the literature. LLVM uses a SelectionDAG based -instruction selector. -

- -

Portions of the DAG instruction selector are generated from the target -description (*.td) files. Our goal is for the entire instruction -selector to be generated from these .td files, though currently -there are still things that require custom C++ code.

+ +

Instruction Selection is the process of translating LLVM code presented to + the code generator into target-specific machine instructions. There are + several well-known ways to do this in the literature. LLVM uses a + SelectionDAG based instruction selector.

+ +

Portions of the DAG instruction selector are generated from the target + description (*.td) files. Our goal is for the entire instruction + selector to be generated from these .td files, though currently + there are still things that require custom C++ code.

+
@@ -766,57 +772,57 @@

The SelectionDAG provides an abstraction for code representation in a way -that is amenable to instruction selection using automatic techniques -(e.g. dynamic-programming based optimal pattern matching selectors). It is also -well-suited to other phases of code generation; in particular, -instruction scheduling (SelectionDAG's are very close to scheduling DAGs -post-selection). Additionally, the SelectionDAG provides a host representation -where a large variety of very-low-level (but target-independent) -optimizations may be -performed; ones which require extensive information about the instructions -efficiently supported by the target.

+ that is amenable to instruction selection using automatic techniques + (e.g. dynamic-programming based optimal pattern matching selectors). It is + also well-suited to other phases of code generation; in particular, + instruction scheduling (SelectionDAG's are very close to scheduling DAGs + post-selection). Additionally, the SelectionDAG provides a host + representation where a large variety of very-low-level (but + target-independent) optimizations may be + performed; ones which require extensive information about the instructions + efficiently supported by the target.

The SelectionDAG is a Directed-Acyclic-Graph whose nodes are instances of the -SDNode class. The primary payload of the SDNode is its -operation code (Opcode) that indicates what operation the node performs and -the operands to the operation. -The various operation node types are described at the top of the -include/llvm/CodeGen/SelectionDAGNodes.h file.

- -

Although most operations define a single value, each node in the graph may -define multiple values. For example, a combined div/rem operation will define -both the dividend and the remainder. Many other situations require multiple -values as well. Each node also has some number of operands, which are edges -to the node defining the used value. Because nodes may define multiple values, -edges are represented by instances of the SDValue class, which is -a <SDNode, unsigned> pair, indicating the node and result -value being used, respectively. Each value produced by an SDNode has -an associated MVT (Machine Value Type) indicating what the type of the -value is.

+ SDNode class. The primary payload of the SDNode is its + operation code (Opcode) that indicates what operation the node performs and + the operands to the operation. The various operation node types are + described at the top of the include/llvm/CodeGen/SelectionDAGNodes.h + file.

+ +

Although most operations define a single value, each node in the graph may + define multiple values. For example, a combined div/rem operation will + define both the dividend and the remainder. Many other situations require + multiple values as well. Each node also has some number of operands, which + are edges to the node defining the used value. Because nodes may define + multiple values, edges are represented by instances of the SDValue + class, which is a <SDNode, unsigned> pair, indicating the node + and result value being used, respectively. Each value produced by + an SDNode has an associated MVT (Machine Value Type) + indicating what the type of the value is.

SelectionDAGs contain two different kinds of values: those that represent -data flow and those that represent control flow dependencies. Data values are -simple edges with an integer or floating point value type. Control edges are -represented as "chain" edges which are of type MVT::Other. These edges -provide an ordering between nodes that have side effects (such as -loads, stores, calls, returns, etc). All nodes that have side effects should -take a token chain as input and produce a new one as output. By convention, -token chain inputs are always operand #0, and chain results are always the last -value produced by an operation.

+ data flow and those that represent control flow dependencies. Data values + are simple edges with an integer or floating point value type. Control edges + are represented as "chain" edges which are of type MVT::Other. + These edges provide an ordering between nodes that have side effects (such as + loads, stores, calls, returns, etc). All nodes that have side effects should + take a token chain as input and produce a new one as output. By convention, + token chain inputs are always operand #0, and chain results are always the + last value produced by an operation.

A SelectionDAG has designated "Entry" and "Root" nodes. The Entry node is -always a marker node with an Opcode of ISD::EntryToken. The Root node -is the final side-effecting node in the token chain. For example, in a single -basic block function it would be the return node.

+ always a marker node with an Opcode of ISD::EntryToken. The Root + node is the final side-effecting node in the token chain. For example, in a + single basic block function it would be the return node.

One important concept for SelectionDAGs is the notion of a "legal" vs. -"illegal" DAG. A legal DAG for a target is one that only uses supported -operations and supported types. On a 32-bit PowerPC, for example, a DAG with -a value of type i1, i8, i16, or i64 would be illegal, as would a DAG that uses a -SREM or UREM operation. The -legalize types and -legalize operations phases are -responsible for turning an illegal DAG into a legal DAG.

+ "illegal" DAG. A legal DAG for a target is one that only uses supported + operations and supported types. On a 32-bit PowerPC, for example, a DAG with + a value of type i1, i8, i16, or i64 would be illegal, as would a DAG that + uses a SREM or UREM operation. The + legalize types and + legalize operations phases are + responsible for turning an illegal DAG into a legal DAG.

@@ -830,63 +836,74 @@

SelectionDAG-based instruction selection consists of the following steps:

    -
  1. Build initial DAG - This stage - performs a simple translation from the input LLVM code to an illegal - SelectionDAG.
  2. -
  3. Optimize SelectionDAG - This stage - performs simple optimizations on the SelectionDAG to simplify it, and - recognize meta instructions (like rotates and div/rem - pairs) for targets that support these meta operations. This makes the - resultant code more efficient and the select - instructions from DAG phase (below) simpler.
  4. -
  5. Legalize SelectionDAG Types - This - stage transforms SelectionDAG nodes to eliminate any types that are - unsupported on the target.
  6. -
  7. Optimize SelectionDAG - The - SelectionDAG optimizer is run to clean up redundancies exposed - by type legalization.
  8. -
  9. Legalize SelectionDAG Types - This - stage transforms SelectionDAG nodes to eliminate any types that are - unsupported on the target.
  10. -
  11. Optimize SelectionDAG - The - SelectionDAG optimizer is run to eliminate inefficiencies introduced - by operation legalization.
  12. -
  13. Select instructions from DAG - Finally, - the target instruction selector matches the DAG operations to target - instructions. This process translates the target-independent input DAG into - another DAG of target instructions.
  14. -
  15. SelectionDAG Scheduling and Formation - - The last phase assigns a linear order to the instructions in the - target-instruction DAG and emits them into the MachineFunction being - compiled. This step uses traditional prepass scheduling techniques.
  16. +
  17. Build initial DAG — This stage + performs a simple translation from the input LLVM code to an illegal + SelectionDAG.
  18. + +
  19. Optimize SelectionDAG — This + stage performs simple optimizations on the SelectionDAG to simplify it, + and recognize meta instructions (like rotates + and div/rem pairs) for targets that support these meta + operations. This makes the resultant code more efficient and + the select instructions from DAG phase + (below) simpler.
  20. + +
  21. Legalize SelectionDAG Types + — This stage transforms SelectionDAG nodes to eliminate any types + that are unsupported on the target.
  22. + +
  23. Optimize SelectionDAG — The + SelectionDAG optimizer is run to clean up redundancies exposed by type + legalization.
  24. + +
  25. Legalize SelectionDAG Types — + This stage transforms SelectionDAG nodes to eliminate any types that are + unsupported on the target.
  26. + +
  27. Optimize SelectionDAG — The + SelectionDAG optimizer is run to eliminate inefficiencies introduced by + operation legalization.
  28. + +
  29. Select instructions from DAG — + Finally, the target instruction selector matches the DAG operations to + target instructions. This process translates the target-independent input + DAG into another DAG of target instructions.
  30. + +
  31. SelectionDAG Scheduling and Formation + — The last phase assigns a linear order to the instructions in the + target-instruction DAG and emits them into the MachineFunction being + compiled. This step uses traditional prepass scheduling techniques.

After all of these steps are complete, the SelectionDAG is destroyed and the -rest of the code generation passes are run.

+ rest of the code generation passes are run.

-

One great way to visualize what is going on here is to take advantage of a -few LLC command line options. The following options pop up a window displaying -the SelectionDAG at specific times (if you only get errors printed to the console -while using this, you probably -need to configure your system to -add support for it).

+

One great way to visualize what is going on here is to take advantage of a + few LLC command line options. The following options pop up a window + displaying the SelectionDAG at specific times (if you only get errors printed + to the console while using this, you probably + need to configure your system + to add support for it).

    -
  • -view-dag-combine1-dags displays the DAG after being built, before - the first optimization pass.
  • -
  • -view-legalize-dags displays the DAG before Legalization.
  • -
  • -view-dag-combine2-dags displays the DAG before the second - optimization pass.
  • -
  • -view-isel-dags displays the DAG before the Select phase.
  • -
  • -view-sched-dags displays the DAG before Scheduling.
  • +
  • -view-dag-combine1-dags displays the DAG after being built, + before the first optimization pass.
  • + +
  • -view-legalize-dags displays the DAG before Legalization.
  • + +
  • -view-dag-combine2-dags displays the DAG before the second + optimization pass.
  • + +
  • -view-isel-dags displays the DAG before the Select phase.
  • + +
  • -view-sched-dags displays the DAG before Scheduling.

The -view-sunit-dags displays the Scheduler's dependency graph. -This graph is based on the final SelectionDAG, with nodes that must be -scheduled together bundled into a single scheduling-unit node, and with -immediate operands and other nodes that aren't relevant for scheduling -omitted. -

+ This graph is based on the final SelectionDAG, with nodes that must be + scheduled together bundled into a single scheduling-unit node, and with + immediate operands and other nodes that aren't relevant for scheduling + omitted.

@@ -898,14 +915,15 @@

The initial SelectionDAG is naïvely peephole expanded from the LLVM -input by the SelectionDAGLowering class in the -lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp file. The intent of this -pass is to expose as much low-level, target-specific details to the SelectionDAG -as possible. This pass is mostly hard-coded (e.g. an LLVM add turns -into an SDNode add while a getelementptr is expanded into the -obvious arithmetic). This pass requires target-specific hooks to lower calls, -returns, varargs, etc. For these features, the -TargetLowering interface is used.

+ input by the SelectionDAGLowering class in the + lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp file. The intent of + this pass is to expose as much low-level, target-specific details to the + SelectionDAG as possible. This pass is mostly hard-coded (e.g. an + LLVM add turns into an SDNode add while a + getelementptr is expanded into the obvious arithmetic). This pass + requires target-specific hooks to lower calls, returns, varargs, etc. For + these features, the TargetLowering + interface is used.

@@ -917,28 +935,27 @@

The Legalize phase is in charge of converting a DAG to only use the types -that are natively supported by the target.

+ that are natively supported by the target.

-

There are two main ways of converting values of unsupported scalar types - to values of supported types: converting small types to - larger types ("promoting"), and breaking up large integer types - into smaller ones ("expanding"). For example, a target might require - that all f32 values are promoted to f64 and that all i1/i8/i16 values - are promoted to i32. The same target might require that all i64 values - be expanded into pairs of i32 values. These changes can insert sign and - zero extensions as needed to make sure that the final code has the same - behavior as the input.

- -

There are two main ways of converting values of unsupported vector types - to value of supported types: splitting vector types, multiple times if - necessary, until a legal type is found, and extending vector types by - adding elements to the end to round them out to legal types ("widening"). - If a vector gets split all the way down to single-element parts with - no supported vector type being found, the elements are converted to - scalars ("scalarizing").

+

There are two main ways of converting values of unsupported scalar types to + values of supported types: converting small types to larger types + ("promoting"), and breaking up large integer types into smaller ones + ("expanding"). For example, a target might require that all f32 values are + promoted to f64 and that all i1/i8/i16 values are promoted to i32. The same + target might require that all i64 values be expanded into pairs of i32 + values. These changes can insert sign and zero extensions as needed to make + sure that the final code has the same behavior as the input.

+ +

There are two main ways of converting values of unsupported vector types to + value of supported types: splitting vector types, multiple times if + necessary, until a legal type is found, and extending vector types by adding + elements to the end to round them out to legal types ("widening"). If a + vector gets split all the way down to single-element parts with no supported + vector type being found, the elements are converted to scalars + ("scalarizing").

-

A target implementation tells the legalizer which types are supported - (and which register class to use for them) by calling the +

A target implementation tells the legalizer which types are supported (and + which register class to use for them) by calling the addRegisterClass method in its TargetLowering constructor.

@@ -951,16 +968,15 @@

The Legalize phase is in charge of converting a DAG to only use the -operations that are natively supported by the target.

+ operations that are natively supported by the target.

-

Targets often have weird constraints, such as not supporting every - operation on every supported datatype (e.g. X86 does not support byte - conditional moves and PowerPC does not support sign-extending loads from - a 16-bit memory location). Legalize takes care of this by open-coding - another sequence of operations to emulate the operation ("expansion"), by - promoting one type to a larger type that supports the operation - ("promotion"), or by using a target-specific hook to implement the - legalization ("custom").

+

Targets often have weird constraints, such as not supporting every operation + on every supported datatype (e.g. X86 does not support byte conditional moves + and PowerPC does not support sign-extending loads from a 16-bit memory + location). Legalize takes care of this by open-coding another sequence of + operations to emulate the operation ("expansion"), by promoting one type to a + larger type that supports the operation ("promotion"), or by using a + target-specific hook to implement the legalization ("custom").

A target implementation tells the legalizer which operations are not supported (and which of the above three actions to take) by calling the @@ -968,11 +984,11 @@ constructor.

Prior to the existence of the Legalize passes, we required that every target -selector supported and handled every -operator and type even if they are not natively supported. The introduction of -the Legalize phases allows all of the canonicalization patterns to be shared -across targets, and makes it very easy to optimize the canonicalized code -because it is still in the form of a DAG.

+ selector supported and handled every + operator and type even if they are not natively supported. The introduction + of the Legalize phases allows all of the canonicalization patterns to be + shared across targets, and makes it very easy to optimize the canonicalized + code because it is still in the form of a DAG.

@@ -984,34 +1000,30 @@
-

The SelectionDAG optimization phase is run multiple times for code generation, -immediately after the DAG is built and once after each legalization. The first -run of the pass allows the initial code to be cleaned up (e.g. performing -optimizations that depend on knowing that the operators have restricted type -inputs). Subsequent runs of the pass clean up the messy code generated by the -Legalize passes, which allows Legalize to be very simple (it can focus on making -code legal instead of focusing on generating good and legal code).

+

The SelectionDAG optimization phase is run multiple times for code + generation, immediately after the DAG is built and once after each + legalization. The first run of the pass allows the initial code to be + cleaned up (e.g. performing optimizations that depend on knowing that the + operators have restricted type inputs). Subsequent runs of the pass clean up + the messy code generated by the Legalize passes, which allows Legalize to be + very simple (it can focus on making code legal instead of focusing on + generating good and legal code).

One important class of optimizations performed is optimizing inserted sign -and zero extension instructions. We currently use ad-hoc techniques, but could -move to more rigorous techniques in the future. Here are some good papers on -the subject:

- -

- "Widening - integer arithmetic"
- Kevin Redwine and Norman Ramsey
- International Conference on Compiler Construction (CC) 2004 -

- - -

- "Effective - sign extension elimination"
- Motohiro Kawahito, Hideaki Komatsu, and Toshio Nakatani
- Proceedings of the ACM SIGPLAN 2002 Conference on Programming Language Design - and Implementation. -

+ and zero extension instructions. We currently use ad-hoc techniques, but + could move to more rigorous techniques in the future. Here are some good + papers on the subject:

+ +

"Widening + integer arithmetic"
+ Kevin Redwine and Norman Ramsey
+ International Conference on Compiler Construction (CC) 2004

+ +

"Effective + sign extension elimination"
+ Motohiro Kawahito, Hideaki Komatsu, and Toshio Nakatani
+ Proceedings of the ACM SIGPLAN 2002 Conference on Programming Language Design + and Implementation.

@@ -1023,9 +1035,9 @@

The Select phase is the bulk of the target-specific code for instruction -selection. This phase takes a legal SelectionDAG as input, pattern matches the -instructions supported by the target to this DAG, and produces a new DAG of -target code. For example, consider the following LLVM fragment:

+ selection. This phase takes a legal SelectionDAG as input, pattern matches + the instructions supported by the target to this DAG, and produces a new DAG + of target code. For example, consider the following LLVM fragment:

@@ -1036,7 +1048,7 @@
 

This LLVM code corresponds to a SelectionDAG that looks basically like -this:

+ this:

@@ -1044,9 +1056,9 @@
 
-

If a target supports floating point multiply-and-add (FMA) operations, one -of the adds can be merged with the multiply. On the PowerPC, for example, the -output of the instruction selector might look like this DAG:

+

If a target supports floating point multiply-and-add (FMA) operations, one of + the adds can be merged with the multiply. On the PowerPC, for example, the + output of the instruction selector might look like this DAG:

@@ -1075,92 +1087,104 @@
 

The portion of the instruction definition in bold indicates the pattern used -to match the instruction. The DAG operators (like fmul/fadd) -are defined in the lib/Target/TargetSelectionDAG.td file. -"F4RC" is the register class of the input and result values.

- -

The TableGen DAG instruction selector generator reads the instruction -patterns in the .td file and automatically builds parts of the pattern -matching code for your target. It has the following strengths:

+ to match the instruction. The DAG operators + (like fmul/fadd) are defined in + the lib/Target/TargetSelectionDAG.td file. "F4RC" is the + register class of the input and result values.

+ +

The TableGen DAG instruction selector generator reads the instruction + patterns in the .td file and automatically builds parts of the + pattern matching code for your target. It has the following strengths:

    -
  • At compiler-compiler time, it analyzes your instruction patterns and tells - you if your patterns make sense or not.
  • -
  • It can handle arbitrary constraints on operands for the pattern match. In - particular, it is straight-forward to say things like "match any immediate - that is a 13-bit sign-extended value". For examples, see the - immSExt16 and related tblgen classes in the PowerPC - backend.
  • -
  • It knows several important identities for the patterns defined. For - example, it knows that addition is commutative, so it allows the - FMADDS pattern above to match "(fadd X, (fmul Y, Z))" as - well as "(fadd (fmul X, Y), Z)", without the target author having - to specially handle this case.
  • -
  • It has a full-featured type-inferencing system. In particular, you should - rarely have to explicitly tell the system what type parts of your patterns - are. In the FMADDS case above, we didn't have to tell - tblgen that all of the nodes in the pattern are of type 'f32'. It - was able to infer and propagate this knowledge from the fact that - F4RC has type 'f32'.
  • -
  • Targets can define their own (and rely on built-in) "pattern fragments". - Pattern fragments are chunks of reusable patterns that get inlined into your - patterns during compiler-compiler time. For example, the integer - "(not x)" operation is actually defined as a pattern fragment that - expands as "(xor x, -1)", since the SelectionDAG does not have a - native 'not' operation. Targets can define their own short-hand - fragments as they see fit. See the definition of 'not' and - 'ineg' for examples.
  • -
  • In addition to instructions, targets can specify arbitrary patterns that - map to one or more instructions using the 'Pat' class. For example, - the PowerPC has no way to load an arbitrary integer immediate into a - register in one instruction. To tell tblgen how to do this, it defines: -
    -
    -
    -
    +  
  • At compiler-compiler time, it analyzes your instruction patterns and tells + you if your patterns make sense or not.
  • + +
  • It can handle arbitrary constraints on operands for the pattern match. In + particular, it is straight-forward to say things like "match any immediate + that is a 13-bit sign-extended value". For examples, see the + immSExt16 and related tblgen classes in the PowerPC + backend.
  • + +
  • It knows several important identities for the patterns defined. For + example, it knows that addition is commutative, so it allows the + FMADDS pattern above to match "(fadd X, (fmul Y, Z))" as + well as "(fadd (fmul X, Y), Z)", without the target author having + to specially handle this case.
  • + +
  • It has a full-featured type-inferencing system. In particular, you should + rarely have to explicitly tell the system what type parts of your patterns + are. In the FMADDS case above, we didn't have to tell + tblgen that all of the nodes in the pattern are of type 'f32'. + It was able to infer and propagate this knowledge from the fact that + F4RC has type 'f32'.
  • + +
  • Targets can define their own (and rely on built-in) "pattern fragments". + Pattern fragments are chunks of reusable patterns that get inlined into + your patterns during compiler-compiler time. For example, the integer + "(not x)" operation is actually defined as a pattern fragment + that expands as "(xor x, -1)", since the SelectionDAG does not + have a native 'not' operation. Targets can define their own + short-hand fragments as they see fit. See the definition of + 'not' and 'ineg' for examples.
  • + +
  • In addition to instructions, targets can specify arbitrary patterns that + map to one or more instructions using the 'Pat' class. For example, the + PowerPC has no way to load an arbitrary integer immediate into a register + in one instruction. To tell tblgen how to do this, it defines: +
    +
    +
    +
     // Arbitrary immediate support.  Implement in terms of LIS/ORI.
     def : Pat<(i32 imm:$imm),
               (ORI (LIS (HI16 imm:$imm)), (LO16 imm:$imm))>;
    -    
    -
    -
    - If none of the single-instruction patterns for loading an immediate into a - register match, this will be used. This rule says "match an arbitrary i32 - immediate, turning it into an ORI ('or a 16-bit immediate') and an - LIS ('load 16-bit immediate, where the immediate is shifted to the - left 16 bits') instruction". To make this work, the - LO16/HI16 node transformations are used to manipulate the - input immediate (in this case, take the high or low 16-bits of the - immediate).
  • -
  • While the system does automate a lot, it still allows you to write custom - C++ code to match special cases if there is something that is hard to - express.
  • +
    +
    +
    + If none of the single-instruction patterns for loading an immediate into a + register match, this will be used. This rule says "match an arbitrary i32 + immediate, turning it into an ORI ('or a 16-bit immediate') and + an LIS ('load 16-bit immediate, where the immediate is shifted to + the left 16 bits') instruction". To make this work, the + LO16/HI16 node transformations are used to manipulate + the input immediate (in this case, take the high or low 16-bits of the + immediate).
  • + +
  • While the system does automate a lot, it still allows you to write custom + C++ code to match special cases if there is something that is hard to + express.

While it has many strengths, the system currently has some limitations, -primarily because it is a work in progress and is not yet finished:

+ primarily because it is a work in progress and is not yet finished:

    -
  • Overall, there is no way to define or match SelectionDAG nodes that define - multiple values (e.g. ADD_PARTS, LOAD, CALL, - etc). This is the biggest reason that you currently still have to - write custom C++ code for your instruction selector.
  • -
  • There is no great way to support matching complex addressing modes yet. In - the future, we will extend pattern fragments to allow them to define - multiple values (e.g. the four operands of the X86 - addressing mode, which are currently matched with custom C++ code). - In addition, we'll extend fragments so that a - fragment can match multiple different patterns.
  • -
  • We don't automatically infer flags like isStore/isLoad yet.
  • -
  • We don't automatically generate the set of supported registers and - operations for the Legalizer yet.
  • -
  • We don't have a way of tying in custom legalized nodes yet.
  • +
  • Overall, there is no way to define or match SelectionDAG nodes that define + multiple values (e.g. ADD_PARTS, LOAD, CALL, + etc). This is the biggest reason that you currently still have + to write custom C++ code for your instruction selector.
  • + +
  • There is no great way to support matching complex addressing modes yet. + In the future, we will extend pattern fragments to allow them to define + multiple values (e.g. the four operands of the X86 + addressing mode, which are currently matched with custom C++ code). + In addition, we'll extend fragments so that a fragment can match multiple + different patterns.
  • + +
  • We don't automatically infer flags like isStore/isLoad yet.
  • + +
  • We don't automatically generate the set of supported registers and + operations for the Legalizer + yet.
  • + +
  • We don't have a way of tying in custom legalized nodes yet.

Despite these limitations, the instruction selector generator is still quite -useful for most of the binary and logical operations in typical instruction -sets. If you run into any problems or can't figure out how to do something, -please let Chris know!

+ useful for most of the binary and logical operations in typical instruction + sets. If you run into any problems or can't figure out how to do something, + please let Chris know!

@@ -1172,15 +1196,16 @@

The scheduling phase takes the DAG of target instructions from the selection -phase and assigns an order. The scheduler can pick an order depending on -various constraints of the machines (i.e. order for minimal register pressure or -try to cover instruction latencies). Once an order is established, the DAG is -converted to a list of MachineInstrs and -the SelectionDAG is destroyed.

+ phase and assigns an order. The scheduler can pick an order depending on + various constraints of the machines (i.e. order for minimal register pressure + or try to cover instruction latencies). Once an order is established, the + DAG is converted to a list + of MachineInstrs and the SelectionDAG is + destroyed.

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

+ phase, but is tied to it closely in the code because it operates on + SelectionDAGs.

@@ -1192,8 +1217,9 @@
    -
  1. Optional function-at-a-time selection.
  2. -
  3. Auto-generate entire selector from .td file.
  4. +
  5. Optional function-at-a-time selection.
  6. + +
  7. Auto-generate entire selector from .td file.
@@ -1212,10 +1238,10 @@

Live Intervals are the ranges (intervals) where a variable is live. -They are used by some register allocator passes to -determine if two or more virtual registers which require the same physical -register are live at the same point in the program (i.e., they conflict). When -this situation occurs, one virtual register must be spilled.

+ They are used by some register allocator passes to + determine if two or more virtual registers which require the same physical + register are live at the same point in the program (i.e., they conflict). + When this situation occurs, one virtual register must be spilled.

@@ -1226,43 +1252,42 @@
-

The first step in determining the live intervals of variables is to -calculate the set of registers that are immediately dead after the -instruction (i.e., the instruction calculates the value, but it is -never used) and the set of registers that are used by the instruction, -but are never used after the instruction (i.e., they are killed). Live -variable information is computed for each virtual register and -register allocatable physical register in the function. This -is done in a very efficient manner because it uses SSA to sparsely -compute lifetime information for virtual registers (which are in SSA -form) and only has to track physical registers within a block. Before -register allocation, LLVM can assume that physical registers are only -live within a single basic block. This allows it to do a single, -local analysis to resolve physical register lifetimes within each -basic block. If a physical register is not register allocatable (e.g., -a stack pointer or condition codes), it is not tracked.

- -

Physical registers may be live in to or out of a function. Live in values -are typically arguments in registers. Live out values are typically return -values in registers. Live in values are marked as such, and are given a dummy -"defining" instruction during live intervals analysis. If the last basic block -of a function is a return, then it's marked as using all live out -values in the function.

- -

PHI nodes need to be handled specially, because the calculation -of the live variable information from a depth first traversal of the CFG of -the function won't guarantee that a virtual register used by the PHI -node is defined before it's used. When a PHI node is encountered, only -the definition is handled, because the uses will be handled in other basic -blocks.

+

The first step in determining the live intervals of variables is to calculate + the set of registers that are immediately dead after the instruction (i.e., + the instruction calculates the value, but it is never used) and the set of + registers that are used by the instruction, but are never used after the + instruction (i.e., they are killed). Live variable information is computed + for each virtual register and register allocatable physical + register in the function. This is done in a very efficient manner because it + uses SSA to sparsely compute lifetime information for virtual registers + (which are in SSA form) and only has to track physical registers within a + block. Before register allocation, LLVM can assume that physical registers + are only live within a single basic block. This allows it to do a single, + local analysis to resolve physical register lifetimes within each basic + block. If a physical register is not register allocatable (e.g., a stack + pointer or condition codes), it is not tracked.

+ +

Physical registers may be live in to or out of a function. Live in values are + typically arguments in registers. Live out values are typically return values + in registers. Live in values are marked as such, and are given a dummy + "defining" instruction during live intervals analysis. If the last basic + block of a function is a return, then it's marked as using all live + out values in the function.

+ +

PHI nodes need to be handled specially, because the calculation of + the live variable information from a depth first traversal of the CFG of the + function won't guarantee that a virtual register used by the PHI + node is defined before it's used. When a PHI node is encountered, + only the definition is handled, because the uses will be handled in other + basic blocks.

For each PHI node of the current basic block, we simulate an -assignment at the end of the current basic block and traverse the successor -basic blocks. If a successor basic block has a PHI node and one of -the PHI node's operands is coming from the current basic block, -then the variable is marked as alive within the current basic block -and all of its predecessor basic blocks, until the basic block with the -defining instruction is encountered.

+ assignment at the end of the current basic block and traverse the successor + basic blocks. If a successor basic block has a PHI node and one of + the PHI node's operands is coming from the current basic block, then + the variable is marked as alive within the current basic block and all + of its predecessor basic blocks, until the basic block with the defining + instruction is encountered.

@@ -1274,13 +1299,13 @@

We now have the information available to perform the live intervals analysis -and build the live intervals themselves. We start off by numbering the basic -blocks and machine instructions. We then handle the "live-in" values. These -are in physical registers, so the physical register is assumed to be killed by -the end of the basic block. Live intervals for virtual registers are computed -for some ordering of the machine instructions [1, N]. A live interval -is an interval [i, j), where 1 <= i <= j < N, for which a -variable is live.

+ and build the live intervals themselves. We start off by numbering the basic + blocks and machine instructions. We then handle the "live-in" values. These + are in physical registers, so the physical register is assumed to be killed + by the end of the basic block. Live intervals for virtual registers are + computed for some ordering of the machine instructions [1, N]. A + live interval is an interval [i, j), where 1 <= i <= j + < N, for which a variable is live.

More to come...

@@ -1294,13 +1319,12 @@

The Register Allocation problem consists in mapping a program -Pv, that can use an unbounded number of virtual -registers, to a program Pp that contains a finite -(possibly small) number of physical registers. Each target architecture has -a different number of physical registers. If the number of physical -registers is not enough to accommodate all the virtual registers, some of -them will have to be mapped into memory. These virtuals are called -spilled virtuals.

+ Pv, that can use an unbounded number of virtual registers, + to a program Pp that contains a finite (possibly small) + number of physical registers. Each target architecture has a different number + of physical registers. If the number of physical registers is not enough to + accommodate all the virtual registers, some of them will have to be mapped + into memory. These virtuals are called spilled virtuals.

@@ -1312,34 +1336,30 @@
-

In LLVM, physical registers are denoted by integer numbers that -normally range from 1 to 1023. To see how this numbering is defined -for a particular architecture, you can read the -GenRegisterNames.inc file for that architecture. For -instance, by inspecting -lib/Target/X86/X86GenRegisterNames.inc we see that the 32-bit -register EAX is denoted by 15, and the MMX register -MM0 is mapped to 48.

- -

Some architectures contain registers that share the same physical -location. A notable example is the X86 platform. For instance, in the -X86 architecture, the registers EAX, AX and -AL share the first eight bits. These physical registers are -marked as aliased in LLVM. Given a particular architecture, you -can check which registers are aliased by inspecting its -RegisterInfo.td file. Moreover, the method -TargetRegisterInfo::getAliasSet(p_reg) returns an array containing -all the physical registers aliased to the register p_reg.

+

In LLVM, physical registers are denoted by integer numbers that normally + range from 1 to 1023. To see how this numbering is defined for a particular + architecture, you can read the GenRegisterNames.inc file for that + architecture. For instance, by + inspecting lib/Target/X86/X86GenRegisterNames.inc we see that the + 32-bit register EAX is denoted by 15, and the MMX register + MM0 is mapped to 48.

+ +

Some architectures contain registers that share the same physical location. A + notable example is the X86 platform. For instance, in the X86 architecture, + the registers EAX, AX and AL share the first eight + bits. These physical registers are marked as aliased in LLVM. Given a + particular architecture, you can check which registers are aliased by + inspecting its RegisterInfo.td file. Moreover, the method + TargetRegisterInfo::getAliasSet(p_reg) returns an array containing + all the physical registers aliased to the register p_reg.

Physical registers, in LLVM, are grouped in Register Classes. -Elements in the same register class are functionally equivalent, and can -be interchangeably used. Each virtual register can only be mapped to -physical registers of a particular class. For instance, in the X86 -architecture, some virtuals can only be allocated to 8 bit registers. -A register class is described by TargetRegisterClass objects. -To discover if a virtual register is compatible with a given physical, -this code can be used: -

+ Elements in the same register class are functionally equivalent, and can be + interchangeably used. Each virtual register can only be mapped to physical + registers of a particular class. For instance, in the X86 architecture, some + virtuals can only be allocated to 8 bit registers. A register class is + described by TargetRegisterClass objects. To discover if a virtual + register is compatible with a given physical, this code can be used:

@@ -1354,69 +1374,63 @@
 
-

Sometimes, mostly for debugging purposes, it is useful to change -the number of physical registers available in the target -architecture. This must be done statically, inside the -TargetRegsterInfo.td file. Just grep for -RegisterClass, the last parameter of which is a list of -registers. Just commenting some out is one simple way to avoid them -being used. A more polite way is to explicitly exclude some registers -from the allocation order. See the definition of the -GR register class in -lib/Target/IA64/IA64RegisterInfo.td for an example of this -(e.g., numReservedRegs registers are hidden.)

- -

Virtual registers are also denoted by integer numbers. Contrary to -physical registers, different virtual registers never share the same -number. The smallest virtual register is normally assigned the number -1024. This may change, so, in order to know which is the first virtual -register, you should access -TargetRegisterInfo::FirstVirtualRegister. Any register whose -number is greater than or equal to -TargetRegisterInfo::FirstVirtualRegister is considered a virtual -register. Whereas physical registers are statically defined in a -TargetRegisterInfo.td file and cannot be created by the -application developer, that is not the case with virtual registers. -In order to create new virtual registers, use the method -MachineRegisterInfo::createVirtualRegister(). This method will return a -virtual register with the highest code. -

- -

Before register allocation, the operands of an instruction are -mostly virtual registers, although physical registers may also be -used. In order to check if a given machine operand is a register, use -the boolean function MachineOperand::isRegister(). To obtain -the integer code of a register, use -MachineOperand::getReg(). An instruction may define or use a -register. For instance, ADD reg:1026 := reg:1025 reg:1024 -defines the registers 1024, and uses registers 1025 and 1026. Given a -register operand, the method MachineOperand::isUse() informs -if that register is being used by the instruction. The method -MachineOperand::isDef() informs if that registers is being -defined.

- -

We will call physical registers present in the LLVM bitcode before -register allocation pre-colored registers. Pre-colored -registers are used in many different situations, for instance, to pass -parameters of functions calls, and to store results of particular -instructions. There are two types of pre-colored registers: the ones -implicitly defined, and those explicitly -defined. Explicitly defined registers are normal operands, and can be -accessed with MachineInstr::getOperand(int)::getReg(). In -order to check which registers are implicitly defined by an -instruction, use the -TargetInstrInfo::get(opcode)::ImplicitDefs, where -opcode is the opcode of the target instruction. One important -difference between explicit and implicit physical registers is that -the latter are defined statically for each instruction, whereas the -former may vary depending on the program being compiled. For example, -an instruction that represents a function call will always implicitly -define or use the same set of physical registers. To read the -registers implicitly used by an instruction, use -TargetInstrInfo::get(opcode)::ImplicitUses. Pre-colored -registers impose constraints on any register allocation algorithm. The -register allocator must make sure that none of them is been -overwritten by the values of virtual registers while still alive.

+

Sometimes, mostly for debugging purposes, it is useful to change the number + of physical registers available in the target architecture. This must be done + statically, inside the TargetRegsterInfo.td file. Just grep + for RegisterClass, the last parameter of which is a list of + registers. Just commenting some out is one simple way to avoid them being + used. A more polite way is to explicitly exclude some registers from + the allocation order. See the definition of the GR register + class in lib/Target/IA64/IA64RegisterInfo.td for an example of this + (e.g., numReservedRegs registers are hidden.)

+ +

Virtual registers are also denoted by integer numbers. Contrary to physical + registers, different virtual registers never share the same number. The + smallest virtual register is normally assigned the number 1024. This may + change, so, in order to know which is the first virtual register, you should + access TargetRegisterInfo::FirstVirtualRegister. Any register whose + number is greater than or equal + to TargetRegisterInfo::FirstVirtualRegister is considered a virtual + register. Whereas physical registers are statically defined in + a TargetRegisterInfo.td file and cannot be created by the + application developer, that is not the case with virtual registers. In order + to create new virtual registers, use the + method MachineRegisterInfo::createVirtualRegister(). This method + will return a virtual register with the highest code.

+ +

Before register allocation, the operands of an instruction are mostly virtual + registers, although physical registers may also be used. In order to check if + a given machine operand is a register, use the boolean + function MachineOperand::isRegister(). To obtain the integer code of + a register, use MachineOperand::getReg(). An instruction may define + or use a register. For instance, ADD reg:1026 := reg:1025 reg:1024 + defines the registers 1024, and uses registers 1025 and 1026. Given a + register operand, the method MachineOperand::isUse() informs if that + register is being used by the instruction. The + method MachineOperand::isDef() informs if that registers is being + defined.

+ +

We will call physical registers present in the LLVM bitcode before register + allocation pre-colored registers. Pre-colored registers are used in + many different situations, for instance, to pass parameters of functions + calls, and to store results of particular instructions. There are two types + of pre-colored registers: the ones implicitly defined, and + those explicitly defined. Explicitly defined registers are normal + operands, and can be accessed + with MachineInstr::getOperand(int)::getReg(). In order to check + which registers are implicitly defined by an instruction, use + the TargetInstrInfo::get(opcode)::ImplicitDefs, + where opcode is the opcode of the target instruction. One important + difference between explicit and implicit physical registers is that the + latter are defined statically for each instruction, whereas the former may + vary depending on the program being compiled. For example, an instruction + that represents a function call will always implicitly define or use the same + set of physical registers. To read the registers implicitly used by an + instruction, + use TargetInstrInfo::get(opcode)::ImplicitUses. Pre-colored + registers impose constraints on any register allocation algorithm. The + register allocator must make sure that none of them is been overwritten by + the values of virtual registers while still alive.

@@ -1429,49 +1443,45 @@

There are two ways to map virtual registers to physical registers (or to -memory slots). The first way, that we will call direct mapping, -is based on the use of methods of the classes TargetRegisterInfo, -and MachineOperand. The second way, that we will call -indirect mapping, relies on the VirtRegMap class in -order to insert loads and stores sending and getting values to and from -memory.

- -

The direct mapping provides more flexibility to the developer of -the register allocator; however, it is more error prone, and demands -more implementation work. Basically, the programmer will have to -specify where load and store instructions should be inserted in the -target function being compiled in order to get and store values in -memory. To assign a physical register to a virtual register present in -a given operand, use MachineOperand::setReg(p_reg). To insert -a store instruction, use -TargetRegisterInfo::storeRegToStackSlot(...), and to insert a load -instruction, use TargetRegisterInfo::loadRegFromStackSlot.

- -

The indirect mapping shields the application developer from the -complexities of inserting load and store instructions. In order to map -a virtual register to a physical one, use -VirtRegMap::assignVirt2Phys(vreg, preg). In order to map a -certain virtual register to memory, use -VirtRegMap::assignVirt2StackSlot(vreg). This method will -return the stack slot where vreg's value will be located. If -it is necessary to map another virtual register to the same stack -slot, use VirtRegMap::assignVirt2StackSlot(vreg, -stack_location). One important point to consider when using the -indirect mapping, is that even if a virtual register is mapped to -memory, it still needs to be mapped to a physical register. This -physical register is the location where the virtual register is -supposed to be found before being stored or after being reloaded.

- -

If the indirect strategy is used, after all the virtual registers -have been mapped to physical registers or stack slots, it is necessary -to use a spiller object to place load and store instructions in the -code. Every virtual that has been mapped to a stack slot will be -stored to memory after been defined and will be loaded before being -used. The implementation of the spiller tries to recycle load/store -instructions, avoiding unnecessary instructions. For an example of how -to invoke the spiller, see -RegAllocLinearScan::runOnMachineFunction in -lib/CodeGen/RegAllocLinearScan.cpp.

+ memory slots). The first way, that we will call direct mapping, is + based on the use of methods of the classes TargetRegisterInfo, + and MachineOperand. The second way, that we will call indirect + mapping, relies on the VirtRegMap class in order to insert loads + and stores sending and getting values to and from memory.

+ +

The direct mapping provides more flexibility to the developer of the register + allocator; however, it is more error prone, and demands more implementation + work. Basically, the programmer will have to specify where load and store + instructions should be inserted in the target function being compiled in + order to get and store values in memory. To assign a physical register to a + virtual register present in a given operand, + use MachineOperand::setReg(p_reg). To insert a store instruction, + use TargetRegisterInfo::storeRegToStackSlot(...), and to insert a + load instruction, use TargetRegisterInfo::loadRegFromStackSlot.

+ +

The indirect mapping shields the application developer from the complexities + of inserting load and store instructions. In order to map a virtual register + to a physical one, use VirtRegMap::assignVirt2Phys(vreg, preg). In + order to map a certain virtual register to memory, + use VirtRegMap::assignVirt2StackSlot(vreg). This method will return + the stack slot where vreg's value will be located. If it is + necessary to map another virtual register to the same stack slot, + use VirtRegMap::assignVirt2StackSlot(vreg, stack_location). One + important point to consider when using the indirect mapping, is that even if + a virtual register is mapped to memory, it still needs to be mapped to a + physical register. This physical register is the location where the virtual + register is supposed to be found before being stored or after being + reloaded.

+ +

If the indirect strategy is used, after all the virtual registers have been + mapped to physical registers or stack slots, it is necessary to use a spiller + object to place load and store instructions in the code. Every virtual that + has been mapped to a stack slot will be stored to memory after been defined + and will be loaded before being used. The implementation of the spiller tries + to recycle load/store instructions, avoiding unnecessary instructions. For an + example of how to invoke the spiller, + see RegAllocLinearScan::runOnMachineFunction + in lib/CodeGen/RegAllocLinearScan.cpp.

@@ -1482,23 +1492,21 @@
-

With very rare exceptions (e.g., function calls), the LLVM machine -code instructions are three address instructions. That is, each -instruction is expected to define at most one register, and to use at -most two registers. However, some architectures use two address -instructions. In this case, the defined register is also one of the -used register. For instance, an instruction such as ADD %EAX, -%EBX, in X86 is actually equivalent to %EAX = %EAX + -%EBX.

+

With very rare exceptions (e.g., function calls), the LLVM machine code + instructions are three address instructions. That is, each instruction is + expected to define at most one register, and to use at most two registers. + However, some architectures use two address instructions. In this case, the + defined register is also one of the used register. For instance, an + instruction such as ADD %EAX, %EBX, in X86 is actually equivalent + to %EAX = %EAX + %EBX.

In order to produce correct code, LLVM must convert three address -instructions that represent two address instructions into true two -address instructions. LLVM provides the pass -TwoAddressInstructionPass for this specific purpose. It must -be run before register allocation takes place. After its execution, -the resulting code may no longer be in SSA form. This happens, for -instance, in situations where an instruction such as %a = ADD %b -%c is converted to two instructions such as:

+ instructions that represent two address instructions into true two address + instructions. LLVM provides the pass TwoAddressInstructionPass for + this specific purpose. It must be run before register allocation takes + place. After its execution, the resulting code may no longer be in SSA + form. This happens, for instance, in situations where an instruction such + as %a = ADD %b %c is converted to two instructions such as:

@@ -1508,8 +1516,8 @@
 

Notice that, internally, the second instruction is represented as -ADD %a[def/use] %c. I.e., the register operand %a is -both used and defined by the instruction.

+ ADD %a[def/use] %c. I.e., the register operand %a is both + used and defined by the instruction.

@@ -1521,20 +1529,19 @@

An important transformation that happens during register allocation is called -the SSA Deconstruction Phase. The SSA form simplifies many -analyses that are performed on the control flow graph of -programs. However, traditional instruction sets do not implement -PHI instructions. Thus, in order to generate executable code, compilers -must replace PHI instructions with other instructions that preserve their -semantics.

- -

There are many ways in which PHI instructions can safely be removed -from the target code. The most traditional PHI deconstruction -algorithm replaces PHI instructions with copy instructions. That is -the strategy adopted by LLVM. The SSA deconstruction algorithm is -implemented in lib/CodeGen/PHIElimination.cpp. In order to -invoke this pass, the identifier PHIEliminationID must be -marked as required in the code of the register allocator.

+ the SSA Deconstruction Phase. The SSA form simplifies many analyses + that are performed on the control flow graph of programs. However, + traditional instruction sets do not implement PHI instructions. Thus, in + order to generate executable code, compilers must replace PHI instructions + with other instructions that preserve their semantics.

+ +

There are many ways in which PHI instructions can safely be removed from the + target code. The most traditional PHI deconstruction algorithm replaces PHI + instructions with copy instructions. That is the strategy adopted by + LLVM. The SSA deconstruction algorithm is implemented + in lib/CodeGen/PHIElimination.cpp. In order to invoke this pass, the + identifier PHIEliminationID must be marked as required in the code + of the register allocator.

@@ -1545,9 +1552,9 @@
-

Instruction folding is an optimization performed during -register allocation that removes unnecessary copy instructions. For -instance, a sequence of instructions such as:

+

Instruction folding is an optimization performed during register + allocation that removes unnecessary copy instructions. For instance, a + sequence of instructions such as:

@@ -1564,12 +1571,13 @@
 
-

Instructions can be folded with the -TargetRegisterInfo::foldMemoryOperand(...) method. Care must be -taken when folding instructions; a folded instruction can be quite -different from the original instruction. See -LiveIntervals::addIntervalsForSpills in -lib/CodeGen/LiveIntervalAnalysis.cpp for an example of its use.

+

Instructions can be folded with + the TargetRegisterInfo::foldMemoryOperand(...) method. Care must be + taken when folding instructions; a folded instruction can be quite different + from the original + instruction. See LiveIntervals::addIntervalsForSpills + in lib/CodeGen/LiveIntervalAnalysis.cpp for an example of its + use.

@@ -1581,20 +1589,22 @@
-

The LLVM infrastructure provides the application developer with -three different register allocators:

+

The LLVM infrastructure provides the application developer with three + different register allocators:

    -
  • Simple - This is a very simple implementation that does - not keep values in registers across instructions. This register - allocator immediately spills every value right after it is - computed, and reloads all used operands from memory to temporary - registers before each instruction.
  • -
  • Local - This register allocator is an improvement on the - Simple implementation. It allocates registers on a basic - block level, attempting to keep values in registers and reusing - registers as appropriate.
  • -
  • Linear Scan - The default allocator. This is the +
  • Simple — This is a very simple implementation that does not + keep values in registers across instructions. This register allocator + immediately spills every value right after it is computed, and reloads all + used operands from memory to temporary registers before each + instruction.
  • + +
  • Local — This register allocator is an improvement on the + Simple implementation. It allocates registers on a basic block + level, attempting to keep values in registers and reusing registers as + appropriate.
  • + +
  • Linear ScanThe default allocator. This is the well-know linear scan register allocator. Whereas the Simple and Local algorithms use a direct mapping implementation technique, the Linear Scan implementation @@ -1602,7 +1612,7 @@

The type of register allocator used in llc can be chosen with the -command line option -regalloc=...:

+ command line option -regalloc=...:

@@ -1652,8 +1662,8 @@
 
 
-

This section of the document explains features or design decisions that -are specific to the code generator for a particular target.

+

This section of the document explains features or design decisions that are + specific to the code generator for a particular target.

@@ -1663,44 +1673,69 @@
-

Tail call optimization, callee reusing the stack of the caller, is currently supported on x86/x86-64 and PowerPC. It is performed if: -

    -
  • Caller and callee have the calling convention fastcc.
  • -
  • The call is a tail call - in tail position (ret immediately follows call and ret uses value of call or is void).
  • -
  • Option -tailcallopt is enabled.
  • -
  • Platform specific constraints are met.
  • -
-

- -

x86/x86-64 constraints: -

    -
  • No variable argument lists are used.
  • -
  • On x86-64 when generating GOT/PIC code only module-local calls (visibility = hidden or protected) are supported.
  • -
-

-

PowerPC constraints: -

    -
  • No variable argument lists are used.
  • -
  • No byval parameters are used.
  • -
  • On ppc32/64 GOT/PIC only module-local calls (visibility = hidden or protected) are supported.
  • -
-

-

Example:

-

Call as llc -tailcallopt test.ll. -

-
+
+

Tail call optimization, callee reusing the stack of the caller, is currently + supported on x86/x86-64 and PowerPC. It is performed if:

+ +
    +
  • Caller and callee have the calling convention fastcc.
  • + +
  • The call is a tail call - in tail position (ret immediately follows call + and ret uses value of call or is void).
  • + +
  • Option -tailcallopt is enabled.
  • + +
  • Platform specific constraints are met.
  • +
+ +

x86/x86-64 constraints:

+ +
    +
  • No variable argument lists are used.
  • + +
  • On x86-64 when generating GOT/PIC code only module-local calls (visibility + = hidden or protected) are supported.
  • +
+ +

PowerPC constraints:

+ +
    +
  • No variable argument lists are used.
  • + +
  • No byval parameters are used.
  • + +
  • On ppc32/64 GOT/PIC only module-local calls (visibility = hidden or protected) are supported.
  • +
+ +

Example:

+ +

Call as llc -tailcallopt test.ll.

+ +
+
 declare fastcc i32 @tailcallee(i32 inreg %a1, i32 inreg %a2, i32 %a3, i32 %a4)
 
 define fastcc i32 @tailcaller(i32 %in1, i32 %in2) {
   %l1 = add i32 %in1, %in2
   %tmp = tail call fastcc i32 @tailcallee(i32 %in1 inreg, i32 %in2 inreg, i32 %in1, i32 %l1)
   ret i32 %tmp
-}
-
-

-

Implications of -tailcallopt:

-

To support tail call optimization in situations where the callee has more arguments than the caller a 'callee pops arguments' convention is used. This currently causes each fastcc call that is not tail call optimized (because one or more of above constraints are not met) to be followed by a readjustment of the stack. So performance might be worse in such cases.

-

On x86 and x86-64 one register is reserved for indirect tail calls (e.g via a function pointer). So there is one less register for integer argument passing. For x86 this means 2 registers (if inreg parameter attribute is used) and for x86-64 this means 5 register are used.

+} +
+
+ +

Implications of -tailcallopt:

+ +

To support tail call optimization in situations where the callee has more + arguments than the caller a 'callee pops arguments' convention is used. This + currently causes each fastcc call that is not tail call optimized + (because one or more of above constraints are not met) to be followed by a + readjustment of the stack. So performance might be worse in such cases.

+ +

On x86 and x86-64 one register is reserved for indirect tail calls (e.g via a + function pointer). So there is one less register for integer argument + passing. For x86 this means 2 registers (if inreg parameter + attribute is used) and for x86-64 this means 5 register are used.

+
@@ -1710,9 +1745,8 @@

The X86 code generator lives in the lib/Target/X86 directory. This -code generator is capable of targeting a variety of x86-32 and x86-64 -processors, and includes support for ISA extensions such as MMX and SSE. -

+ code generator is capable of targeting a variety of x86-32 and x86-64 + processors, and includes support for ISA extensions such as MMX and SSE.

@@ -1723,17 +1757,22 @@
-

The following are the known target triples that are supported by the X86 -backend. This is not an exhaustive list, and it would be useful to add those -that people test.

+

The following are the known target triples that are supported by the X86 + backend. This is not an exhaustive list, and it would be useful to add those + that people test.

    -
  • i686-pc-linux-gnu - Linux
  • -
  • i386-unknown-freebsd5.3 - FreeBSD 5.3
  • -
  • i686-pc-cygwin - Cygwin on Win32
  • -
  • i686-pc-mingw32 - MingW on Win32
  • -
  • i386-pc-mingw32msvc - MingW crosscompiler on Linux
  • -
  • i686-apple-darwin* - Apple Darwin on X86
  • +
  • i686-pc-linux-gnu — Linux
  • + +
  • i386-unknown-freebsd5.3 — FreeBSD 5.3
  • + +
  • i686-pc-cygwin — Cygwin on Win32
  • + +
  • i686-pc-mingw32 — MingW on Win32
  • + +
  • i386-pc-mingw32msvc — MingW crosscompiler on Linux
  • + +
  • i686-apple-darwin* — Apple Darwin on X86
@@ -1749,10 +1788,11 @@

The following target-specific calling conventions are known to backend:

    -
  • x86_StdCall - stdcall calling convention seen on Microsoft Windows -platform (CC ID = 64).
  • -
  • x86_FastCall - fastcall calling convention seen on Microsoft Windows -platform (CC ID = 65).
  • +
  • x86_StdCall — stdcall calling convention seen on Microsoft + Windows platform (CC ID = 64).
  • + +
  • x86_FastCall — fastcall calling convention seen on Microsoft + Windows platform (CC ID = 65).
@@ -1765,8 +1805,8 @@

The x86 has a very flexible way of accessing memory. It is capable of -forming memory addresses of the following expression directly in integer -instructions (which use ModR/M addressing):

+ forming memory addresses of the following expression directly in integer + instructions (which use ModR/M addressing):

@@ -1775,17 +1815,19 @@
 

In order to represent this, LLVM tracks no less than 4 operands for each -memory operand of this form. This means that the "load" form of 'mov' -has the following MachineOperands in this order:

+ memory operand of this form. This means that the "load" form of + 'mov' has the following MachineOperands in this order:

+
 Index:        0     |    1        2       3           4
 Meaning:   DestReg, | BaseReg,  Scale, IndexReg, Displacement
 OperandTy: VirtReg, | VirtReg, UnsImm, VirtReg,   SignExtImm
 
+
-

Stores, and all other instructions, treat the four memory operands in the -same way and in the same order.

+

Stores, and all other instructions, treat the four memory operands in the + same way and in the same order.

@@ -1796,17 +1838,17 @@
-

x86 has the ability to perform loads and stores to different address spaces -via the x86 segment registers. A segment override prefix byte on an instruction -causes the instruction's memory access to go to the specified segment. LLVM -address space 0 is the default address space, which includes the stack, and -any unqualified memory accesses in a program. Address spaces 1-255 are -currently reserved for user-defined code. The GS-segment is represented by -address space 256. Other x86 segments have yet to be allocated address space -numbers. +

x86 has the ability to perform loads and stores to different address spaces + via the x86 segment registers. A segment override prefix byte on an + instruction causes the instruction's memory access to go to the specified + segment. LLVM address space 0 is the default address space, which includes + the stack, and any unqualified memory accesses in a program. Address spaces + 1-255 are currently reserved for user-defined code. The GS-segment is + represented by address space 256. Other x86 segments have yet to be + allocated address space numbers.

Some operating systems use the GS-segment to implement TLS, so care should be -taken when reading and writing to address space 256 on these platforms. + taken when reading and writing to address space 256 on these platforms.

@@ -1818,14 +1860,16 @@

An instruction name consists of the base name, a default operand size, and a -a character per operand with an optional special size. For example:

+ a character per operand with an optional special size. For example:

-

-ADD8rr -> add, 8-bit register, 8-bit register
-IMUL16rmi -> imul, 16-bit register, 16-bit memory, 16-bit immediate
-IMUL16rmi8 -> imul, 16-bit register, 16-bit memory, 8-bit immediate
-MOVSX32rm16 -> movsx, 32-bit register, 16-bit memory -

+
+
+ADD8rr      -> add, 8-bit register, 8-bit register
+IMUL16rmi   -> imul, 16-bit register, 16-bit memory, 16-bit immediate
+IMUL16rmi8  -> imul, 16-bit register, 16-bit memory, 8-bit immediate
+MOVSX32rm16 -> movsx, 32-bit register, 16-bit memory
+
+
@@ -1835,10 +1879,11 @@
+

The PowerPC code generator lives in the lib/Target/PowerPC directory. The -code generation is retargetable to several variations or subtargets of -the PowerPC ISA; including ppc32, ppc64 and altivec. -

+ code generation is retargetable to several variations or subtargets of + the PowerPC ISA; including ppc32, ppc64 and altivec.

+
@@ -1847,16 +1892,18 @@
+

LLVM follows the AIX PowerPC ABI, with two deviations. LLVM uses a PC -relative (PIC) or static addressing for accessing global values, so no TOC (r2) -is used. Second, r31 is used as a frame pointer to allow dynamic growth of a -stack frame. LLVM takes advantage of having no TOC to provide space to save -the frame pointer in the PowerPC linkage area of the caller frame. Other -details of PowerPC ABI can be found at PowerPC ABI. Note: This link describes the 32 bit ABI. The -64 bit ABI is similar except space for GPRs are 8 bytes wide (not 4) and r13 is -reserved for system use.

+ relative (PIC) or static addressing for accessing global values, so no TOC + (r2) is used. Second, r31 is used as a frame pointer to allow dynamic growth + of a stack frame. LLVM takes advantage of having no TOC to provide space to + save the frame pointer in the PowerPC linkage area of the caller frame. + Other details of PowerPC ABI can be found at PowerPC ABI. Note: This link describes the 32 bit ABI. The 64 bit ABI + is similar except space for GPRs are 8 bytes wide (not 4) and r13 is reserved + for system use.

+
@@ -1865,157 +1912,145 @@
+

The size of a PowerPC frame is usually fixed for the duration of a -function’s invocation. Since the frame is fixed size, all references into -the frame can be accessed via fixed offsets from the stack pointer. The -exception to this is when dynamic alloca or variable sized arrays are present, -then a base pointer (r31) is used as a proxy for the stack pointer and stack -pointer is free to grow or shrink. A base pointer is also used if llvm-gcc is -not passed the -fomit-frame-pointer flag. The stack pointer is always aligned to -16 bytes, so that space allocated for altivec vectors will be properly -aligned.

+ function's invocation. Since the frame is fixed size, all references + into the frame can be accessed via fixed offsets from the stack pointer. The + exception to this is when dynamic alloca or variable sized arrays are + present, then a base pointer (r31) is used as a proxy for the stack pointer + and stack pointer is free to grow or shrink. A base pointer is also used if + llvm-gcc is not passed the -fomit-frame-pointer flag. The stack pointer is + always aligned to 16 bytes, so that space allocated for altivec vectors will + be properly aligned.

+

An invocation frame is laid out as follows (low memory at top);

-
-
- - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + +
Linkage

Parameter area

Dynamic area

Locals area

Saved registers area


Previous Frame

Linkage

Parameter area

Dynamic area

Locals area

Saved registers area


Previous Frame

-
-

The linkage area is used by a callee to save special registers prior -to allocating its own frame. Only three entries are relevant to LLVM. The -first entry is the previous stack pointer (sp), aka link. This allows probing -tools like gdb or exception handlers to quickly scan the frames in the stack. A -function epilog can also use the link to pop the frame from the stack. The -third entry in the linkage area is used to save the return address from the lr -register. Finally, as mentioned above, the last entry is used to save the -previous frame pointer (r31.) The entries in the linkage area are the size of a -GPR, thus the linkage area is 24 bytes long in 32 bit mode and 48 bytes in 64 -bit mode.

-
+ to allocating its own frame. Only three entries are relevant to LLVM. The + first entry is the previous stack pointer (sp), aka link. This allows + probing tools like gdb or exception handlers to quickly scan the frames in + the stack. A function epilog can also use the link to pop the frame from the + stack. The third entry in the linkage area is used to save the return + address from the lr register. Finally, as mentioned above, the last entry is + used to save the previous frame pointer (r31.) The entries in the linkage + area are the size of a GPR, thus the linkage area is 24 bytes long in 32 bit + mode and 48 bytes in 64 bit mode.

-

32 bit linkage area

+ - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + +
0Saved SP (r1)
4Saved CR
8Saved LR
12Reserved
16Reserved
20Saved FP (r31)
0Saved SP (r1)
4Saved CR
8Saved LR
12Reserved
16Reserved
20Saved FP (r31)
-
-

64 bit linkage area

+ - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + +
0Saved SP (r1)
8Saved CR
16Saved LR
24Reserved
32Reserved
40Saved FP (r31)
0Saved SP (r1)
8Saved CR
16Saved LR
24Reserved
32Reserved
40Saved FP (r31)
-
-

The parameter area is used to store arguments being passed to a callee -function. Following the PowerPC ABI, the first few arguments are actually -passed in registers, with the space in the parameter area unused. However, if -there are not enough registers or the callee is a thunk or vararg function, -these register arguments can be spilled into the parameter area. Thus, the -parameter area must be large enough to store all the parameters for the largest -call sequence made by the caller. The size must also be minimally large enough -to spill registers r3-r10. This allows callees blind to the call signature, -such as thunks and vararg functions, enough space to cache the argument -registers. Therefore, the parameter area is minimally 32 bytes (64 bytes in 64 -bit mode.) Also note that since the parameter area is a fixed offset from the -top of the frame, that a callee can access its spilt arguments using fixed -offsets from the stack pointer (or base pointer.)

-
+ function. Following the PowerPC ABI, the first few arguments are actually + passed in registers, with the space in the parameter area unused. However, + if there are not enough registers or the callee is a thunk or vararg + function, these register arguments can be spilled into the parameter area. + Thus, the parameter area must be large enough to store all the parameters for + the largest call sequence made by the caller. The size must also be + minimally large enough to spill registers r3-r10. This allows callees blind + to the call signature, such as thunks and vararg functions, enough space to + cache the argument registers. Therefore, the parameter area is minimally 32 + bytes (64 bytes in 64 bit mode.) Also note that since the parameter area is + a fixed offset from the top of the frame, that a callee can access its spilt + arguments using fixed offsets from the stack pointer (or base pointer.)

-

Combining the information about the linkage, parameter areas and alignment. A -stack frame is minimally 64 bytes in 32 bit mode and 128 bytes in 64 bit -mode.

-
+ stack frame is minimally 64 bytes in 32 bit mode and 128 bytes in 64 bit + mode.

-

The dynamic area starts out as size zero. If a function uses dynamic -alloca then space is added to the stack, the linkage and parameter areas are -shifted to top of stack, and the new space is available immediately below the -linkage and parameter areas. The cost of shifting the linkage and parameter -areas is minor since only the link value needs to be copied. The link value can -be easily fetched by adding the original frame size to the base pointer. Note -that allocations in the dynamic space need to observe 16 byte alignment.

-
+ alloca then space is added to the stack, the linkage and parameter areas are + shifted to top of stack, and the new space is available immediately below the + linkage and parameter areas. The cost of shifting the linkage and parameter + areas is minor since only the link value needs to be copied. The link value + can be easily fetched by adding the original frame size to the base pointer. + Note that allocations in the dynamic space need to observe 16 byte + alignment.

-

The locals area is where the llvm compiler reserves space for local -variables.

-
+ variables.

+ +

The saved registers area is where the llvm compiler spills callee + saved registers on entry to the callee.

-
-

The saved registers area is where the llvm compiler spills callee saved -registers on entry to the callee.

@@ -2024,12 +2059,15 @@
+

The llvm prolog and epilog are the same as described in the PowerPC ABI, with -the following exceptions. Callee saved registers are spilled after the frame is -created. This allows the llvm epilog/prolog support to be common with other -targets. The base pointer callee saved register r31 is saved in the TOC slot of -linkage area. This simplifies allocation of space for the base pointer and -makes it convenient to locate programatically and during debugging.

+ the following exceptions. Callee saved registers are spilled after the frame + is created. This allows the llvm epilog/prolog support to be common with + other targets. The base pointer callee saved register r31 is saved in the + TOC slot of linkage area. This simplifies allocation of space for the base + pointer and makes it convenient to locate programatically and during + debugging.

+
@@ -2038,11 +2076,9 @@
-

-
-

TODO - More to come.

+
From clattner at apple.com Tue Apr 14 22:21:53 2009 From: clattner at apple.com (Chris Lattner) Date: Tue, 14 Apr 2009 20:21:53 -0700 Subject: [llvm-commits] [llvm] r69121 - /llvm/trunk/lib/Transforms/Scalar/CondPropagate.cpp In-Reply-To: <200904150044.n3F0iBu1022498@zion.cs.uiuc.edu> References: <200904150044.n3F0iBu1022498@zion.cs.uiuc.edu> Message-ID: <14E6AE7F-2BB1-4B59-AAA3-DA2CAF9E3906@apple.com> On Apr 14, 2009, at 5:44 PM, Evan Cheng wrote: > Author: evancheng > Date: Tue Apr 14 19:43:54 2009 > New Revision: 69121 > > URL: http://llvm.org/viewvc/llvm-project?rev=69121&view=rev > Log: > Avoid making the transformation enabled by my last patch if the new > destinations have phi nodes. Thanks, testcase? :) -Chris > > > Modified: > llvm/trunk/lib/Transforms/Scalar/CondPropagate.cpp > > Modified: llvm/trunk/lib/Transforms/Scalar/CondPropagate.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CondPropagate.cpp?rev=69121&r1=69120&r2=69121&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Transforms/Scalar/CondPropagate.cpp (original) > +++ llvm/trunk/lib/Transforms/Scalar/CondPropagate.cpp Tue Apr 14 > 19:43:54 2009 > @@ -267,11 +267,21 @@ > // Change FromBr to branch to the new destination. > FromBr->setSuccessor(0, ToBB); > } else { > + BasicBlock *Succ0 = BI->getSuccessor(0); > + // Do not perform transform if the new destination has PHI > nodes. The > + // transform will add new preds to the PHI's. > + if (isa(Succ0->begin())) > + return false; > + > + BasicBlock *Succ1 = BI->getSuccessor(1); > + if (isa(Succ1->begin())) > + return false; > + > // Insert the new conditional branch. > - BranchInst::Create(BI->getSuccessor(0), BI->getSuccessor(1), > Cond, FromBr); > + BranchInst::Create(Succ0, Succ1, Cond, FromBr); > > - FoldSingleEntryPHINodes(BI->getSuccessor(0)); > - FoldSingleEntryPHINodes(BI->getSuccessor(1)); > + FoldSingleEntryPHINodes(Succ0); > + FoldSingleEntryPHINodes(Succ1); > > // Update PHI nodes in OldSucc to know that FromBB no longer > branches to it. > OldSucc->removePredecessor(FromBB); > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From eli.friedman at gmail.com Tue Apr 14 22:27:21 2009 From: eli.friedman at gmail.com (Eli Friedman) Date: Tue, 14 Apr 2009 20:27:21 -0700 Subject: [llvm-commits] [llvm] r69102 - in /llvm/trunk: lib/Transforms/Scalar/CondPropagate.cpp test/Transforms/CondProp/phisimplify3.ll In-Reply-To: <200904142340.n3ENe4FD020265@zion.cs.uiuc.edu> References: <200904142340.n3ENe4FD020265@zion.cs.uiuc.edu> Message-ID: On Tue, Apr 14, 2009 at 4:40 PM, Evan Cheng wrote: > Author: evancheng > Date: Tue Apr 14 18:40:03 2009 > New Revision: 69102 > > URL: http://llvm.org/viewvc/llvm-project?rev=69102&view=rev > Log: > Optimize conditional branch on i1 phis with non-constant inputs. See http://llvm.org/bugs/show_bug.cgi?id=3906? -Eli From isanbard at gmail.com Tue Apr 14 23:50:45 2009 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 15 Apr 2009 04:50:45 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r69139 - /llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Message-ID: <200904150450.n3F4ojOQ030419@zion.cs.uiuc.edu> Author: void Date: Tue Apr 14 23:50:44 2009 New Revision: 69139 URL: http://llvm.org/viewvc/llvm-project?rev=69139&view=rev Log: Set the alignment while we're at it. Modified: llvm-gcc-4.2/trunk/gcc/llvm-backend.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=69139&r1=69138&r2=69139&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Tue Apr 14 23:50:44 2009 @@ -1199,6 +1199,7 @@ GV->getName(), TheModule); NGV->setVisibility(GV->getVisibility()); NGV->setSection(GV->getSection()); + NGV->setAlignment(GV->getAlignment()); GV->replaceAllUsesWith(TheFolder->CreateBitCast(NGV, GV->getType())); changeLLVMConstant(GV, NGV); delete GV; From isanbard at gmail.com Tue Apr 14 23:51:05 2009 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 15 Apr 2009 04:51:05 -0000 Subject: [llvm-commits] [llvm] r69140 - /llvm/trunk/test/FrontendObjC/2009-04-14-AsmSection.m Message-ID: <200904150451.n3F4p5Mg030438@zion.cs.uiuc.edu> Author: void Date: Tue Apr 14 23:51:05 2009 New Revision: 69140 URL: http://llvm.org/viewvc/llvm-project?rev=69140&view=rev Log: Check for alignment. Modified: llvm/trunk/test/FrontendObjC/2009-04-14-AsmSection.m Modified: llvm/trunk/test/FrontendObjC/2009-04-14-AsmSection.m URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/FrontendObjC/2009-04-14-AsmSection.m?rev=69140&r1=69139&r2=69140&view=diff ============================================================================== --- llvm/trunk/test/FrontendObjC/2009-04-14-AsmSection.m (original) +++ llvm/trunk/test/FrontendObjC/2009-04-14-AsmSection.m Tue Apr 14 23:51:05 2009 @@ -1,4 +1,5 @@ -// RUN: %llvmgcc -S %s -fobjc-abi-version=2 -emit-llvm -o - | grep {OBJC_CLASS_\$_A.*section.*__DATA, __objc_data} +// RUN: %llvmgcc -S %s -fobjc-abi-version=2 -emit-llvm -o %t +// RUN: grep {OBJC_CLASS_\\\$_A.*section.*__DATA, __objc_data.*align} %t // XTARGETS: darwin @interface A From dgregor at apple.com Tue Apr 14 23:53:47 2009 From: dgregor at apple.com (Douglas Gregor) Date: Wed, 15 Apr 2009 04:53:47 -0000 Subject: [llvm-commits] [llvm] r69145 - /llvm/trunk/include/llvm/Bitcode/BitstreamReader.h Message-ID: <200904150453.n3F4rlc1030581@zion.cs.uiuc.edu> Author: dgregor Date: Tue Apr 14 23:53:47 2009 New Revision: 69145 URL: http://llvm.org/viewvc/llvm-project?rev=69145&view=rev Log: Allow jumping to the end of a bitstream while reading Modified: llvm/trunk/include/llvm/Bitcode/BitstreamReader.h Modified: llvm/trunk/include/llvm/Bitcode/BitstreamReader.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/BitstreamReader.h?rev=69145&r1=69144&r2=69145&view=diff ============================================================================== --- llvm/trunk/include/llvm/Bitcode/BitstreamReader.h (original) +++ llvm/trunk/include/llvm/Bitcode/BitstreamReader.h Tue Apr 14 23:53:47 2009 @@ -122,7 +122,7 @@ void JumpToBit(uint64_t BitNo) { uintptr_t ByteNo = uintptr_t(BitNo/8) & ~3; uintptr_t WordBitNo = uintptr_t(BitNo) & 31; - assert(ByteNo < (uintptr_t)(LastChar-FirstChar) && "Invalid location"); + assert(ByteNo <= (uintptr_t)(LastChar-FirstChar) && "Invalid location"); // Move the cursor to the right word. NextChar = FirstChar+ByteNo; From nicholas at mxc.ca Tue Apr 14 23:56:53 2009 From: nicholas at mxc.ca (Nick Lewycky) Date: Tue, 14 Apr 2009 21:56:53 -0700 Subject: [llvm-commits] [llvm] r69116 - in /llvm/trunk: include/llvm/CodeGen/DwarfWriter.h lib/CodeGen/AsmPrinter/AsmPrinter.cpp lib/CodeGen/AsmPrinter/DwarfWriter.cpp lib/CodeGen/SelectionDAG/FastISel.cpp In-Reply-To: <200904150010.n3F0ARFR021382@zion.cs.uiuc.edu> References: <200904150010.n3F0ARFR021382@zion.cs.uiuc.edu> Message-ID: <49E56915.9040708@mxc.ca> Hi Devang, Either this patch or r69115 introduced a new failure in test/DebugInfo/2008-11-05-InlinedFuncStart.ll , and given that that the other patch didn't claim to affect debug info I'm suspecting this one. Please investigate. http://google1.osuosl.org:8011/builders/llvm-x86_64-linux/builds/3218/steps/test/logs/stdio Nick Devang Patel wrote: > Author: dpatel > Date: Tue Apr 14 19:10:26 2009 > New Revision: 69116 > > URL: http://llvm.org/viewvc/llvm-project?rev=69116&view=rev > Log: > Construct and emit DW_TAG_inlined_subroutine DIEs for inlined subroutine scopes (only in FastISel mode). > > Modified: > llvm/trunk/include/llvm/CodeGen/DwarfWriter.h > llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp > llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp > llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp > > Modified: llvm/trunk/include/llvm/CodeGen/DwarfWriter.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/DwarfWriter.h?rev=69116&r1=69115&r2=69116&view=diff > > ============================================================================== > --- llvm/trunk/include/llvm/CodeGen/DwarfWriter.h (original) > +++ llvm/trunk/include/llvm/CodeGen/DwarfWriter.h Tue Apr 14 19:10:26 2009 > @@ -29,11 +29,15 @@ > class DwarfException; > class MachineModuleInfo; > class MachineFunction; > +class MachineInstr; > class Value; > class Module; > class GlobalVariable; > class TargetAsmInfo; > class raw_ostream; > +class Instruction; > +class DISubprogram; > +class DIVariable; > > //===----------------------------------------------------------------------===// > // DwarfWriter - Emits Dwarf debug and exception handling directives. > @@ -94,9 +98,6 @@ > /// RecordRegionStart - Indicate the start of a region. > unsigned RecordRegionStart(GlobalVariable *V); > > - /// RecordRegionStart - Indicate the start of a region. > - unsigned RecordRegionStart(GlobalVariable *V, unsigned ID); > - > /// RecordRegionEnd - Indicate the end of a region. > unsigned RecordRegionEnd(GlobalVariable *V); > > @@ -105,15 +106,23 @@ > > /// RecordVariable - Indicate the declaration of a local variable. > /// > - void RecordVariable(GlobalVariable *GV, unsigned FrameIndex); > + void RecordVariable(GlobalVariable *GV, unsigned FrameIndex, > + const MachineInstr *MI); > > /// ShouldEmitDwarfDebug - Returns true if Dwarf debugging declarations should > /// be emitted. > bool ShouldEmitDwarfDebug() const; > > - //// RecordInlineInfo - Global variable GV is inlined at the location marked > - //// by LabelID label. > - void RecordInlineInfo(GlobalVariable *GV, unsigned LabelID); > + //// RecordInlinedFnStart - Indicate the start of a inlined function. > + void RecordInlinedFnStart(Instruction *I, DISubprogram &SP, unsigned LabelID, > + unsigned Src, unsigned Line, unsigned Col); > + > + /// RecordInlinedFnEnd - Indicate the end of inlined subroutine. > + unsigned RecordInlinedFnEnd(DISubprogram &SP); > + > + /// RecordVariableScope - Record scope for the variable declared by > + /// DeclareMI. DeclareMI must describe TargetInstrInfo::DECLARE. > + void RecordVariableScope(DIVariable &DV, const MachineInstr *DeclareMI); > }; > > > > Modified: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp?rev=69116&r1=69115&r2=69116&view=diff > > ============================================================================== > --- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (original) > +++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Tue Apr 14 19:10:26 2009 > @@ -1532,7 +1532,7 @@ > void AsmPrinter::printDeclare(const MachineInstr *MI) const { > unsigned FI = MI->getOperand(0).getIndex(); > GlobalValue *GV = MI->getOperand(1).getGlobal(); > - DW->RecordVariable(cast(GV), FI); > + DW->RecordVariable(cast(GV), FI, MI); > } > > /// PrintAsmOperand - Print the specified operand of MI, an INLINEASM > > Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp?rev=69116&r1=69115&r2=69116&view=diff > > ============================================================================== > --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp (original) > +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp Tue Apr 14 19:10:26 2009 > @@ -1140,7 +1140,7 @@ > DbgScope(DbgScope *P, DIDescriptor D) > : Parent(P), Desc(D), StartLabelID(0), EndLabelID(0), Scopes(), Variables() > {} > - ~DbgScope() { > + virtual ~DbgScope() { > for (unsigned i = 0, N = Scopes.size(); i < N; ++i) delete Scopes[i]; > for (unsigned j = 0, M = Variables.size(); j < M; ++j) delete Variables[j]; > } > @@ -1162,6 +1162,32 @@ > /// AddVariable - Add a variable to the scope. > /// > void AddVariable(DbgVariable *V) { Variables.push_back(V); } > + > + virtual bool isInlinedSubroutine() { return false; } > + virtual unsigned getLine() { assert ( 0 && "Unexpected scope!"); } > + virtual unsigned getColumn() { assert ( 0 && "Unexpected scope!"); } > + virtual unsigned getFile() { assert ( 0 && "Unexpected scope!"); } > +}; > + > + > +//===----------------------------------------------------------------------===// > +/// DbgInlinedSubroutineScope - This class is used to track inlined subroutine > +/// scope information. > +/// > +class DbgInlinedSubroutineScope : public DbgScope { > + unsigned Src; > + unsigned Line; > + unsigned Col; > +public: > + DbgInlinedSubroutineScope(DbgScope *P, DIDescriptor D, > + unsigned S, unsigned L, unsigned C) > + : DbgScope(P, D), Src(S), Line(L), Col(C) > + {} > + > + unsigned getLine() { return Line; } > + unsigned getColumn() { return Col; } > + unsigned getFile() { return Src; } > + bool isInlinedSubroutine() { return true; } > }; > > //===----------------------------------------------------------------------===// > @@ -1252,10 +1278,17 @@ > /// DbgScopeMap - Tracks the scopes in the current function. > DenseMap DbgScopeMap; > > + /// DbgInlinedScopeMap - Tracks inlined scopes in the current function. > + DenseMap > DbgInlinedScopeMap; > + > /// InlineInfo - Keep track of inlined functions and their location. > /// This information is used to populate debug_inlined section. > DenseMap > InlineInfo; > > + /// InlinedVariableScopes - Scopes information for the inlined subroutine > + /// variables. > + DenseMap InlinedVariableScopes; > + > /// DebugTimer - Timer for the Dwarf debug writer. > Timer *DebugTimer; > > @@ -1469,7 +1502,7 @@ > /// AddDelta - Add a label delta attribute data and value. > /// > void AddDelta(DIE *Die, unsigned Attribute, unsigned Form, > - const DWLabel &Hi, const DWLabel &Lo) { > + const DWLabel &Hi, const DWLabel &Lo) { > FoldingSetNodeID ID; > DIEDelta::Profile(ID, Hi, Lo); > void *Where; > @@ -1550,7 +1583,7 @@ > /// AddAddress - Add an address attribute to a die based on the location > /// provided. > void AddAddress(DIE *Die, unsigned Attribute, > - const MachineLocation &Location) { > + const MachineLocation &Location) { > unsigned Reg = RI->getDwarfRegNum(Location.getReg(), false); > DIEBlock *Block = new DIEBlock(); > > @@ -1933,6 +1966,10 @@ > > if (!SP.isLocalToUnit()) > AddUInt(SPDie, DW_AT_external, DW_FORM_flag, 1); > + > + // DW_TAG_inlined_subroutine may refer to this DIE. > + DIE *&Slot = DW_Unit->getDieMapSlotFor(SP.getGV()); > + Slot = SPDie; > return SPDie; > } > > @@ -1987,33 +2024,39 @@ > DbgScope *&Slot = DbgScopeMap[V]; > if (Slot) return Slot; > > - // FIXME - breaks down when the context is an inlined function. > - DIDescriptor ParentDesc; > - DIDescriptor Desc(V); > - > - if (Desc.getTag() == dwarf::DW_TAG_lexical_block) { > - DIBlock Block(V); > - ParentDesc = Block.getContext(); > + DbgScope *Parent = NULL; > + DIBlock Block(V); > + if (!Block.isNull()) { > + DIDescriptor ParentDesc = Block.getContext(); > + Parent = > + ParentDesc.isNull() ? NULL : getOrCreateScope(ParentDesc.getGV()); > } > + Slot = new DbgScope(Parent, DIDescriptor(V)); > > - DbgScope *Parent = ParentDesc.isNull() ? > - NULL : getOrCreateScope(ParentDesc.getGV()); > - Slot = new DbgScope(Parent, Desc); > - > - if (Parent) { > + if (Parent) > Parent->AddScope(Slot); > - } else if (RootDbgScope) { > - // FIXME - Add inlined function scopes to the root so we can delete them > - // later. Long term, handle inlined functions properly. > - RootDbgScope->AddScope(Slot); > - } else { > + else > // First function is top level function. > RootDbgScope = Slot; > - } > > return Slot; > } > > + /// createInlinedSubroutineScope - Returns the scope associated with the > + /// inlined subroutine. > + /// > + DbgScope *createInlinedSubroutineScope(DISubprogram SP, unsigned Src, > + unsigned Line, unsigned Col) { > + DbgScope *Scope = > + new DbgInlinedSubroutineScope(NULL, SP, Src, Line, Col); > + > + // FIXME - Add inlined function scopes to the root so we can delete them > + // later. > + assert (RootDbgScope && "Function scope info missing!"); > + RootDbgScope->AddScope(Scope); > + return Scope; > + } > + > /// ConstructDbgScope - Construct the components of a scope. > /// > void ConstructDbgScope(DbgScope *ParentScope, > @@ -2035,12 +2078,11 @@ > unsigned StartID = MMI->MappedLabel(Scope->getStartLabelID()); > unsigned EndID = MMI->MappedLabel(Scope->getEndLabelID()); > > - // Ignore empty scopes. > + // Ignore empty scopes. > + // Do not ignore inlined scope even if it does not have any > + // variables or scopes. > if (StartID == EndID && StartID != 0) continue; > - > - // Do not ignore inlined scope even if it is empty. Inlined scope > - // does not have any parent. > - if (Scope->getParent() > + if (!Scope->isInlinedSubroutine() > && Scope->getScopes().empty() && Scope->getVariables().empty()) > continue; > > @@ -2048,27 +2090,37 @@ > // Just add stuff to the parent scope. > ConstructDbgScope(Scope, ParentStartID, ParentEndID, ParentDie, Unit); > } else { > - DIE *ScopeDie = new DIE(DW_TAG_lexical_block); > - > - // Add the scope bounds. > - if (StartID) { > - AddLabel(ScopeDie, DW_AT_low_pc, DW_FORM_addr, > - DWLabel("label", StartID)); > - } else { > - AddLabel(ScopeDie, DW_AT_low_pc, DW_FORM_addr, > - DWLabel("func_begin", SubprogramCount)); > + DIE *ScopeDie = NULL; > + if (MainCU && TAI->doesDwarfUsesInlineInfoSection()) { > + ScopeDie = new DIE(DW_TAG_inlined_subroutine); > + DIE *Origin = MainCU->getDieMapSlotFor(Scope->getDesc().getGV()); > + AddDIEntry(ScopeDie, DW_AT_abstract_origin, DW_FORM_ref4, Origin); > + AddUInt(ScopeDie, DW_AT_call_file, 0, Scope->getFile()); > + AddUInt(ScopeDie, DW_AT_call_line, 0, Scope->getLine()); > + AddUInt(ScopeDie, DW_AT_call_column, 0, Scope->getColumn()); > } > - if (EndID) { > - AddLabel(ScopeDie, DW_AT_high_pc, DW_FORM_addr, > - DWLabel("label", EndID)); > - } else { > - AddLabel(ScopeDie, DW_AT_high_pc, DW_FORM_addr, > - DWLabel("func_end", SubprogramCount)); > - } > - > - // Add the scope contents. > - ConstructDbgScope(Scope, StartID, EndID, ScopeDie, Unit); > - ParentDie->AddChild(ScopeDie); > + else > + ScopeDie = new DIE(DW_TAG_lexical_block); > + > + // Add the scope bounds. > + if (StartID) { > + AddLabel(ScopeDie, DW_AT_low_pc, DW_FORM_addr, > + DWLabel("label", StartID)); > + } else { > + AddLabel(ScopeDie, DW_AT_low_pc, DW_FORM_addr, > + DWLabel("func_begin", SubprogramCount)); > + } > + if (EndID) { > + AddLabel(ScopeDie, DW_AT_high_pc, DW_FORM_addr, > + DWLabel("label", EndID)); > + } else { > + AddLabel(ScopeDie, DW_AT_high_pc, DW_FORM_addr, > + DWLabel("func_end", SubprogramCount)); > + } > + > + // Add the scope contents. > + ConstructDbgScope(Scope, StartID, EndID, ScopeDie, Unit); > + ParentDie->AddChild(ScopeDie); > } > } > } > @@ -3286,6 +3338,8 @@ > if (RootDbgScope) { > delete RootDbgScope; > DbgScopeMap.clear(); > + DbgInlinedScopeMap.clear(); > + InlinedVariableScopes.clear(); > RootDbgScope = NULL; > } > > @@ -3423,20 +3477,6 @@ > return ID; > } > > - /// RecordRegionStart - Indicate the start of a region. > - unsigned RecordRegionStart(GlobalVariable *V, unsigned ID) { > - if (TimePassesIsEnabled) > - DebugTimer->startTimer(); > - > - DbgScope *Scope = getOrCreateScope(V); > - if (!Scope->getStartLabelID()) Scope->setStartLabelID(ID); > - > - if (TimePassesIsEnabled) > - DebugTimer->stopTimer(); > - > - return ID; > - } > - > /// RecordRegionEnd - Indicate the end of a region. > unsigned RecordRegionEnd(GlobalVariable *V) { > if (TimePassesIsEnabled) > @@ -3453,7 +3493,8 @@ > } > > /// RecordVariable - Indicate the declaration of a local variable. > - void RecordVariable(GlobalVariable *GV, unsigned FrameIndex) { > + void RecordVariable(GlobalVariable *GV, unsigned FrameIndex, > + const MachineInstr *MI) { > if (TimePassesIsEnabled) > DebugTimer->startTimer(); > > @@ -3465,9 +3506,16 @@ > DIGlobalVariable DG(GV); > Scope = getOrCreateScope(DG.getContext().getGV()); > } else { > + DenseMap::iterator > + SI = InlinedVariableScopes.find(MI); > + if (SI != InlinedVariableScopes.end()) { > + // or GV is an inlined local variable. > + Scope = SI->second; > + } else { > // or GV is a local variable. > - DIVariable DV(GV); > - Scope = getOrCreateScope(DV.getContext().getGV()); > + DIVariable DV(GV); > + Scope = getOrCreateScope(DV.getContext().getGV()); > + } > } > > assert(Scope && "Unable to find variable' scope"); > @@ -3478,10 +3526,28 @@ > DebugTimer->stopTimer(); > } > > - //// RecordInlineInfo - Global variable GV is inlined at the location marked > - //// by LabelID label. > - void RecordInlineInfo(GlobalVariable *GV, unsigned LabelID) { > + //// RecordInlinedFnStart - Indicate the start of inlined subroutine. > + void RecordInlinedFnStart(Instruction *FSI, DISubprogram &SP, unsigned LabelID, > + unsigned Src, unsigned Line, unsigned Col) { > + if (!TAI->doesDwarfUsesInlineInfoSection()) > + return; > + > + DbgScope *Scope = createInlinedSubroutineScope(SP, Src, Line, Col); > + Scope->setStartLabelID(LabelID); > MMI->RecordUsedDbgLabel(LabelID); > + GlobalVariable *GV = SP.getGV(); > + > + DenseMap >::iterator > + SI = DbgInlinedScopeMap.find(GV); > + if (SI == DbgInlinedScopeMap.end()) { > + SmallVector Scopes; > + Scopes.push_back(Scope); > + DbgInlinedScopeMap[GV] = Scopes; > + } else { > + SmallVector &Scopes = SI->second; > + Scopes.push_back(Scope); > + } > + > DenseMap >::iterator > I = InlineInfo.find(GV); > if (I == InlineInfo.end()) { > @@ -3494,6 +3560,43 @@ > SmallVector &Labels = I->second; > Labels.push_back(LabelID); > } > + > + /// RecordInlinedFnEnd - Indicate the end of inlined subroutine. > + unsigned RecordInlinedFnEnd(DISubprogram &SP) { > + if (!TAI->doesDwarfUsesInlineInfoSection()) > + return 0; > + > + GlobalVariable *GV = SP.getGV(); > + DenseMap >::iterator > + I = DbgInlinedScopeMap.find(GV); > + if (I == DbgInlinedScopeMap.end()) > + return 0; > + > + SmallVector &Scopes = I->second; > + DbgScope *Scope = Scopes.back(); Scopes.pop_back(); > + unsigned ID = MMI->NextLabelID(); > + MMI->RecordUsedDbgLabel(ID); > + Scope->setEndLabelID(ID); > + return ID; > + } > + > + /// RecordVariableScope - Record scope for the variable declared by > + /// DeclareMI. DeclareMI must describe TargetInstrInfo::DECLARE. > + /// Record scopes for only inlined subroutine variables. Other > + /// variables' scopes are determined during RecordVariable(). > + void RecordVariableScope(DIVariable &DV, const MachineInstr *DeclareMI) { > + DISubprogram SP(DV.getContext().getGV()); > + if (SP.isNull()) > + return; > + DenseMap >::iterator > + I = DbgInlinedScopeMap.find(SP.getGV()); > + if (I == DbgInlinedScopeMap.end()) > + return; > + > + SmallVector &Scopes = I->second; > + InlinedVariableScopes[DeclareMI] = Scopes.back(); > + } > + > }; > > //===----------------------------------------------------------------------===// > @@ -4652,11 +4755,6 @@ > return DD->RecordRegionStart(V); > } > > -/// RecordRegionStart - Indicate the start of a region. > -unsigned DwarfWriter::RecordRegionStart(GlobalVariable *V, unsigned ID) { > - return DD->RecordRegionStart(V, ID); > -} > - > /// RecordRegionEnd - Indicate the end of a region. > unsigned DwarfWriter::RecordRegionEnd(GlobalVariable *V) { > return DD->RecordRegionEnd(V); > @@ -4669,8 +4767,9 @@ > > /// RecordVariable - Indicate the declaration of a local variable. > /// > -void DwarfWriter::RecordVariable(GlobalVariable *GV, unsigned FrameIndex) { > - DD->RecordVariable(GV, FrameIndex); > +void DwarfWriter::RecordVariable(GlobalVariable *GV, unsigned FrameIndex, > + const MachineInstr *MI) { > + DD->RecordVariable(GV, FrameIndex, MI); > } > > /// ShouldEmitDwarfDebug - Returns true if Dwarf debugging declarations should > @@ -4679,9 +4778,22 @@ > return DD->ShouldEmitDwarfDebug(); > } > > -//// RecordInlineInfo - Global variable GV is inlined at the location marked > +//// RecordInlinedFnStart - Global variable GV is inlined at the location marked > //// by LabelID label. > -void DwarfWriter::RecordInlineInfo(GlobalVariable *GV, unsigned LabelID) { > - DD->RecordInlineInfo(GV, LabelID); > +void DwarfWriter::RecordInlinedFnStart(Instruction *I, DISubprogram &SP, > + unsigned LabelID, unsigned Src, > + unsigned Line, unsigned Col) { > + DD->RecordInlinedFnStart(I, SP, LabelID, Src, Line, Col); > +} > + > +/// RecordInlinedFnEnd - Indicate the end of inlined subroutine. > +unsigned DwarfWriter::RecordInlinedFnEnd(DISubprogram &SP) { > + return DD->RecordInlinedFnEnd(SP); > +} > + > +/// RecordVariableScope - Record scope for the variable declared by > +/// DeclareMI. DeclareMI must describe TargetInstrInfo::DECLARE. > +void DwarfWriter::RecordVariableScope(DIVariable &DV, > + const MachineInstr *DeclareMI) { > + DD->RecordVariableScope(DV, DeclareMI); > } > - > > Modified: llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp?rev=69116&r1=69115&r2=69116&view=diff > > ============================================================================== > --- llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp (original) > +++ llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp Tue Apr 14 19:10:26 2009 > @@ -47,6 +47,7 @@ > #include "llvm/CodeGen/MachineInstrBuilder.h" > #include "llvm/CodeGen/MachineModuleInfo.h" > #include "llvm/CodeGen/MachineRegisterInfo.h" > +#include "llvm/CodeGen/DebugLoc.h" > #include "llvm/CodeGen/DwarfWriter.h" > #include "llvm/Analysis/DebugInfo.h" > #include "llvm/Target/TargetData.h" > @@ -354,10 +355,18 @@ > case Intrinsic::dbg_region_end: { > DbgRegionEndInst *REI = cast(I); > if (DW && DW->ValidDebugInfo(REI->getContext(), true)) { > - unsigned ID = > - DW->RecordRegionEnd(cast(REI->getContext())); > - const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL); > - BuildMI(MBB, DL, II).addImm(ID); > + unsigned ID = 0; > + DISubprogram Subprogram(cast(REI->getContext())); > + if (!Subprogram.describes(MF.getFunction())) { > + // This is end of an inlined function. > + const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL); > + ID = DW->RecordInlinedFnEnd(Subprogram); > + BuildMI(MBB, DL, II).addImm(ID); > + } else { > + const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL); > + ID = DW->RecordRegionEnd(cast(REI->getContext())); > + BuildMI(MBB, DL, II).addImm(ID); > + } > } > return true; > } > @@ -369,6 +378,7 @@ > if (DW->ValidDebugInfo(SP, true)) { > // llvm.dbg.func.start implicitly defines a dbg_stoppoint which is what > // (most?) gdb expects. > + DebugLoc PrevLoc = DL; > DISubprogram Subprogram(cast(SP)); > DICompileUnit CompileUnit = Subprogram.getCompileUnit(); > std::string Dir, FN; > @@ -379,17 +389,15 @@ > unsigned Line = Subprogram.getLineNumber(); > unsigned LabelID = DW->RecordSourceLine(Line, 0, SrcFile); > setCurDebugLoc(DebugLoc::get(MF.getOrCreateDebugLocID(SrcFile, Line, 0))); > - > - std::string SPName; > - Subprogram.getLinkageName(SPName); > - if (!SPName.empty() > - && strcmp(SPName.c_str(), MF.getFunction()->getNameStart())) { > - // This is a beginning of inlined function. > - DW->RecordRegionStart(cast(FSI->getSubprogram()), > - LabelID); > + if (!Subprogram.describes(MF.getFunction())) { > + // This is a beginning of an inlined function. > const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL); > BuildMI(MBB, DL, II).addImm(LabelID); > - DW->RecordInlineInfo(Subprogram.getGV(), LabelID); > + DebugLocTuple PrevLocTpl = MF.getDebugLocTuple(PrevLoc); > + DW->RecordInlinedFnStart(FSI, Subprogram, LabelID, > + PrevLocTpl.Src, > + PrevLocTpl.Line, > + PrevLocTpl.Col); > } else { > // llvm.dbg.func_start also defines beginning of function scope. > DW->RecordRegionStart(cast(FSI->getSubprogram())); > @@ -419,7 +427,13 @@ > > // Build the DECLARE instruction. > const TargetInstrDesc &II = TII.get(TargetInstrInfo::DECLARE); > - BuildMI(MBB, DL, II).addFrameIndex(FI).addGlobalAddress(GV); > + MachineInstr *DeclareMI > + = BuildMI(MBB, DL, II).addFrameIndex(FI).addGlobalAddress(GV); > + DIVariable DV(cast(GV)); > + if (!DV.isNull()) { > + // This is a local variable > + DW->RecordVariableScope(DV, DeclareMI); > + } > } > return true; > } > > > _______________________________________________ > 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 Wed Apr 15 00:10:48 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 14 Apr 2009 22:10:48 -0700 Subject: [llvm-commits] [llvm] r69102 - in /llvm/trunk: lib/Transforms/Scalar/CondPropagate.cpp test/Transforms/CondProp/phisimplify3.ll In-Reply-To: References: <200904142340.n3ENe4FD020265@zion.cs.uiuc.edu> Message-ID: <6924812B-5974-49B3-9068-5EF883F8E991@apple.com> I have no problem with sucking the transformations into another pass and removing condprop. Patches welcome. :-) Evan On Apr 14, 2009, at 8:27 PM, Eli Friedman wrote: > On Tue, Apr 14, 2009 at 4:40 PM, Evan Cheng > wrote: >> Author: evancheng >> Date: Tue Apr 14 18:40:03 2009 >> New Revision: 69102 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=69102&view=rev >> Log: >> Optimize conditional branch on i1 phis with non-constant inputs. > > See http://llvm.org/bugs/show_bug.cgi?id=3906? > > -Eli > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From nicholas at mxc.ca Wed Apr 15 01:23:41 2009 From: nicholas at mxc.ca (Nick Lewycky) Date: Wed, 15 Apr 2009 06:23:41 -0000 Subject: [llvm-commits] [llvm] r69151 - /llvm/trunk/lib/VMCore/Value.cpp Message-ID: <200904150623.n3F6NfHY001090@zion.cs.uiuc.edu> Author: nicholas Date: Wed Apr 15 01:23:41 2009 New Revision: 69151 URL: http://llvm.org/viewvc/llvm-project?rev=69151&view=rev Log: Limit the number of times we're willing to chase pointers. Removes an O(n^2) problem from instcombine. Modified: llvm/trunk/lib/VMCore/Value.cpp Modified: llvm/trunk/lib/VMCore/Value.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Value.cpp?rev=69151&r1=69150&r2=69151&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Value.cpp (original) +++ llvm/trunk/lib/VMCore/Value.cpp Wed Apr 15 01:23:41 2009 @@ -365,6 +365,7 @@ if (!isa(getType())) return this; Value *V = this; + unsigned MaxLookup = 6; do { if (Instruction *I = dyn_cast(V)) { if (!isa(I) && !isa(I)) @@ -379,7 +380,8 @@ return V; } assert(isa(V->getType()) && "Unexpected operand type!"); - } while (1); + } while (--MaxLookup); + return V; } /// DoPHITranslation - If this value is a PHI node with CurBB as its parent, From sabre at nondot.org Wed Apr 15 01:26:50 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 15 Apr 2009 06:26:50 -0000 Subject: [llvm-commits] [llvm] r69152 - /llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp Message-ID: <200904150626.n3F6Qoql001251@zion.cs.uiuc.edu> Author: lattner Date: Wed Apr 15 01:26:49 2009 New Revision: 69152 URL: http://llvm.org/viewvc/llvm-project?rev=69152&view=rev Log: minor cleanups Modified: llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp Modified: llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp?rev=69152&r1=69151&r2=69152&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp Wed Apr 15 01:26:49 2009 @@ -20,7 +20,6 @@ #include "llvm/ADT/DenseSet.h" #include #include - using namespace llvm; //===----------------------------------------------------------------------===// @@ -68,8 +67,8 @@ // Warning Tables (.inc file) generation. //===----------------------------------------------------------------------===// -static void ProcessDiag(std::ostream& OS, const Record* DiagClass, - const Record& R) { +static void ProcessDiag(std::ostream &OS, const Record *DiagClass, + const Record &R) { const Record* DiagKind = getDiagKind(DiagClass, R); if (!DiagKind) @@ -107,17 +106,12 @@ } for (RecordVector::const_iterator I=Diags.begin(), E=Diags.end(); I!=E; ++I) { - if (!Component.empty()) { - const RecordVal* V = findRecordVal(**I, "Component"); - if (!V) - continue; - - const StringInit* SV = dynamic_cast(V->getValue()); - if (!SV || SV->getValue() != Component) - continue; - } + const Record &R = **I; + // Filter by component. + if (!Component.empty() && Component != R.getValueAsString("Component")) + continue; - ProcessDiag(OS, DiagClass, **I); + ProcessDiag(OS, DiagClass, R); } } @@ -169,8 +163,8 @@ // If an Option includes another Option, inline the Diagnostics of the // included Option. if (Def->isSubClassOf("Option")) { - if (const RecordVal* V = findRecordVal(*Def, "Members")) - if (const ListInit* LV = dynamic_cast(V->getValue())) + if (const RecordVal *V = findRecordVal(*Def, "Members")) + if (const ListInit *LV = dynamic_cast(V->getValue())) BuildGroup(DS, Visited, LV); return; @@ -192,10 +186,10 @@ void ClangOptionsEmitter::run(std::ostream &OS) { // Build up a map from options to controlled diagnostics. - OptionMap OM; + OptionMap OM; const RecordVector &Opts = Records.getAllDerivedDefinitions("Option"); - for (RecordVector::const_iterator I=Opts.begin(), E=Opts.end(); I!=E; ++I) + for (RecordVector::const_iterator I=Opts.begin(), E=Opts.end(); I != E; ++I) if (const RecordVal* V = findRecordVal(**I, "Members")) if (const ListInit* LV = dynamic_cast(V->getValue())) { VisitedLists Visited; From sabre at nondot.org Wed Apr 15 11:43:21 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 15 Apr 2009 16:43:21 -0000 Subject: [llvm-commits] [llvm] r69173 - /llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp Message-ID: <200904151643.n3FGhMdW000354@zion.cs.uiuc.edu> Author: lattner Date: Wed Apr 15 11:43:18 2009 New Revision: 69173 URL: http://llvm.org/viewvc/llvm-project?rev=69173&view=rev Log: include the default mapping in the clang diagnostic .inc files. Modified: llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp Modified: llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp?rev=69173&r1=69172&r2=69173&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp Wed Apr 15 11:43:18 2009 @@ -69,20 +69,15 @@ static void ProcessDiag(std::ostream &OS, const Record *DiagClass, const Record &R) { - const Record* DiagKind = getDiagKind(DiagClass, R); if (!DiagKind) return; OS << "DIAG(" << R.getName() << ", "; EmitAllCaps(OS, DiagKind->getName()); - - const RecordVal* Text = findRecordVal(R, "Text"); - assert(Text && "No 'Text' entry in Diagnostic."); - const StringInit* TextVal = dynamic_cast(Text->getValue()); - assert(TextVal && "Value 'Text' must be a string."); + OS << ", diag::" << R.getValueAsDef("DefaultMapping")->getName(); OS << ", \""; - EmitEscaped(OS, TextVal->getValue()); + EmitEscaped(OS, R.getValueAsString("Text")); OS << "\")\n"; } From sabre at nondot.org Wed Apr 15 11:55:53 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 15 Apr 2009 16:55:53 -0000 Subject: [llvm-commits] [llvm] r69176 - /llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp Message-ID: <200904151655.n3FGtsuD000795@zion.cs.uiuc.edu> Author: lattner Date: Wed Apr 15 11:55:46 2009 New Revision: 69176 URL: http://llvm.org/viewvc/llvm-project?rev=69176&view=rev Log: don't infer diag class from parenting relations, make it an explicit field in the record. Modified: llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp Modified: llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp?rev=69176&r1=69175&r2=69176&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp Wed Apr 15 11:55:46 2009 @@ -39,16 +39,6 @@ return 0; } -static const Record* getDiagKind(const Record* DiagClass, const Record &R) { - const SuperClassVector &SC = R.getSuperClasses(); - for (SuperClassVector::const_iterator I=SC.begin(), E=SC.end(); I!=E; ++I) - if ((*I)->isSubClassOf(DiagClass) && - (*I)->getName() != "DiagnosticControlled") - return *I; - - return 0; -} - static void EmitEscaped(std::ostream& OS, const std::string &s) { for (std::string::const_iterator I=s.begin(), E=s.end(); I!=E; ++I) switch (*I) { @@ -69,12 +59,8 @@ static void ProcessDiag(std::ostream &OS, const Record *DiagClass, const Record &R) { - const Record* DiagKind = getDiagKind(DiagClass, R); - if (!DiagKind) - return; - OS << "DIAG(" << R.getName() << ", "; - EmitAllCaps(OS, DiagKind->getName()); + OS << R.getValueAsDef("Class")->getName(); OS << ", diag::" << R.getValueAsDef("DefaultMapping")->getName(); OS << ", \""; EmitEscaped(OS, R.getValueAsString("Text")); From gohman at apple.com Wed Apr 15 12:59:12 2009 From: gohman at apple.com (Dan Gohman) Date: Wed, 15 Apr 2009 17:59:12 -0000 Subject: [llvm-commits] [llvm] r69190 - /llvm/trunk/lib/CodeGen/MachineInstr.cpp Message-ID: <200904151759.n3FHxCvA003808@zion.cs.uiuc.edu> Author: djg Date: Wed Apr 15 12:59:11 2009 New Revision: 69190 URL: http://llvm.org/viewvc/llvm-project?rev=69190&view=rev Log: Fix MachineInstr::getNumExplicitOperands to count variadic operands correctly. Patch by Jakob Stoklund Olesen! Modified: llvm/trunk/lib/CodeGen/MachineInstr.cpp Modified: llvm/trunk/lib/CodeGen/MachineInstr.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineInstr.cpp?rev=69190&r1=69189&r2=69190&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineInstr.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineInstr.cpp Wed Apr 15 12:59:11 2009 @@ -623,8 +623,8 @@ if (!TID->isVariadic()) return NumOperands; - for (unsigned e = getNumOperands(); NumOperands != e; ++NumOperands) { - const MachineOperand &MO = getOperand(NumOperands); + for (unsigned i = NumOperands, e = getNumOperands(); i != e; ++i) { + const MachineOperand &MO = getOperand(i); if (!MO.isReg() || !MO.isImplicit()) NumOperands++; } From dpatel at apple.com Wed Apr 15 14:42:59 2009 From: dpatel at apple.com (Devang Patel) Date: Wed, 15 Apr 2009 19:42:59 -0000 Subject: [llvm-commits] [llvm] r69202 - /llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp Message-ID: <200904151942.n3FJgxrE007858@zion.cs.uiuc.edu> Author: dpatel Date: Wed Apr 15 14:42:57 2009 New Revision: 69202 URL: http://llvm.org/viewvc/llvm-project?rev=69202&view=rev Log: Check isInlinedSubroutine() before creating DW_TAG_inlined_subroutine. Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp?rev=69202&r1=69201&r2=69202&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp Wed Apr 15 14:42:57 2009 @@ -2091,7 +2091,8 @@ ConstructDbgScope(Scope, ParentStartID, ParentEndID, ParentDie, Unit); } else { DIE *ScopeDie = NULL; - if (MainCU && TAI->doesDwarfUsesInlineInfoSection()) { + if (MainCU && TAI->doesDwarfUsesInlineInfoSection() + && Scope->isInlinedSubroutine()) { ScopeDie = new DIE(DW_TAG_inlined_subroutine); DIE *Origin = MainCU->getDieMapSlotFor(Scope->getDesc().getGV()); AddDIEntry(ScopeDie, DW_AT_abstract_origin, DW_FORM_ref4, Origin); From gohman at apple.com Wed Apr 15 14:48:28 2009 From: gohman at apple.com (Dan Gohman) Date: Wed, 15 Apr 2009 19:48:28 -0000 Subject: [llvm-commits] [llvm] r69203 - /llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Message-ID: <200904151948.n3FJmSZc008035@zion.cs.uiuc.edu> Author: djg Date: Wed Apr 15 14:48:28 2009 New Revision: 69203 URL: http://llvm.org/viewvc/llvm-project?rev=69203&view=rev Log: Add a folding table entry for MOV8rr_NOREX. Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=69203&r1=69202&r2=69203&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Wed Apr 15 14:48:28 2009 @@ -264,6 +264,7 @@ { X86::MOV64rr, X86::MOV64mr, 0 }, { X86::MOV8ri, X86::MOV8mi, 0 }, { X86::MOV8rr, X86::MOV8mr, 0 }, + { X86::MOV8rr_NOREX, X86::MOV8mr_NOREX, 0 }, { X86::MOVAPDrr, X86::MOVAPDmr, 0 }, { X86::MOVAPSrr, X86::MOVAPSmr, 0 }, { X86::MOVDQArr, X86::MOVDQAmr, 0 }, From gohman at apple.com Wed Apr 15 14:48:58 2009 From: gohman at apple.com (Dan Gohman) Date: Wed, 15 Apr 2009 19:48:58 -0000 Subject: [llvm-commits] [llvm] r69204 - in /llvm/trunk/lib/Target/X86: X86InstrInfo.cpp X86InstrInfo.td Message-ID: <200904151948.n3FJmwrr008069@zion.cs.uiuc.edu> Author: djg Date: Wed Apr 15 14:48:57 2009 New Revision: 69204 URL: http://llvm.org/viewvc/llvm-project?rev=69204&view=rev Log: Fix 80-column violations. Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp llvm/trunk/lib/Target/X86/X86InstrInfo.td Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=69204&r1=69203&r2=69204&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Wed Apr 15 14:48:57 2009 @@ -1664,8 +1664,8 @@ } else if (DestRC == &X86::GR16RegClass) { Opc = X86::MOV16rr; } else if (DestRC == &X86::GR8RegClass) { - // Copying two or from a physical H register requires a NOREX move. Otherwise - // use a normal move. + // Copying two or from a physical H register requires a NOREX move. + // Otherwise use a normal move. if (isHReg(DestReg) || isHReg(SrcReg)) Opc = X86::MOV8rr_NOREX; else Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=69204&r1=69203&r2=69204&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Wed Apr 15 14:48:57 2009 @@ -787,7 +787,8 @@ // can be used for copying and storing h registers, which can't be encoded when // a REX prefix is present. let neverHasSideEffects = 1 in -def MOV8rr_NOREX : I<0x88, MRMDestReg, (outs GR8_NOREX:$dst), (ins GR8_NOREX:$src), +def MOV8rr_NOREX : I<0x88, MRMDestReg, + (outs GR8_NOREX:$dst), (ins GR8_NOREX:$src), "mov{b}\t{$src, $dst|$dst, $src} # NOREX", []>; def MOV8mr_NOREX : I<0x88, MRMDestMem, (outs), (ins i8mem_NOREX:$dst, GR8_NOREX:$src), From sabre at nondot.org Wed Apr 15 14:57:42 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 15 Apr 2009 19:57:42 -0000 Subject: [llvm-commits] [llvm] r69206 - /llvm/trunk/Makefile.rules Message-ID: <200904151957.n3FJvhJY008330@zion.cs.uiuc.edu> Author: lattner Date: Wed Apr 15 14:57:42 2009 New Revision: 69206 URL: http://llvm.org/viewvc/llvm-project?rev=69206&view=rev Log: move clang-specific makefile goop to clang makefile. Modified: llvm/trunk/Makefile.rules Modified: llvm/trunk/Makefile.rules URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/Makefile.rules?rev=69206&r1=69205&r2=69206&view=diff ============================================================================== --- llvm/trunk/Makefile.rules (original) +++ llvm/trunk/Makefile.rules Wed Apr 15 14:57:42 2009 @@ -1363,10 +1363,6 @@ TABLEGEN_INC_FILES_COMMON = 1 endif -ifdef CLANG_BUILD_DIAGNOSTICS_INC -TABLEGEN_INC_FILES_COMMON = 1 -endif - ifdef TABLEGEN_INC_FILES_COMMON INCFiles := $(filter %.inc,$(BUILT_SOURCES)) @@ -1481,15 +1477,6 @@ endif # LLVMC_BUILD_AUTOGENERATED_INC -ifdef CLANG_BUILD_DIAGNOSTICS_INC - -$(ObjDir)/Diagnostic%Kinds.inc.tmp : Diagnostic.td Diagnostic%Kinds.td $(TBLGEN) - $(Echo) "Building Clang $(patsubst Diagnostic%Kinds.inc.tmp,%,$(@F)) diagnostic tables with tblgen" - $(Verb) $(MKDIR) $(@D) - $(Verb) $(TableGen) -gen-clang-diags-defs -clang-component=$(patsubst Diagnostic%Kinds.inc.tmp,%,$(@F)) -o $(call SYSPATH, $@) $< - -endif - ############################################################################### # OTHER RULES: Other rules needed ############################################################################### From sabre at nondot.org Wed Apr 15 15:02:32 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 15 Apr 2009 20:02:32 -0000 Subject: [llvm-commits] [llvm] r69208 - in /llvm/trunk/utils/TableGen: ClangDiagnosticsEmitter.cpp ClangDiagnosticsEmitter.h TableGen.cpp Message-ID: <200904152002.n3FK2Wad008490@zion.cs.uiuc.edu> Author: lattner Date: Wed Apr 15 15:02:32 2009 New Revision: 69208 URL: http://llvm.org/viewvc/llvm-project?rev=69208&view=rev Log: rename -gen-clang-diags-options -> -gen-clang-diag-groups Modified: llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.h llvm/trunk/utils/TableGen/TableGen.cpp Modified: llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp?rev=69208&r1=69207&r2=69208&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp Wed Apr 15 15:02:32 2009 @@ -165,7 +165,7 @@ } -void ClangOptionsEmitter::run(std::ostream &OS) { +void ClangDiagGroupsEmitter::run(std::ostream &OS) { // Build up a map from options to controlled diagnostics. OptionMap OM; Modified: llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.h?rev=69208&r1=69207&r2=69208&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.h (original) +++ llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.h Wed Apr 15 15:02:32 2009 @@ -32,10 +32,10 @@ void run(std::ostream &OS); }; -class ClangOptionsEmitter : public TableGenBackend { +class ClangDiagGroupsEmitter : public TableGenBackend { RecordKeeper &Records; public: - explicit ClangOptionsEmitter(RecordKeeper &R) : Records(R) {} + explicit ClangDiagGroupsEmitter(RecordKeeper &R) : Records(R) {} void run(std::ostream &OS); }; Modified: llvm/trunk/utils/TableGen/TableGen.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/TableGen.cpp?rev=69208&r1=69207&r2=69208&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/TableGen.cpp (original) +++ llvm/trunk/utils/TableGen/TableGen.cpp Wed Apr 15 15:02:32 2009 @@ -48,7 +48,7 @@ GenInstrEnums, GenInstrs, GenAsmWriter, GenCallingConv, GenClangDiagsDefs, - GenClangDiagsOptions, + GenClangDiagGroups, GenDAGISel, GenFastISel, GenSubtarget, @@ -91,8 +91,8 @@ "Generate target intrinsic information"), clEnumValN(GenClangDiagsDefs, "gen-clang-diags-defs", "Generate Clang diagnostics definitions"), - clEnumValN(GenClangDiagsOptions, "gen-clang-diags-options", - "Generate options for Clang diagnostics"), + clEnumValN(GenClangDiagGroups, "gen-clang-diag-groups", + "Generate Clang diagnostic groups"), clEnumValN(GenLLVMCConf, "gen-llvmc", "Generate LLVMC configuration library"), clEnumValN(PrintEnums, "print-enums", @@ -212,8 +212,8 @@ case GenClangDiagsDefs: ClangDiagsDefsEmitter(Records, ClangComponent).run(*Out); break; - case GenClangDiagsOptions: - ClangOptionsEmitter(Records).run(*Out); + case GenClangDiagGroups: + ClangDiagGroupsEmitter(Records).run(*Out); break; case GenDAGISel: DAGISelEmitter(Records).run(*Out); From gohman at apple.com Wed Apr 15 15:06:31 2009 From: gohman at apple.com (Dan Gohman) Date: Wed, 15 Apr 2009 20:06:31 -0000 Subject: [llvm-commits] [llvm] r69209 - in /llvm/trunk: include/llvm/CodeGen/DAGISelHeader.h include/llvm/CodeGen/SelectionDAG.h lib/CodeGen/SelectionDAG/LegalizeDAG.cpp lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200904152006.n3FK6XH4008647@zion.cs.uiuc.edu> Author: djg Date: Wed Apr 15 15:06:30 2009 New Revision: 69209 URL: http://llvm.org/viewvc/llvm-project?rev=69209&view=rev Log: Generalize one of the SelectionDAG::ReplaceAllUsesWith overloads to support replacing a node with another that has a superset of the result types. Use this instead of calling ReplaceAllUsesOfValueWith for each value. Modified: llvm/trunk/include/llvm/CodeGen/DAGISelHeader.h llvm/trunk/include/llvm/CodeGen/SelectionDAG.h llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Modified: llvm/trunk/include/llvm/CodeGen/DAGISelHeader.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/DAGISelHeader.h?rev=69209&r1=69208&r2=69209&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/DAGISelHeader.h (original) +++ llvm/trunk/include/llvm/CodeGen/DAGISelHeader.h Wed Apr 15 15:06:30 2009 @@ -80,15 +80,8 @@ /// ReplaceUses - replace all uses of the old node F with the use /// of the new node T. void ReplaceUses(SDNode *F, SDNode *T) DISABLE_INLINE { - unsigned FNumVals = F->getNumValues(); - unsigned TNumVals = T->getNumValues(); ISelUpdater ISU(ISelPosition); - if (FNumVals != TNumVals) { - for (unsigned i = 0, e = std::min(FNumVals, TNumVals); i < e; ++i) - CurDAG->ReplaceAllUsesOfValueWith(SDValue(F, i), SDValue(T, i), &ISU); - } else { - CurDAG->ReplaceAllUsesWith(F, T, &ISU); - } + CurDAG->ReplaceAllUsesWith(F, T, &ISU); } /// SelectRoot - Top level entry to DAG instruction selector. Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAG.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAG.h?rev=69209&r1=69208&r2=69209&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/SelectionDAG.h (original) +++ llvm/trunk/include/llvm/CodeGen/SelectionDAG.h Wed Apr 15 15:06:30 2009 @@ -693,7 +693,8 @@ /// ReplaceAllUsesWith - Modify anything using 'From' to use 'To' instead. /// This can cause recursive merging of nodes in the DAG. Use the first /// version if 'From' is known to have a single result, use the second - /// if you have two nodes with identical results, use the third otherwise. + /// if you have two nodes with identical results (or if 'To' has a superset + /// of the results of 'From'), use the third otherwise. /// /// These methods all take an optional UpdateListener, which (if not null) is /// informed about nodes that are deleted and modified due to recursive Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=69209&r1=69208&r2=69209&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Wed Apr 15 15:06:30 2009 @@ -4420,8 +4420,7 @@ DAG.getVTList(&ValueVTs[0], 2), &Ops[0], 2); SDNode *RNode = Result.getNode(); - DAG.ReplaceAllUsesOfValueWith(SDValue(Node, 0), SDValue(RNode, 0)); - DAG.ReplaceAllUsesOfValueWith(SDValue(Node, 1), SDValue(RNode, 1)); + DAG.ReplaceAllUsesWith(Node, RNode); break; } } @@ -4456,8 +4455,7 @@ DAG.getVTList(&ValueVTs[0], 2), &Ops[0], 2); SDNode *RNode = Result.getNode(); - DAG.ReplaceAllUsesOfValueWith(SDValue(Node, 0), SDValue(RNode, 0)); - DAG.ReplaceAllUsesOfValueWith(SDValue(Node, 1), SDValue(RNode, 1)); + DAG.ReplaceAllUsesWith(Node, RNode); break; } } Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=69209&r1=69208&r2=69209&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Wed Apr 15 15:06:30 2009 @@ -4500,14 +4500,17 @@ /// ReplaceAllUsesWith - Modify anything using 'From' to use 'To' instead. /// This can cause recursive merging of nodes in the DAG. /// -/// This version assumes From/To have matching types and numbers of result -/// values. +/// This version assumes that for each value of From, there is a +/// corresponding value in To in the same position with the same type. /// void SelectionDAG::ReplaceAllUsesWith(SDNode *From, SDNode *To, DAGUpdateListener *UpdateListener) { - assert(From->getVTList().VTs == To->getVTList().VTs && - From->getNumValues() == To->getNumValues() && - "Cannot use this version of ReplaceAllUsesWith!"); +#ifndef NDEBUG + for (unsigned i = 0, e = From->getNumValues(); i != e; ++i) + assert((!From->hasAnyUseOfValue(i) || + From->getValueType(i) == To->getValueType(i)) && + "Cannot use this version of ReplaceAllUsesWith!"); +#endif // Handle the trivial case. if (From == To) From dpatel at apple.com Wed Apr 15 15:11:09 2009 From: dpatel at apple.com (Devang Patel) Date: Wed, 15 Apr 2009 20:11:09 -0000 Subject: [llvm-commits] [llvm] r69210 - /llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp Message-ID: <200904152011.n3FKB9D5008811@zion.cs.uiuc.edu> Author: dpatel Date: Wed Apr 15 15:11:08 2009 New Revision: 69210 URL: http://llvm.org/viewvc/llvm-project?rev=69210&view=rev Log: Add DISubprogram is not null check. This fixes test/CodeGen//2009-01-21-invalid-debug-info.m test case. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp?rev=69210&r1=69209&r2=69210&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp Wed Apr 15 15:11:08 2009 @@ -357,11 +357,13 @@ if (DW && DW->ValidDebugInfo(REI->getContext(), true)) { unsigned ID = 0; DISubprogram Subprogram(cast(REI->getContext())); - if (!Subprogram.describes(MF.getFunction())) { + if (!Subprogram.isNull() && !Subprogram.describes(MF.getFunction())) { // This is end of an inlined function. const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL); ID = DW->RecordInlinedFnEnd(Subprogram); - BuildMI(MBB, DL, II).addImm(ID); + if (ID) + // If ID is 0 then this was not an end of inlined region. + BuildMI(MBB, DL, II).addImm(ID); } else { const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL); ID = DW->RecordRegionEnd(cast(REI->getContext())); From sabre at nondot.org Wed Apr 15 15:12:52 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 15 Apr 2009 20:12:52 -0000 Subject: [llvm-commits] [llvm] r69211 - /llvm/trunk/lib/Support/StringExtras.cpp Message-ID: <200904152012.n3FKCrK3008903@zion.cs.uiuc.edu> Author: lattner Date: Wed Apr 15 15:12:52 2009 New Revision: 69211 URL: http://llvm.org/viewvc/llvm-project?rev=69211&view=rev Log: teach EscapeString and UnescapeString to handle ". Modified: llvm/trunk/lib/Support/StringExtras.cpp Modified: llvm/trunk/lib/Support/StringExtras.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/StringExtras.cpp?rev=69211&r1=69210&r2=69211&view=diff ============================================================================== --- llvm/trunk/lib/Support/StringExtras.cpp (original) +++ llvm/trunk/lib/Support/StringExtras.cpp Wed Apr 15 15:12:52 2009 @@ -77,6 +77,7 @@ case 'r': Str[i] = '\r'; break; case 't': Str[i] = '\t'; break; case 'v': Str[i] = '\v'; break; + case '"': Str[i] = '\"'; break; case '\'': Str[i] = '\''; break; case '\\': Str[i] = '\\'; break; } @@ -96,6 +97,8 @@ } else if (Str[i] == '\t') { Str[i++] = '\\'; Str.insert(Str.begin()+i, 't'); + } else if (Str[i] == '"') { + Str.insert(Str.begin()+i++, '\\'); } else if (Str[i] == '\n') { Str[i++] = '\\'; Str.insert(Str.begin()+i, 'n'); From sabre at nondot.org Wed Apr 15 15:13:19 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 15 Apr 2009 20:13:19 -0000 Subject: [llvm-commits] [llvm] r69212 - /llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp Message-ID: <200904152013.n3FKDJvL008930@zion.cs.uiuc.edu> Author: lattner Date: Wed Apr 15 15:13:18 2009 New Revision: 69212 URL: http://llvm.org/viewvc/llvm-project?rev=69212&view=rev Log: use escape string. Modified: llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp Modified: llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp?rev=69212&r1=69211&r2=69212&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp Wed Apr 15 15:13:18 2009 @@ -16,8 +16,9 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Streams.h" -#include "llvm/ADT/VectorExtras.h" #include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/VectorExtras.h" #include #include using namespace llvm; @@ -39,15 +40,6 @@ return 0; } -static void EmitEscaped(std::ostream& OS, const std::string &s) { - for (std::string::const_iterator I=s.begin(), E=s.end(); I!=E; ++I) - switch (*I) { - default: OS << *I; break; - case '\"': OS << "\\" << *I; break; - case '\\': OS << "\\\\"; break; - } -} - static void EmitAllCaps(std::ostream& OS, const std::string &s) { for (std::string::const_iterator I=s.begin(), E=s.end(); I!=E; ++I) OS << char(toupper(*I)); @@ -63,8 +55,9 @@ OS << R.getValueAsDef("Class")->getName(); OS << ", diag::" << R.getValueAsDef("DefaultMapping")->getName(); OS << ", \""; - EmitEscaped(OS, R.getValueAsString("Text")); - OS << "\")\n"; + std::string S = R.getValueAsString("Text"); + EscapeString(S); + OS << S << "\")\n"; } void ClangDiagsDefsEmitter::run(std::ostream &OS) { @@ -168,7 +161,7 @@ void ClangDiagGroupsEmitter::run(std::ostream &OS) { // Build up a map from options to controlled diagnostics. OptionMap OM; - + const RecordVector &Opts = Records.getAllDerivedDefinitions("Option"); for (RecordVector::const_iterator I=Opts.begin(), E=Opts.end(); I != E; ++I) if (const RecordVal* V = findRecordVal(**I, "Members")) From sabre at nondot.org Wed Apr 15 15:16:13 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 15 Apr 2009 20:16:13 -0000 Subject: [llvm-commits] [llvm] r69213 - /llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp Message-ID: <200904152016.n3FKGEcT009014@zion.cs.uiuc.edu> Author: lattner Date: Wed Apr 15 15:16:12 2009 New Revision: 69213 URL: http://llvm.org/viewvc/llvm-project?rev=69213&view=rev Log: use UppercaseString instead of EmitAllCaps Modified: llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp Modified: llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp?rev=69213&r1=69212&r2=69213&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp Wed Apr 15 15:16:12 2009 @@ -28,10 +28,9 @@ //===----------------------------------------------------------------------===// typedef std::vector RecordVector; -typedef std::vector SuperClassVector; -typedef std::vector RecordValVector; static const RecordVal* findRecordVal(const Record& R, const std::string &key) { + typedef std::vector RecordValVector; const RecordValVector &Vals = R.getValues(); for (RecordValVector::const_iterator I=Vals.begin(), E=Vals.end(); I!=E; ++I) if ((*I).getName() == key) @@ -40,11 +39,6 @@ return 0; } -static void EmitAllCaps(std::ostream& OS, const std::string &s) { - for (std::string::const_iterator I=s.begin(), E=s.end(); I!=E; ++I) - OS << char(toupper(*I)); -} - //===----------------------------------------------------------------------===// // Warning Tables (.inc file) generation. //===----------------------------------------------------------------------===// @@ -68,15 +62,12 @@ // Write the #if guard if (!Component.empty()) { - OS << "#ifdef "; - EmitAllCaps(OS, Component); - OS << "START\n__"; - EmitAllCaps(OS, Component); - OS << "START = DIAG_START_"; - EmitAllCaps(OS, Component); - OS << ",\n#undef "; - EmitAllCaps(OS, Component); - OS << "START\n#endif\n"; + std::string ComponentName = UppercaseString(Component); + OS << "#ifdef " << ComponentName << "START\n"; + OS << "__" << ComponentName << "START = DIAG_START_" << ComponentName + << ",\n"; + OS << "#undef " << ComponentName << "START\n"; + OS << "#endif\n"; } for (RecordVector::const_iterator I=Diags.begin(), E=Diags.end(); I!=E; ++I) { From dalej at apple.com Wed Apr 15 15:41:03 2009 From: dalej at apple.com (Dale Johannesen) Date: Wed, 15 Apr 2009 20:41:03 -0000 Subject: [llvm-commits] [llvm] r69215 - /llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp Message-ID: <200904152041.n3FKf3QQ009813@zion.cs.uiuc.edu> Author: johannes Date: Wed Apr 15 15:41:02 2009 New Revision: 69215 URL: http://llvm.org/viewvc/llvm-project?rev=69215&view=rev Log: Eliminate zext over (iv & const) or ((iv+const)&const) if a longer iv is available. These subscript forms are not common; they're a bottleneck in OpenSSL. 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=69215&r1=69214&r2=69215&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp Wed Apr 15 15:41:02 2009 @@ -798,48 +798,106 @@ if (PN == OrigControllingPHI && PN->getType() != LargestType) for (Value::use_iterator UI = PN->use_begin(), UE = PN->use_end(); UI != UE; ++UI) { - if (isa(UI) && NoSignedWrap) { + Instruction *UInst = dyn_cast(*UI); + if (UInst && isa(UInst) && NoSignedWrap) { Value *TruncIndVar = getSignExtendedTruncVar(AR, SE, LargestType, L, - UI->getType(), Rewriter, InsertPt); - UI->replaceAllUsesWith(TruncIndVar); - if (Instruction *DeadUse = dyn_cast(*UI)) - DeadInsts.insert(DeadUse); + UInst->getType(), Rewriter, InsertPt); + UInst->replaceAllUsesWith(TruncIndVar); + DeadInsts.insert(UInst); } // See if we can figure out sext(i+constant) doesn't wrap, so we can // use a larger add. This is common in subscripting. - Instruction *UInst = dyn_cast(*UI); if (UInst && UInst->getOpcode()==Instruction::Add && UInst->hasOneUse() && isa(UInst->getOperand(1)) && - isa(UInst->use_begin()) && NoSignedWrap && LimitVal) { - uint64_t numBits = LimitVal->getValue().getBitWidth(); - ConstantInt* RHS = dyn_cast(UInst->getOperand(1)); - if (((APInt::getSignedMaxValue(numBits) - IncrVal->getValue()) - - RHS->getValue()).sgt(LimitVal->getValue())) { - SExtInst* oldSext = dyn_cast(UInst->use_begin()); - Value *TruncIndVar = getSignExtendedTruncVar(AR, SE, LargestType, L, - oldSext->getType(), Rewriter, - InsertPt); - APInt APcopy = APInt(RHS->getValue()); - ConstantInt* newRHS = - ConstantInt::get(APcopy.sext(oldSext->getType()-> - getPrimitiveSizeInBits())); - Value *NewAdd = BinaryOperator::CreateAdd(TruncIndVar, newRHS, - UInst->getName()+".nosex", - UInst); - oldSext->replaceAllUsesWith(NewAdd); - if (Instruction *DeadUse = dyn_cast(oldSext)) - DeadInsts.insert(DeadUse); - if (Instruction *DeadUse = dyn_cast(UInst)) - DeadInsts.insert(DeadUse); + NoSignedWrap && LimitVal) { + uint64_t oldBitSize = LimitVal->getValue().getBitWidth(); + uint64_t newBitSize = LargestType->getPrimitiveSizeInBits(); + ConstantInt* AddRHS = dyn_cast(UInst->getOperand(1)); + if (((APInt::getSignedMaxValue(oldBitSize) - IncrVal->getValue()) - + AddRHS->getValue()).sgt(LimitVal->getValue())) { + // We've determined this is (i+constant) and it won't overflow. + if (isa(UInst->use_begin())) { + SExtInst* oldSext = dyn_cast(UInst->use_begin()); + Value *TruncIndVar = getSignExtendedTruncVar(AR, SE, LargestType, + L, oldSext->getType(), Rewriter, + InsertPt); + APInt APcopy = APInt(AddRHS->getValue()); + ConstantInt* newAddRHS =ConstantInt::get(APcopy.sext(newBitSize)); + Value *NewAdd = + BinaryOperator::CreateAdd(TruncIndVar, newAddRHS, + UInst->getName()+".nosex", UInst); + oldSext->replaceAllUsesWith(NewAdd); + if (Instruction *DeadUse = dyn_cast(oldSext)) + DeadInsts.insert(DeadUse); + DeadInsts.insert(UInst); + } } } - if (isa(UI) && NoUnsignedWrap) { + if (UInst && isa(UInst) && NoUnsignedWrap) { Value *TruncIndVar = getZeroExtendedTruncVar(AR, SE, LargestType, L, - UI->getType(), Rewriter, InsertPt); - UI->replaceAllUsesWith(TruncIndVar); - if (Instruction *DeadUse = dyn_cast(*UI)) + UInst->getType(), Rewriter, InsertPt); + UInst->replaceAllUsesWith(TruncIndVar); + DeadInsts.insert(UInst); + } + // If we have zext(i&constant), we can use the larger variable. This + // is not common but is a bottleneck in Openssl. + // (RHS doesn't have to be constant. There should be a better approach + // than bottom-up pattern matching for this...) + if (UInst && UInst->getOpcode()==Instruction::And && + UInst->hasOneUse() && + isa(UInst->getOperand(1)) && + isa(UInst->use_begin())) { + uint64_t newBitSize = LargestType->getPrimitiveSizeInBits(); + ConstantInt* AndRHS = dyn_cast(UInst->getOperand(1)); + ZExtInst* oldZext = dyn_cast(UInst->use_begin()); + Value *TruncIndVar = getSignExtendedTruncVar(AR, SE, LargestType, + L, oldZext->getType(), Rewriter, InsertPt); + APInt APcopy = APInt(AndRHS->getValue()); + ConstantInt* newAndRHS = ConstantInt::get(APcopy.zext(newBitSize)); + Value *NewAnd = + BinaryOperator::CreateAnd(TruncIndVar, newAndRHS, + UInst->getName()+".nozex", UInst); + oldZext->replaceAllUsesWith(NewAnd); + if (Instruction *DeadUse = dyn_cast(oldZext)) DeadInsts.insert(DeadUse); + DeadInsts.insert(UInst); + } + // If we have zext((i+constant)&constant), we can use the larger + // variable even if the add does overflow. This works whenever the + // constant being ANDed is the same size as i, which it presumably is. + // We don't need to restrict the expression being and'ed to i+const, + // but we have to promote everything in it, so it's convenient. + if (UInst && UInst->getOpcode()==Instruction::Add && + UInst->hasOneUse() && + isa(UInst->getOperand(1))) { + uint64_t newBitSize = LargestType->getPrimitiveSizeInBits(); + ConstantInt* AddRHS = dyn_cast(UInst->getOperand(1)); + Instruction *UInst2 = dyn_cast(UInst->use_begin()); + if (UInst2 && UInst2->getOpcode() == Instruction::And && + UInst2->hasOneUse() && + isa(UInst2->getOperand(1)) && + isa(UInst2->use_begin())) { + ZExtInst* oldZext = dyn_cast(UInst2->use_begin()); + Value *TruncIndVar = getSignExtendedTruncVar(AR, SE, LargestType, + L, oldZext->getType(), Rewriter, InsertPt); + ConstantInt* AndRHS = dyn_cast(UInst2->getOperand(1)); + APInt APcopy = APInt(AddRHS->getValue()); + ConstantInt* newAddRHS = ConstantInt::get(APcopy.zext(newBitSize)); + Value *NewAdd = + BinaryOperator::CreateAdd(TruncIndVar, newAddRHS, + UInst->getName()+".nozex", UInst2); + APInt APcopy2 = APInt(AndRHS->getValue()); + ConstantInt* newAndRHS = ConstantInt::get(APcopy2.zext(newBitSize)); + Value *NewAnd = + BinaryOperator::CreateAnd(NewAdd, newAndRHS, + UInst->getName()+".nozex", UInst2); + oldZext->replaceAllUsesWith(NewAnd); + if (Instruction *DeadUse = dyn_cast(oldZext)) + DeadInsts.insert(DeadUse); + DeadInsts.insert(UInst); + DeadInsts.insert(UInst2); + } } } From dpatel at apple.com Wed Apr 15 15:41:32 2009 From: dpatel at apple.com (Devang Patel) Date: Wed, 15 Apr 2009 20:41:32 -0000 Subject: [llvm-commits] [llvm] r69216 - /llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp Message-ID: <200904152041.n3FKfX5I009837@zion.cs.uiuc.edu> Author: dpatel Date: Wed Apr 15 15:41:31 2009 New Revision: 69216 URL: http://llvm.org/viewvc/llvm-project?rev=69216&view=rev Log: s/RootDbgScope/FunctionDbgScope/g Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp?rev=69216&r1=69215&r2=69216&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp Wed Apr 15 15:41:31 2009 @@ -1271,9 +1271,9 @@ /// bool shouldEmit; - // RootDbgScope - Top level scope for the current function. + // FunctionDbgScope - Top level scope for the current function. // - DbgScope *RootDbgScope; + DbgScope *FunctionDbgScope; /// DbgScopeMap - Tracks the scopes in the current function. DenseMap DbgScopeMap; @@ -2037,7 +2037,7 @@ Parent->AddScope(Slot); else // First function is top level function. - RootDbgScope = Slot; + FunctionDbgScope = Slot; return Slot; } @@ -2052,8 +2052,8 @@ // FIXME - Add inlined function scopes to the root so we can delete them // later. - assert (RootDbgScope && "Function scope info missing!"); - RootDbgScope->AddScope(Scope); + assert (FunctionDbgScope && "Function scope info missing!"); + FunctionDbgScope->AddScope(Scope); return Scope; } @@ -2126,9 +2126,9 @@ } } - /// ConstructRootDbgScope - Construct the scope for the subprogram. + /// ConstructFunctionDbgScope - Construct the scope for the subprogram. /// - void ConstructRootDbgScope(DbgScope *RootScope) { + void ConstructFunctionDbgScope(DbgScope *RootScope) { // Exit if there is no root scope. if (!RootScope) return; DIDescriptor Desc = RootScope->getDesc(); @@ -3120,7 +3120,7 @@ AbbreviationsSet(InitAbbreviationsSetSize), Abbreviations(), ValuesSet(InitValuesSetSize), Values(), StringPool(), SectionMap(), SectionSourceLines(), didInitial(false), shouldEmit(false), - RootDbgScope(0), DebugTimer(0) { + FunctionDbgScope(0), DebugTimer(0) { if (TimePassesIsEnabled) DebugTimer = new Timer("Dwarf Debug Writer", getDwarfTimerGroup()); @@ -3319,8 +3319,8 @@ } // Construct scopes for subprogram. - if (RootDbgScope) - ConstructRootDbgScope(RootDbgScope); + if (FunctionDbgScope) + ConstructFunctionDbgScope(FunctionDbgScope); else // FIXME: This is wrong. We are essentially getting past a problem with // debug information not being able to handle unreachable blocks that have @@ -3336,12 +3336,12 @@ MMI->getFrameMoves())); // Clear debug info - if (RootDbgScope) { - delete RootDbgScope; + if (FunctionDbgScope) { + delete FunctionDbgScope; DbgScopeMap.clear(); DbgInlinedScopeMap.clear(); InlinedVariableScopes.clear(); - RootDbgScope = NULL; + FunctionDbgScope = NULL; } Lines.clear(); From sabre at nondot.org Wed Apr 15 15:55:09 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 15 Apr 2009 20:55:09 -0000 Subject: [llvm-commits] [llvm] r69219 - /llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp Message-ID: <200904152055.n3FKt9NC010324@zion.cs.uiuc.edu> Author: lattner Date: Wed Apr 15 15:55:08 2009 New Revision: 69219 URL: http://llvm.org/viewvc/llvm-project?rev=69219&view=rev Log: implement support for writing out diagnostic group tables. Modified: llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp Modified: llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp?rev=69219&r1=69218&r2=69219&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp Wed Apr 15 15:55:08 2009 @@ -24,42 +24,10 @@ using namespace llvm; //===----------------------------------------------------------------------===// -// Generic routines for all Clang TableGen backends. -//===----------------------------------------------------------------------===// - -typedef std::vector RecordVector; - -static const RecordVal* findRecordVal(const Record& R, const std::string &key) { - typedef std::vector RecordValVector; - const RecordValVector &Vals = R.getValues(); - for (RecordValVector::const_iterator I=Vals.begin(), E=Vals.end(); I!=E; ++I) - if ((*I).getName() == key) - return &*I; - - return 0; -} - -//===----------------------------------------------------------------------===// // Warning Tables (.inc file) generation. //===----------------------------------------------------------------------===// -static void ProcessDiag(std::ostream &OS, const Record *DiagClass, - const Record &R) { - OS << "DIAG(" << R.getName() << ", "; - OS << R.getValueAsDef("Class")->getName(); - OS << ", diag::" << R.getValueAsDef("DefaultMapping")->getName(); - OS << ", \""; - std::string S = R.getValueAsString("Text"); - EscapeString(S); - OS << S << "\")\n"; -} - void ClangDiagsDefsEmitter::run(std::ostream &OS) { - const RecordVector &Diags = Records.getAllDerivedDefinitions("Diagnostic"); - - const Record* DiagClass = Records.getClass("Diagnostic"); - assert(DiagClass && "No Diagnostic class defined."); - // Write the #if guard if (!Component.empty()) { std::string ComponentName = UppercaseString(Component); @@ -69,127 +37,73 @@ OS << "#undef " << ComponentName << "START\n"; OS << "#endif\n"; } + + const std::vector &Diags = + Records.getAllDerivedDefinitions("Diagnostic"); - for (RecordVector::const_iterator I=Diags.begin(), E=Diags.end(); I!=E; ++I) { - const Record &R = **I; + for (unsigned i = 0, e = Diags.size(); i != e; ++i) { + const Record &R = *Diags[i]; // Filter by component. if (!Component.empty() && Component != R.getValueAsString("Component")) continue; - ProcessDiag(OS, DiagClass, R); + OS << "DIAG(" << R.getName() << ", "; + OS << R.getValueAsDef("Class")->getName(); + OS << ", diag::" << R.getValueAsDef("DefaultMapping")->getName(); + OS << ", \""; + std::string S = R.getValueAsString("Text"); + EscapeString(S); + OS << S << "\")\n"; } } //===----------------------------------------------------------------------===// -// Warning Group Tables generation. +// Warning Group Tables generation //===----------------------------------------------------------------------===// -static const std::string &getOptName(const Record *R) { - const RecordVal *V = findRecordVal(*R, "Name"); - assert(V && "Options must have a 'Name' value."); - const StringInit* SV = dynamic_cast(V->getValue()); - assert(SV && "'Name' entry must be a string."); - return SV->getValue(); -} - -namespace { -struct VISIBILITY_HIDDEN CompareOptName { - bool operator()(const Record* A, const Record* B) const { - return getOptName(A) < getOptName(B); - } -}; -} - -typedef std::set DiagnosticSet; -typedef std::map OptionMap; -typedef llvm::DenseSet VisitedLists; - -static void BuildGroup(DiagnosticSet& DS, VisitedLists &Visited, const Init* X); - -static void BuildGroup(DiagnosticSet &DS, VisitedLists &Visited, - const ListInit* LV) { - - // Simple hack to prevent including a list multiple times. This may be useful - // if one declares an Option by including a bunch of other Options that - // include other Options, etc. - if (Visited.count(LV)) - return; - - Visited.insert(LV); - - // Iterate through the list and grab all DiagnosticControlled. - for (ListInit::const_iterator I = LV->begin(), E = LV->end(); I!=E; ++I) - BuildGroup(DS, Visited, *I); -} - -static void BuildGroup(DiagnosticSet& DS, VisitedLists &Visited, - const Record *Def) { - - // If an Option includes another Option, inline the Diagnostics of the - // included Option. - if (Def->isSubClassOf("Option")) { - if (const RecordVal *V = findRecordVal(*Def, "Members")) - if (const ListInit *LV = dynamic_cast(V->getValue())) - BuildGroup(DS, Visited, LV); - - return; - } - - if (Def->isSubClassOf("DiagnosticControlled")) - DS.insert(Def); -} - -static void BuildGroup(DiagnosticSet& DS, VisitedLists &Visited, - const Init* X) { - - if (const DefInit *D = dynamic_cast(X)) - BuildGroup(DS, Visited, D->getDef()); - - // We may have some other cases here in the future. -} - - void ClangDiagGroupsEmitter::run(std::ostream &OS) { - // Build up a map from options to controlled diagnostics. - OptionMap OM; - - const RecordVector &Opts = Records.getAllDerivedDefinitions("Option"); - for (RecordVector::const_iterator I=Opts.begin(), E=Opts.end(); I != E; ++I) - if (const RecordVal* V = findRecordVal(**I, "Members")) - if (const ListInit* LV = dynamic_cast(V->getValue())) { - VisitedLists Visited; - BuildGroup(OM[*I], Visited, LV); - } - - // Iterate through the OptionMap and emit the declarations. - for (OptionMap::iterator I = OM.begin(), E = OM.end(); I!=E; ++I) { - // Output the option. - OS << "static const diag::kind " << I->first->getName() << "[] = { "; - - DiagnosticSet &DS = I->second; - bool first = true; - for (DiagnosticSet::iterator I2 = DS.begin(), E2 = DS.end(); I2!=E2; ++I2) { - if (first) - first = false; - else - OS << ", "; - - OS << "diag::" << (*I2)->getName(); - } - OS << " };\n"; - } - - // Now emit the OptionTable table. - OS << "\nstatic const WarningOption OptionTable[] = {"; - bool first = true; - for (OptionMap::iterator I = OM.begin(), E = OM.end(); I!=E; ++I) { - if (first) - first = false; - else - OS << ','; + // Invert the 1-[0/1] mapping of diags to group into a one to many mapping of + // groups to diags in the group. + std::map > DiagsInGroup; + + const std::vector &Diags = + Records.getAllDerivedDefinitions("Diagnostic"); + + for (unsigned i = 0, e = Diags.size(); i != e; ++i) { + const Record *R = Diags[i]; + DefInit *DI = dynamic_cast(R->getValueInit("Group")); + if (DI == 0) continue; + DiagsInGroup[DI->getDef()->getValueAsString("GroupName")].push_back(R); + } + + // Walk through the groups emitting an array for each diagnostic of the diags + // that are mapped to. + OS << "\n#ifdef GET_DIAG_ARRAYS\n"; + unsigned IDNo = 0; + unsigned MaxLen = 0; + for (std::map >::iterator + I = DiagsInGroup.begin(), E = DiagsInGroup.end(); I != E; ++I) { + MaxLen = std::max(MaxLen, (unsigned)I->first.size()); - OS << "\n {\"" << getOptName(I->first) - << "\", DIAGS(" << I->first->getName() << ")}"; + OS << "static const short DiagArray" << IDNo++ + << "[] = { "; + std::vector &V = I->second; + for (unsigned i = 0, e = V.size(); i != e; ++i) + OS << "diag::" << V[i]->getName() << ", "; + OS << "-1 };\n"; + } + OS << "#endif // GET_DIAG_ARRAYS\n\n"; + + // Emit the table now. + OS << "\n#ifdef GET_DIAG_TABLE\n"; + IDNo = 0; + for (std::map >::iterator + I = DiagsInGroup.begin(), E = DiagsInGroup.end(); I != E; ++I) { + std::string S = I->first; + EscapeString(S); + OS << " { \"" << S << "\"," + << std::string(MaxLen-I->first.size()+1, ' ') + << "DiagArray" << IDNo++ << " },\n"; } - OS << "\n};\n"; + OS << "#endif // GET_DIAG_TABLE\n\n"; } From clattner at apple.com Wed Apr 15 16:01:39 2009 From: clattner at apple.com (Chris Lattner) Date: Wed, 15 Apr 2009 14:01:39 -0700 Subject: [llvm-commits] [llvm] r69215 - /llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp In-Reply-To: <200904152041.n3FKf3QQ009813@zion.cs.uiuc.edu> References: <200904152041.n3FKf3QQ009813@zion.cs.uiuc.edu> Message-ID: On Apr 15, 2009, at 1:41 PM, Dale Johannesen wrote: > Author: johannes > Date: Wed Apr 15 15:41:02 2009 > New Revision: 69215 > > URL: http://llvm.org/viewvc/llvm-project?rev=69215&view=rev > Log: > Eliminate zext over (iv & const) or ((iv+const)&const) > if a longer iv is available. These subscript forms are > not common; they're a bottleneck in OpenSSL. Testcase? :) -Chris > > > > 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=69215&r1=69214&r2=69215&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp (original) > +++ llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp Wed Apr 15 > 15:41:02 2009 > @@ -798,48 +798,106 @@ > if (PN == OrigControllingPHI && PN->getType() != LargestType) > for (Value::use_iterator UI = PN->use_begin(), UE = PN- > >use_end(); > UI != UE; ++UI) { > - if (isa(UI) && NoSignedWrap) { > + Instruction *UInst = dyn_cast(*UI); > + if (UInst && isa(UInst) && NoSignedWrap) { > Value *TruncIndVar = getSignExtendedTruncVar(AR, SE, > LargestType, L, > - UI->getType(), > Rewriter, InsertPt); > - UI->replaceAllUsesWith(TruncIndVar); > - if (Instruction *DeadUse = dyn_cast(*UI)) > - DeadInsts.insert(DeadUse); > + UInst->getType(), > Rewriter, InsertPt); > + UInst->replaceAllUsesWith(TruncIndVar); > + DeadInsts.insert(UInst); > } > // See if we can figure out sext(i+constant) doesn't wrap, > so we can > // use a larger add. This is common in subscripting. > - Instruction *UInst = dyn_cast(*UI); > if (UInst && UInst->getOpcode()==Instruction::Add && > UInst->hasOneUse() && > isa(UInst->getOperand(1)) && > - isa(UInst->use_begin()) && NoSignedWrap && > LimitVal) { > - uint64_t numBits = LimitVal->getValue().getBitWidth(); > - ConstantInt* RHS = dyn_cast(UInst- > >getOperand(1)); > - if (((APInt::getSignedMaxValue(numBits) - IncrVal- > >getValue()) - > - RHS->getValue()).sgt(LimitVal->getValue())) { > - SExtInst* oldSext = dyn_cast(UInst- > >use_begin()); > - Value *TruncIndVar = getSignExtendedTruncVar(AR, SE, > LargestType, L, > - oldSext->getType(), > Rewriter, > - InsertPt); > - APInt APcopy = APInt(RHS->getValue()); > - ConstantInt* newRHS = > - ConstantInt::get(APcopy.sext(oldSext->getType()-> > - > getPrimitiveSizeInBits())); > - Value *NewAdd = BinaryOperator::CreateAdd(TruncIndVar, > newRHS, > - UInst- > >getName()+".nosex", > - UInst); > - oldSext->replaceAllUsesWith(NewAdd); > - if (Instruction *DeadUse = > dyn_cast(oldSext)) > - DeadInsts.insert(DeadUse); > - if (Instruction *DeadUse = dyn_cast(UInst)) > - DeadInsts.insert(DeadUse); > + NoSignedWrap && LimitVal) { > + uint64_t oldBitSize = LimitVal->getValue().getBitWidth(); > + uint64_t newBitSize = LargestType- > >getPrimitiveSizeInBits(); > + ConstantInt* AddRHS = dyn_cast(UInst- > >getOperand(1)); > + if (((APInt::getSignedMaxValue(oldBitSize) - IncrVal- > >getValue()) - > + AddRHS->getValue()).sgt(LimitVal->getValue())) { > + // We've determined this is (i+constant) and it won't > overflow. > + if (isa(UInst->use_begin())) { > + SExtInst* oldSext = dyn_cast(UInst- > >use_begin()); > + Value *TruncIndVar = getSignExtendedTruncVar(AR, SE, > LargestType, > + L, oldSext- > >getType(), Rewriter, > + InsertPt); > + APInt APcopy = APInt(AddRHS->getValue()); > + ConstantInt* newAddRHS > =ConstantInt::get(APcopy.sext(newBitSize)); > + Value *NewAdd = > + BinaryOperator::CreateAdd(TruncIndVar, newAddRHS, > + UInst->getName() > +".nosex", UInst); > + oldSext->replaceAllUsesWith(NewAdd); > + if (Instruction *DeadUse = > dyn_cast(oldSext)) > + DeadInsts.insert(DeadUse); > + DeadInsts.insert(UInst); > + } > } > } > - if (isa(UI) && NoUnsignedWrap) { > + if (UInst && isa(UInst) && NoUnsignedWrap) { > Value *TruncIndVar = getZeroExtendedTruncVar(AR, SE, > LargestType, L, > - UI->getType(), > Rewriter, InsertPt); > - UI->replaceAllUsesWith(TruncIndVar); > - if (Instruction *DeadUse = dyn_cast(*UI)) > + UInst->getType(), > Rewriter, InsertPt); > + UInst->replaceAllUsesWith(TruncIndVar); > + DeadInsts.insert(UInst); > + } > + // If we have zext(i&constant), we can use the larger > variable. This > + // is not common but is a bottleneck in Openssl. > + // (RHS doesn't have to be constant. There should be a > better approach > + // than bottom-up pattern matching for this...) > + if (UInst && UInst->getOpcode()==Instruction::And && > + UInst->hasOneUse() && > + isa(UInst->getOperand(1)) && > + isa(UInst->use_begin())) { > + uint64_t newBitSize = LargestType- > >getPrimitiveSizeInBits(); > + ConstantInt* AndRHS = dyn_cast(UInst- > >getOperand(1)); > + ZExtInst* oldZext = dyn_cast(UInst->use_begin()); > + Value *TruncIndVar = getSignExtendedTruncVar(AR, SE, > LargestType, > + L, oldZext->getType(), Rewriter, > InsertPt); > + APInt APcopy = APInt(AndRHS->getValue()); > + ConstantInt* newAndRHS = > ConstantInt::get(APcopy.zext(newBitSize)); > + Value *NewAnd = > + BinaryOperator::CreateAnd(TruncIndVar, newAndRHS, > + UInst->getName() > +".nozex", UInst); > + oldZext->replaceAllUsesWith(NewAnd); > + if (Instruction *DeadUse = dyn_cast(oldZext)) > DeadInsts.insert(DeadUse); > + DeadInsts.insert(UInst); > + } > + // If we have zext((i+constant)&constant), we can use the > larger > + // variable even if the add does overflow. This works > whenever the > + // constant being ANDed is the same size as i, which it > presumably is. > + // We don't need to restrict the expression being and'ed to > i+const, > + // but we have to promote everything in it, so it's > convenient. > + if (UInst && UInst->getOpcode()==Instruction::Add && > + UInst->hasOneUse() && > + isa(UInst->getOperand(1))) { > + uint64_t newBitSize = LargestType- > >getPrimitiveSizeInBits(); > + ConstantInt* AddRHS = dyn_cast(UInst- > >getOperand(1)); > + Instruction *UInst2 = dyn_cast(UInst- > >use_begin()); > + if (UInst2 && UInst2->getOpcode() == Instruction::And && > + UInst2->hasOneUse() && > + isa(UInst2->getOperand(1)) && > + isa(UInst2->use_begin())) { > + ZExtInst* oldZext = dyn_cast(UInst2- > >use_begin()); > + Value *TruncIndVar = getSignExtendedTruncVar(AR, SE, > LargestType, > + L, oldZext->getType(), > Rewriter, InsertPt); > + ConstantInt* AndRHS = dyn_cast(UInst2- > >getOperand(1)); > + APInt APcopy = APInt(AddRHS->getValue()); > + ConstantInt* newAddRHS = > ConstantInt::get(APcopy.zext(newBitSize)); > + Value *NewAdd = > + BinaryOperator::CreateAdd(TruncIndVar, newAddRHS, > + UInst->getName() > +".nozex", UInst2); > + APInt APcopy2 = APInt(AndRHS->getValue()); > + ConstantInt* newAndRHS = > ConstantInt::get(APcopy2.zext(newBitSize)); > + Value *NewAnd = > + BinaryOperator::CreateAnd(NewAdd, newAndRHS, > + UInst->getName() > +".nozex", UInst2); > + oldZext->replaceAllUsesWith(NewAnd); > + if (Instruction *DeadUse = > dyn_cast(oldZext)) > + DeadInsts.insert(DeadUse); > + DeadInsts.insert(UInst); > + DeadInsts.insert(UInst2); > + } > } > } > > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From dalej at apple.com Wed Apr 15 16:03:12 2009 From: dalej at apple.com (Dale Johannesen) Date: Wed, 15 Apr 2009 14:03:12 -0700 Subject: [llvm-commits] [llvm] r69215 - /llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp In-Reply-To: References: <200904152041.n3FKf3QQ009813@zion.cs.uiuc.edu> Message-ID: <8EEE1604-10D8-426A-9ECB-926A5E4679CE@apple.com> On Apr 15, 2009, at 2:01 PMPDT, Chris Lattner wrote: > > On Apr 15, 2009, at 1:41 PM, Dale Johannesen wrote: > >> Author: johannes >> Date: Wed Apr 15 15:41:02 2009 >> New Revision: 69215 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=69215&view=rev >> Log: >> Eliminate zext over (iv & const) or ((iv+const)&const) >> if a longer iv is available. These subscript forms are >> not common; they're a bottleneck in OpenSSL. > > Testcase? :) Coming. Apparently I'm in a hurry, although I didn't find that out until lunch. > > -Chris > >> >> >> >> 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=69215&r1=69214&r2=69215&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp (original) >> +++ llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp Wed Apr 15 >> 15:41:02 2009 >> @@ -798,48 +798,106 @@ >> if (PN == OrigControllingPHI && PN->getType() != LargestType) >> for (Value::use_iterator UI = PN->use_begin(), UE = PN- >>> use_end(); >> UI != UE; ++UI) { >> - if (isa(UI) && NoSignedWrap) { >> + Instruction *UInst = dyn_cast(*UI); >> + if (UInst && isa(UInst) && NoSignedWrap) { >> Value *TruncIndVar = getSignExtendedTruncVar(AR, SE, >> LargestType, L, >> - UI->getType(), >> Rewriter, InsertPt); >> - UI->replaceAllUsesWith(TruncIndVar); >> - if (Instruction *DeadUse = dyn_cast(*UI)) >> - DeadInsts.insert(DeadUse); >> + UInst->getType(), >> Rewriter, InsertPt); >> + UInst->replaceAllUsesWith(TruncIndVar); >> + DeadInsts.insert(UInst); >> } >> // See if we can figure out sext(i+constant) doesn't wrap, >> so we can >> // use a larger add. This is common in subscripting. >> - Instruction *UInst = dyn_cast(*UI); >> if (UInst && UInst->getOpcode()==Instruction::Add && >> UInst->hasOneUse() && >> isa(UInst->getOperand(1)) && >> - isa(UInst->use_begin()) && NoSignedWrap && >> LimitVal) { >> - uint64_t numBits = LimitVal->getValue().getBitWidth(); >> - ConstantInt* RHS = dyn_cast(UInst- >>> getOperand(1)); >> - if (((APInt::getSignedMaxValue(numBits) - IncrVal- >>> getValue()) - >> - RHS->getValue()).sgt(LimitVal->getValue())) { >> - SExtInst* oldSext = dyn_cast(UInst- >>> use_begin()); >> - Value *TruncIndVar = getSignExtendedTruncVar(AR, SE, >> LargestType, L, >> - oldSext->getType(), >> Rewriter, >> - InsertPt); >> - APInt APcopy = APInt(RHS->getValue()); >> - ConstantInt* newRHS = >> - ConstantInt::get(APcopy.sext(oldSext->getType()-> >> - >> getPrimitiveSizeInBits())); >> - Value *NewAdd = BinaryOperator::CreateAdd(TruncIndVar, >> newRHS, >> - UInst- >>> getName()+".nosex", >> - UInst); >> - oldSext->replaceAllUsesWith(NewAdd); >> - if (Instruction *DeadUse = >> dyn_cast(oldSext)) >> - DeadInsts.insert(DeadUse); >> - if (Instruction *DeadUse = dyn_cast(UInst)) >> - DeadInsts.insert(DeadUse); >> + NoSignedWrap && LimitVal) { >> + uint64_t oldBitSize = LimitVal->getValue().getBitWidth(); >> + uint64_t newBitSize = LargestType- >>> getPrimitiveSizeInBits(); >> + ConstantInt* AddRHS = dyn_cast(UInst- >>> getOperand(1)); >> + if (((APInt::getSignedMaxValue(oldBitSize) - IncrVal- >>> getValue()) - >> + AddRHS->getValue()).sgt(LimitVal->getValue())) { >> + // We've determined this is (i+constant) and it won't >> overflow. >> + if (isa(UInst->use_begin())) { >> + SExtInst* oldSext = dyn_cast(UInst- >>> use_begin()); >> + Value *TruncIndVar = getSignExtendedTruncVar(AR, SE, >> LargestType, >> + L, oldSext- >>> getType(), Rewriter, >> + InsertPt); >> + APInt APcopy = APInt(AddRHS->getValue()); >> + ConstantInt* newAddRHS >> =ConstantInt::get(APcopy.sext(newBitSize)); >> + Value *NewAdd = >> + BinaryOperator::CreateAdd(TruncIndVar, >> newAddRHS, >> + UInst->getName() >> +".nosex", UInst); >> + oldSext->replaceAllUsesWith(NewAdd); >> + if (Instruction *DeadUse = >> dyn_cast(oldSext)) >> + DeadInsts.insert(DeadUse); >> + DeadInsts.insert(UInst); >> + } >> } >> } >> - if (isa(UI) && NoUnsignedWrap) { >> + if (UInst && isa(UInst) && NoUnsignedWrap) { >> Value *TruncIndVar = getZeroExtendedTruncVar(AR, SE, >> LargestType, L, >> - UI->getType(), >> Rewriter, InsertPt); >> - UI->replaceAllUsesWith(TruncIndVar); >> - if (Instruction *DeadUse = dyn_cast(*UI)) >> + UInst->getType(), >> Rewriter, InsertPt); >> + UInst->replaceAllUsesWith(TruncIndVar); >> + DeadInsts.insert(UInst); >> + } >> + // If we have zext(i&constant), we can use the larger >> variable. This >> + // is not common but is a bottleneck in Openssl. >> + // (RHS doesn't have to be constant. There should be a >> better approach >> + // than bottom-up pattern matching for this...) >> + if (UInst && UInst->getOpcode()==Instruction::And && >> + UInst->hasOneUse() && >> + isa(UInst->getOperand(1)) && >> + isa(UInst->use_begin())) { >> + uint64_t newBitSize = LargestType- >>> getPrimitiveSizeInBits(); >> + ConstantInt* AndRHS = dyn_cast(UInst- >>> getOperand(1)); >> + ZExtInst* oldZext = dyn_cast(UInst- >> >use_begin()); >> + Value *TruncIndVar = getSignExtendedTruncVar(AR, SE, >> LargestType, >> + L, oldZext->getType(), Rewriter, >> InsertPt); >> + APInt APcopy = APInt(AndRHS->getValue()); >> + ConstantInt* newAndRHS = >> ConstantInt::get(APcopy.zext(newBitSize)); >> + Value *NewAnd = >> + BinaryOperator::CreateAnd(TruncIndVar, newAndRHS, >> + UInst->getName() >> +".nozex", UInst); >> + oldZext->replaceAllUsesWith(NewAnd); >> + if (Instruction *DeadUse = dyn_cast(oldZext)) >> DeadInsts.insert(DeadUse); >> + DeadInsts.insert(UInst); >> + } >> + // If we have zext((i+constant)&constant), we can use the >> larger >> + // variable even if the add does overflow. This works >> whenever the >> + // constant being ANDed is the same size as i, which it >> presumably is. >> + // We don't need to restrict the expression being and'ed to >> i+const, >> + // but we have to promote everything in it, so it's >> convenient. >> + if (UInst && UInst->getOpcode()==Instruction::Add && >> + UInst->hasOneUse() && >> + isa(UInst->getOperand(1))) { >> + uint64_t newBitSize = LargestType- >>> getPrimitiveSizeInBits(); >> + ConstantInt* AddRHS = dyn_cast(UInst- >>> getOperand(1)); >> + Instruction *UInst2 = dyn_cast(UInst- >>> use_begin()); >> + if (UInst2 && UInst2->getOpcode() == Instruction::And && >> + UInst2->hasOneUse() && >> + isa(UInst2->getOperand(1)) && >> + isa(UInst2->use_begin())) { >> + ZExtInst* oldZext = dyn_cast(UInst2- >>> use_begin()); >> + Value *TruncIndVar = getSignExtendedTruncVar(AR, SE, >> LargestType, >> + L, oldZext->getType(), >> Rewriter, InsertPt); >> + ConstantInt* AndRHS = dyn_cast(UInst2- >>> getOperand(1)); >> + APInt APcopy = APInt(AddRHS->getValue()); >> + ConstantInt* newAddRHS = >> ConstantInt::get(APcopy.zext(newBitSize)); >> + Value *NewAdd = >> + BinaryOperator::CreateAdd(TruncIndVar, newAddRHS, >> + UInst->getName() >> +".nozex", UInst2); >> + APInt APcopy2 = APInt(AndRHS->getValue()); >> + ConstantInt* newAndRHS = >> ConstantInt::get(APcopy2.zext(newBitSize)); >> + Value *NewAnd = >> + BinaryOperator::CreateAnd(NewAdd, newAndRHS, >> + UInst->getName() >> +".nozex", UInst2); >> + oldZext->replaceAllUsesWith(NewAnd); >> + if (Instruction *DeadUse = >> dyn_cast(oldZext)) >> + DeadInsts.insert(DeadUse); >> + DeadInsts.insert(UInst); >> + DeadInsts.insert(UInst2); >> + } >> } >> } >> >> >> >> _______________________________________________ >> 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 sabre at nondot.org Wed Apr 15 17:33:02 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 15 Apr 2009 22:33:02 -0000 Subject: [llvm-commits] [llvm] r69235 - /llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp Message-ID: <200904152233.n3FMX282013514@zion.cs.uiuc.edu> Author: lattner Date: Wed Apr 15 17:33:02 2009 New Revision: 69235 URL: http://llvm.org/viewvc/llvm-project?rev=69235&view=rev Log: make sure that empty diag groups get known by clang. Modified: llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp Modified: llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp?rev=69235&r1=69234&r2=69235&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp Wed Apr 15 17:33:02 2009 @@ -66,9 +66,8 @@ // groups to diags in the group. std::map > DiagsInGroup; - const std::vector &Diags = + std::vector Diags = Records.getAllDerivedDefinitions("Diagnostic"); - for (unsigned i = 0, e = Diags.size(); i != e; ++i) { const Record *R = Diags[i]; DefInit *DI = dynamic_cast(R->getValueInit("Group")); @@ -76,6 +75,13 @@ DiagsInGroup[DI->getDef()->getValueAsString("GroupName")].push_back(R); } + // Add all DiagGroup's to the DiagsInGroup list to make sure we pick up empty + // groups (these are warnings that GCC supports that clang never produces). + Diags = Records.getAllDerivedDefinitions("DiagGroup"); + for (unsigned i = 0, e = Diags.size(); i != e; ++i) { + DiagsInGroup[Diags[i]->getValueAsString("GroupName")]; + } + // Walk through the groups emitting an array for each diagnostic of the diags // that are mapped to. OS << "\n#ifdef GET_DIAG_ARRAYS\n"; From dalej at apple.com Wed Apr 15 18:31:51 2009 From: dalej at apple.com (Dale Johannesen) Date: Wed, 15 Apr 2009 23:31:51 -0000 Subject: [llvm-commits] [llvm] r69241 - /llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp Message-ID: <200904152331.n3FNVq76015332@zion.cs.uiuc.edu> Author: johannes Date: Wed Apr 15 18:31:51 2009 New Revision: 69241 URL: http://llvm.org/viewvc/llvm-project?rev=69241&view=rev Log: Eliminate zext over (iv | const) or (signed iv), and sext over (iv | const), if a longer iv is available. Allow expressions to have more than one zext/sext parent. All from OpenSSL. 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=69241&r1=69240&r2=69241&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp Wed Apr 15 18:31:51 2009 @@ -663,6 +663,23 @@ return Rewriter.expandCodeFor(ExtendedAddRec, InsertPt); } +/// allUsesAreSameTyped - See whether all Uses of I are instructions +/// with the same Opcode and the same type. +static bool allUsesAreSameTyped(unsigned int Opcode, Instruction *I) { + const Type* firstType = NULL; + for (Value::use_iterator UI = I->use_begin(), UE = I->use_end(); + UI != UE; ++UI) { + Instruction *II = dyn_cast(*UI); + if (!II || II->getOpcode() != Opcode) + return false; + if (!firstType) + firstType = II->getType(); + else if (firstType != II->getType()) + return false; + } + return true; +} + bool IndVarSimplify::runOnLoop(Loop *L, LPPassManager &LPM) { LI = &getAnalysis(); SE = &getAnalysis(); @@ -808,7 +825,7 @@ // See if we can figure out sext(i+constant) doesn't wrap, so we can // use a larger add. This is common in subscripting. if (UInst && UInst->getOpcode()==Instruction::Add && - UInst->hasOneUse() && + allUsesAreSameTyped(Instruction::SExt, UInst) && isa(UInst->getOperand(1)) && NoSignedWrap && LimitVal) { uint64_t oldBitSize = LimitVal->getValue().getBitWidth(); @@ -827,27 +844,56 @@ Value *NewAdd = BinaryOperator::CreateAdd(TruncIndVar, newAddRHS, UInst->getName()+".nosex", UInst); - oldSext->replaceAllUsesWith(NewAdd); - if (Instruction *DeadUse = dyn_cast(oldSext)) - DeadInsts.insert(DeadUse); + for (Value::use_iterator UI2 = UInst->use_begin(), + UE2 = UInst->use_end(); UI2 != UE2; ++UI2) { + Instruction *II = dyn_cast(UI2); + II->replaceAllUsesWith(NewAdd); + DeadInsts.insert(II); + } DeadInsts.insert(UInst); } } } - if (UInst && isa(UInst) && NoUnsignedWrap) { + // Try for sext(i | constant). This is safe as long as the + // high bit of the constant is not set. + if (UInst && UInst->getOpcode()==Instruction::Or && + allUsesAreSameTyped(Instruction::SExt, UInst) && NoSignedWrap && + isa(UInst->getOperand(1))) { + ConstantInt* RHS = dyn_cast(UInst->getOperand(1)); + if (!RHS->getValue().isNegative()) { + uint64_t newBitSize = LargestType->getPrimitiveSizeInBits(); + SExtInst* oldSext = dyn_cast(UInst->use_begin()); + Value *TruncIndVar = getSignExtendedTruncVar(AR, SE, LargestType, + L, oldSext->getType(), Rewriter, + InsertPt); + APInt APcopy = APInt(RHS->getValue()); + ConstantInt* newRHS =ConstantInt::get(APcopy.sext(newBitSize)); + Value *NewAdd = + BinaryOperator::CreateOr(TruncIndVar, newRHS, + UInst->getName()+".nosex", UInst); + for (Value::use_iterator UI2 = UInst->use_begin(), + UE2 = UInst->use_end(); UI2 != UE2; ++UI2) { + Instruction *II = dyn_cast(UI2); + II->replaceAllUsesWith(NewAdd); + DeadInsts.insert(II); + } + DeadInsts.insert(UInst); + } + } + // A zext of a signed variable known not to overflow is still safe. + if (UInst && isa(UInst) && (NoUnsignedWrap || NoSignedWrap)) { Value *TruncIndVar = getZeroExtendedTruncVar(AR, SE, LargestType, L, UInst->getType(), Rewriter, InsertPt); UInst->replaceAllUsesWith(TruncIndVar); DeadInsts.insert(UInst); } - // If we have zext(i&constant), we can use the larger variable. This - // is not common but is a bottleneck in Openssl. + // If we have zext(i&constant), it's always safe to use the larger + // variable. This is not common but is a bottleneck in Openssl. // (RHS doesn't have to be constant. There should be a better approach // than bottom-up pattern matching for this...) if (UInst && UInst->getOpcode()==Instruction::And && - UInst->hasOneUse() && - isa(UInst->getOperand(1)) && - isa(UInst->use_begin())) { + allUsesAreSameTyped(Instruction::ZExt, UInst) && + isa(UInst->getOperand(1))) { uint64_t newBitSize = LargestType->getPrimitiveSizeInBits(); ConstantInt* AndRHS = dyn_cast(UInst->getOperand(1)); ZExtInst* oldZext = dyn_cast(UInst->use_begin()); @@ -858,9 +904,12 @@ Value *NewAnd = BinaryOperator::CreateAnd(TruncIndVar, newAndRHS, UInst->getName()+".nozex", UInst); - oldZext->replaceAllUsesWith(NewAnd); - if (Instruction *DeadUse = dyn_cast(oldZext)) - DeadInsts.insert(DeadUse); + for (Value::use_iterator UI2 = UInst->use_begin(), + UE2 = UInst->use_end(); UI2 != UE2; ++UI2) { + Instruction *II = dyn_cast(UI2); + II->replaceAllUsesWith(NewAnd); + DeadInsts.insert(II); + } DeadInsts.insert(UInst); } // If we have zext((i+constant)&constant), we can use the larger @@ -868,33 +917,39 @@ // constant being ANDed is the same size as i, which it presumably is. // We don't need to restrict the expression being and'ed to i+const, // but we have to promote everything in it, so it's convenient. - if (UInst && UInst->getOpcode()==Instruction::Add && + // zext((i | constant)&constant) is also valid and accepted here. + if (UInst && (UInst->getOpcode()==Instruction::Add || + UInst->getOpcode()==Instruction::Or) && UInst->hasOneUse() && isa(UInst->getOperand(1))) { uint64_t newBitSize = LargestType->getPrimitiveSizeInBits(); ConstantInt* AddRHS = dyn_cast(UInst->getOperand(1)); Instruction *UInst2 = dyn_cast(UInst->use_begin()); if (UInst2 && UInst2->getOpcode() == Instruction::And && - UInst2->hasOneUse() && - isa(UInst2->getOperand(1)) && - isa(UInst2->use_begin())) { + allUsesAreSameTyped(Instruction::ZExt, UInst2) && + isa(UInst2->getOperand(1))) { ZExtInst* oldZext = dyn_cast(UInst2->use_begin()); Value *TruncIndVar = getSignExtendedTruncVar(AR, SE, LargestType, L, oldZext->getType(), Rewriter, InsertPt); ConstantInt* AndRHS = dyn_cast(UInst2->getOperand(1)); APInt APcopy = APInt(AddRHS->getValue()); ConstantInt* newAddRHS = ConstantInt::get(APcopy.zext(newBitSize)); - Value *NewAdd = + Value *NewAdd = ((UInst->getOpcode()==Instruction::Add) ? BinaryOperator::CreateAdd(TruncIndVar, newAddRHS, - UInst->getName()+".nozex", UInst2); + UInst->getName()+".nozex", UInst2) : + BinaryOperator::CreateOr(TruncIndVar, newAddRHS, + UInst->getName()+".nozex", UInst2)); APInt APcopy2 = APInt(AndRHS->getValue()); ConstantInt* newAndRHS = ConstantInt::get(APcopy2.zext(newBitSize)); Value *NewAnd = BinaryOperator::CreateAnd(NewAdd, newAndRHS, UInst->getName()+".nozex", UInst2); - oldZext->replaceAllUsesWith(NewAnd); - if (Instruction *DeadUse = dyn_cast(oldZext)) - DeadInsts.insert(DeadUse); + for (Value::use_iterator UI2 = UInst2->use_begin(), + UE2 = UInst2->use_end(); UI2 != UE2; ++UI2) { + Instruction *II = dyn_cast(UI2); + II->replaceAllUsesWith(NewAnd); + DeadInsts.insert(II); + } DeadInsts.insert(UInst); DeadInsts.insert(UInst2); } From dalej at apple.com Wed Apr 15 19:45:24 2009 From: dalej at apple.com (Dale Johannesen) Date: Thu, 16 Apr 2009 00:45:24 -0000 Subject: [llvm-commits] [llvm] r69247 - /llvm/trunk/test/Transforms/IndVarSimplify/2009-04-15-shorten-iv-vars-2.ll Message-ID: <200904160045.n3G0jOa4017484@zion.cs.uiuc.edu> Author: johannes Date: Wed Apr 15 19:45:21 2009 New Revision: 69247 URL: http://llvm.org/viewvc/llvm-project?rev=69247&view=rev Log: Another testcase for IV shortening. Added: llvm/trunk/test/Transforms/IndVarSimplify/2009-04-15-shorten-iv-vars-2.ll Added: llvm/trunk/test/Transforms/IndVarSimplify/2009-04-15-shorten-iv-vars-2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/IndVarSimplify/2009-04-15-shorten-iv-vars-2.ll?rev=69247&view=auto ============================================================================== --- llvm/trunk/test/Transforms/IndVarSimplify/2009-04-15-shorten-iv-vars-2.ll (added) +++ llvm/trunk/test/Transforms/IndVarSimplify/2009-04-15-shorten-iv-vars-2.ll Wed Apr 15 19:45:21 2009 @@ -0,0 +1,161 @@ +; RUN: llvm-as < %s | opt -indvars | llvm-dis | not grep {sext} +; RUN: llvm-as < %s | opt -indvars | llvm-dis | not grep {zext} +; ModuleID = '' +;extern int *a, *b, *c, *d, *e, *f; /* 64 bit */ +;extern int K[256]; +;void foo () { +; int i; +; for (i=0; i<23647; i++) { +; a[(i&15)] = b[i&15]+c[i&15]; +; a[(i+1)&15] = b[(i+1)&15]+c[(i+1)&15]; +; a[(i+2)&15] = b[(i+2)&15]+c[(i+2)&15]; +; d[i&15] = e[i&15]+f[i&15] +K[i]; +; d[(i+1)&15] = e[(i+1)&15]+f[(i+1)&15]+K[i+1]; +; d[(i+2)&15] = e[(i+2)&15]+f[(i+2)&15]+K[i+2]; +; } +;} +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" +target triple = "x86_64-apple-darwin9.6" + at a = external global i32* ; [#uses=3] + at b = external global i32* ; [#uses=3] + at c = external global i32* ; [#uses=3] + at d = external global i32* ; [#uses=3] + at e = external global i32* ; [#uses=3] + at f = external global i32* ; [#uses=3] + at K = external global [256 x i32] ; <[256 x i32]*> [#uses=3] + +define void @foo() nounwind { +bb1.thread: + br label %bb1 + +bb1: ; preds = %bb1, %bb1.thread + %i.0.reg2mem.0 = phi i32 [ 0, %bb1.thread ], [ %116, %bb1 ] ; [#uses=22] + %0 = load i32** @a, align 8 ; [#uses=1] + %1 = and i32 %i.0.reg2mem.0, 15 ; [#uses=1] + %2 = load i32** @b, align 8 ; [#uses=1] + %3 = and i32 %i.0.reg2mem.0, 15 ; [#uses=1] + %4 = zext i32 %3 to i64 ; [#uses=1] + %5 = getelementptr i32* %2, i64 %4 ; [#uses=1] + %6 = load i32* %5, align 1 ; [#uses=1] + %7 = load i32** @c, align 8 ; [#uses=1] + %8 = and i32 %i.0.reg2mem.0, 15 ; [#uses=1] + %9 = zext i32 %8 to i64 ; [#uses=1] + %10 = getelementptr i32* %7, i64 %9 ; [#uses=1] + %11 = load i32* %10, align 1 ; [#uses=1] + %12 = add i32 %11, %6 ; [#uses=1] + %13 = zext i32 %1 to i64 ; [#uses=1] + %14 = getelementptr i32* %0, i64 %13 ; [#uses=1] + store i32 %12, i32* %14, align 1 + %15 = load i32** @a, align 8 ; [#uses=1] + %16 = add i32 %i.0.reg2mem.0, 1 ; [#uses=1] + %17 = and i32 %16, 15 ; [#uses=1] + %18 = load i32** @b, align 8 ; [#uses=1] + %19 = add i32 %i.0.reg2mem.0, 1 ; [#uses=1] + %20 = and i32 %19, 15 ; [#uses=1] + %21 = zext i32 %20 to i64 ; [#uses=1] + %22 = getelementptr i32* %18, i64 %21 ; [#uses=1] + %23 = load i32* %22, align 1 ; [#uses=1] + %24 = load i32** @c, align 8 ; [#uses=1] + %25 = add i32 %i.0.reg2mem.0, 1 ; [#uses=1] + %26 = and i32 %25, 15 ; [#uses=1] + %27 = zext i32 %26 to i64 ; [#uses=1] + %28 = getelementptr i32* %24, i64 %27 ; [#uses=1] + %29 = load i32* %28, align 1 ; [#uses=1] + %30 = add i32 %29, %23 ; [#uses=1] + %31 = zext i32 %17 to i64 ; [#uses=1] + %32 = getelementptr i32* %15, i64 %31 ; [#uses=1] + store i32 %30, i32* %32, align 1 + %33 = load i32** @a, align 8 ; [#uses=1] + %34 = add i32 %i.0.reg2mem.0, 2 ; [#uses=1] + %35 = and i32 %34, 15 ; [#uses=1] + %36 = load i32** @b, align 8 ; [#uses=1] + %37 = add i32 %i.0.reg2mem.0, 2 ; [#uses=1] + %38 = and i32 %37, 15 ; [#uses=1] + %39 = zext i32 %38 to i64 ; [#uses=1] + %40 = getelementptr i32* %36, i64 %39 ; [#uses=1] + %41 = load i32* %40, align 1 ; [#uses=1] + %42 = load i32** @c, align 8 ; [#uses=1] + %43 = add i32 %i.0.reg2mem.0, 2 ; [#uses=1] + %44 = and i32 %43, 15 ; [#uses=1] + %45 = zext i32 %44 to i64 ; [#uses=1] + %46 = getelementptr i32* %42, i64 %45 ; [#uses=1] + %47 = load i32* %46, align 1 ; [#uses=1] + %48 = add i32 %47, %41 ; [#uses=1] + %49 = zext i32 %35 to i64 ; [#uses=1] + %50 = getelementptr i32* %33, i64 %49 ; [#uses=1] + store i32 %48, i32* %50, align 1 + %51 = load i32** @d, align 8 ; [#uses=1] + %52 = and i32 %i.0.reg2mem.0, 15 ; [#uses=1] + %53 = load i32** @e, align 8 ; [#uses=1] + %54 = and i32 %i.0.reg2mem.0, 15 ; [#uses=1] + %55 = zext i32 %54 to i64 ; [#uses=1] + %56 = getelementptr i32* %53, i64 %55 ; [#uses=1] + %57 = load i32* %56, align 1 ; [#uses=1] + %58 = load i32** @f, align 8 ; [#uses=1] + %59 = and i32 %i.0.reg2mem.0, 15 ; [#uses=1] + %60 = zext i32 %59 to i64 ; [#uses=1] + %61 = getelementptr i32* %58, i64 %60 ; [#uses=1] + %62 = load i32* %61, align 1 ; [#uses=1] + %63 = sext i32 %i.0.reg2mem.0 to i64 ; [#uses=1] + %64 = getelementptr [256 x i32]* @K, i64 0, i64 %63 ; [#uses=1] + %65 = load i32* %64, align 4 ; [#uses=1] + %66 = add i32 %62, %57 ; [#uses=1] + %67 = add i32 %66, %65 ; [#uses=1] + %68 = zext i32 %52 to i64 ; [#uses=1] + %69 = getelementptr i32* %51, i64 %68 ; [#uses=1] + store i32 %67, i32* %69, align 1 + %70 = load i32** @d, align 8 ; [#uses=1] + %71 = add i32 %i.0.reg2mem.0, 1 ; [#uses=1] + %72 = and i32 %71, 15 ; [#uses=1] + %73 = load i32** @e, align 8 ; [#uses=1] + %74 = add i32 %i.0.reg2mem.0, 1 ; [#uses=1] + %75 = and i32 %74, 15 ; [#uses=1] + %76 = zext i32 %75 to i64 ; [#uses=1] + %77 = getelementptr i32* %73, i64 %76 ; [#uses=1] + %78 = load i32* %77, align 1 ; [#uses=1] + %79 = load i32** @f, align 8 ; [#uses=1] + %80 = add i32 %i.0.reg2mem.0, 1 ; [#uses=1] + %81 = and i32 %80, 15 ; [#uses=1] + %82 = zext i32 %81 to i64 ; [#uses=1] + %83 = getelementptr i32* %79, i64 %82 ; [#uses=1] + %84 = load i32* %83, align 1 ; [#uses=1] + %85 = add i32 %i.0.reg2mem.0, 1 ; [#uses=1] + %86 = sext i32 %85 to i64 ; [#uses=1] + %87 = getelementptr [256 x i32]* @K, i64 0, i64 %86 ; [#uses=1] + %88 = load i32* %87, align 4 ; [#uses=1] + %89 = add i32 %84, %78 ; [#uses=1] + %90 = add i32 %89, %88 ; [#uses=1] + %91 = zext i32 %72 to i64 ; [#uses=1] + %92 = getelementptr i32* %70, i64 %91 ; [#uses=1] + store i32 %90, i32* %92, align 1 + %93 = load i32** @d, align 8 ; [#uses=1] + %94 = add i32 %i.0.reg2mem.0, 2 ; [#uses=1] + %95 = and i32 %94, 15 ; [#uses=1] + %96 = load i32** @e, align 8 ; [#uses=1] + %97 = add i32 %i.0.reg2mem.0, 2 ; [#uses=1] + %98 = and i32 %97, 15 ; [#uses=1] + %99 = zext i32 %98 to i64 ; [#uses=1] + %100 = getelementptr i32* %96, i64 %99 ; [#uses=1] + %101 = load i32* %100, align 1 ; [#uses=1] + %102 = load i32** @f, align 8 ; [#uses=1] + %103 = add i32 %i.0.reg2mem.0, 2 ; [#uses=1] + %104 = and i32 %103, 15 ; [#uses=1] + %105 = zext i32 %104 to i64 ; [#uses=1] + %106 = getelementptr i32* %102, i64 %105 ; [#uses=1] + %107 = load i32* %106, align 1 ; [#uses=1] + %108 = add i32 %i.0.reg2mem.0, 2 ; [#uses=1] + %109 = sext i32 %108 to i64 ; [#uses=1] + %110 = getelementptr [256 x i32]* @K, i64 0, i64 %109 ; [#uses=1] + %111 = load i32* %110, align 4 ; [#uses=1] + %112 = add i32 %107, %101 ; [#uses=1] + %113 = add i32 %112, %111 ; [#uses=1] + %114 = zext i32 %95 to i64 ; [#uses=1] + %115 = getelementptr i32* %93, i64 %114 ; [#uses=1] + store i32 %113, i32* %115, align 1 + %116 = add i32 %i.0.reg2mem.0, 1 ; [#uses=2] + %117 = icmp sgt i32 %116, 23646 ; [#uses=1] + br i1 %117, label %return, label %bb1 + +return: ; preds = %bb1 + ret void +} From sabre at nondot.org Wed Apr 15 19:53:25 2009 From: sabre at nondot.org (Chris Lattner) Date: Thu, 16 Apr 2009 00:53:25 -0000 Subject: [llvm-commits] [llvm] r69249 - /llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp Message-ID: <200904160053.n3G0rPD0017752@zion.cs.uiuc.edu> Author: lattner Date: Wed Apr 15 19:53:25 2009 New Revision: 69249 URL: http://llvm.org/viewvc/llvm-project?rev=69249&view=rev Log: start producing subgroup info. Modified: llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp Modified: llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp?rev=69249&r1=69248&r2=69249&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp Wed Apr 15 19:53:25 2009 @@ -61,10 +61,15 @@ // Warning Group Tables generation //===----------------------------------------------------------------------===// +struct GroupInfo { + std::vector DiagsInGroup; + std::vector SubGroups; +}; + void ClangDiagGroupsEmitter::run(std::ostream &OS) { // Invert the 1-[0/1] mapping of diags to group into a one to many mapping of // groups to diags in the group. - std::map > DiagsInGroup; + std::map DiagsInGroup; std::vector Diags = Records.getAllDerivedDefinitions("Diagnostic"); @@ -72,14 +77,20 @@ const Record *R = Diags[i]; DefInit *DI = dynamic_cast(R->getValueInit("Group")); if (DI == 0) continue; - DiagsInGroup[DI->getDef()->getValueAsString("GroupName")].push_back(R); + std::string GroupName = DI->getDef()->getValueAsString("GroupName"); + DiagsInGroup[GroupName].DiagsInGroup.push_back(R); } // Add all DiagGroup's to the DiagsInGroup list to make sure we pick up empty // groups (these are warnings that GCC supports that clang never produces). Diags = Records.getAllDerivedDefinitions("DiagGroup"); for (unsigned i = 0, e = Diags.size(); i != e; ++i) { - DiagsInGroup[Diags[i]->getValueAsString("GroupName")]; + Record *Group = Diags[i]; + GroupInfo &GI = DiagsInGroup[Group->getValueAsString("GroupName")]; + + std::vector SubGroups = Group->getValueAsListOfDefs("SubGroups"); + for (unsigned j = 0, e = SubGroups.size(); j != e; ++j) + GI.SubGroups.push_back(SubGroups[j]->getValueAsString("GroupName")); } // Walk through the groups emitting an array for each diagnostic of the diags @@ -87,13 +98,15 @@ OS << "\n#ifdef GET_DIAG_ARRAYS\n"; unsigned IDNo = 0; unsigned MaxLen = 0; - for (std::map >::iterator + for (std::map::iterator I = DiagsInGroup.begin(), E = DiagsInGroup.end(); I != E; ++I) { MaxLen = std::max(MaxLen, (unsigned)I->first.size()); + std::vector &V = I->second.DiagsInGroup; + if (V.empty()) continue; + OS << "static const short DiagArray" << IDNo++ << "[] = { "; - std::vector &V = I->second; for (unsigned i = 0, e = V.size(); i != e; ++i) OS << "diag::" << V[i]->getName() << ", "; OS << "-1 };\n"; @@ -103,13 +116,23 @@ // Emit the table now. OS << "\n#ifdef GET_DIAG_TABLE\n"; IDNo = 0; - for (std::map >::iterator + for (std::map::iterator I = DiagsInGroup.begin(), E = DiagsInGroup.end(); I != E; ++I) { std::string S = I->first; EscapeString(S); + // Group option string. OS << " { \"" << S << "\"," - << std::string(MaxLen-I->first.size()+1, ' ') - << "DiagArray" << IDNo++ << " },\n"; + << std::string(MaxLen-I->first.size()+1, ' '); + + // Diagnostics in the group. + if (I->second.DiagsInGroup.empty()) + OS << "0, "; + else + OS << "DiagArray" << IDNo++ << ", "; + + // FIXME: Subgroups. + OS << 0; + OS << " },\n"; } OS << "#endif // GET_DIAG_TABLE\n\n"; } From dpatel at apple.com Wed Apr 15 20:31:55 2009 From: dpatel at apple.com (Devang Patel) Date: Thu, 16 Apr 2009 01:31:55 -0000 Subject: [llvm-commits] [llvm] r69252 - /llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp Message-ID: <200904160131.n3G1Vt8t019121@zion.cs.uiuc.edu> Author: dpatel Date: Wed Apr 15 20:31:54 2009 New Revision: 69252 URL: http://llvm.org/viewvc/llvm-project?rev=69252&view=rev Log: If location where the function was inlined is not know then do not emit debug info describing inlinied region. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp?rev=69252&r1=69251&r2=69252&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp Wed Apr 15 20:31:54 2009 @@ -387,12 +387,14 @@ unsigned SrcFile = DW->getOrCreateSourceID(CompileUnit.getDirectory(Dir), CompileUnit.getFilename(FN)); - // Record the source line. - unsigned Line = Subprogram.getLineNumber(); - unsigned LabelID = DW->RecordSourceLine(Line, 0, SrcFile); - setCurDebugLoc(DebugLoc::get(MF.getOrCreateDebugLocID(SrcFile, Line, 0))); - if (!Subprogram.describes(MF.getFunction())) { + if (!Subprogram.describes(MF.getFunction()) && !PrevLoc.isUnknown()) { // This is a beginning of an inlined function. + + // Record the source line. + unsigned Line = Subprogram.getLineNumber(); + unsigned LabelID = DW->RecordSourceLine(Line, 0, SrcFile); + setCurDebugLoc(DebugLoc::get(MF.getOrCreateDebugLocID(SrcFile, Line, 0))); + const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL); BuildMI(MBB, DL, II).addImm(LabelID); DebugLocTuple PrevLocTpl = MF.getDebugLocTuple(PrevLoc); @@ -401,6 +403,10 @@ PrevLocTpl.Line, PrevLocTpl.Col); } else { + // Record the source line. + unsigned Line = Subprogram.getLineNumber(); + setCurDebugLoc(DebugLoc::get(MF.getOrCreateDebugLocID(SrcFile, Line, 0))); + // llvm.dbg.func_start also defines beginning of function scope. DW->RecordRegionStart(cast(FSI->getSubprogram())); } From dpatel at apple.com Wed Apr 15 20:33:10 2009 From: dpatel at apple.com (Devang Patel) Date: Thu, 16 Apr 2009 01:33:10 -0000 Subject: [llvm-commits] [llvm] r69253 - in /llvm/trunk: include/llvm/CodeGen/FastISel.h lib/CodeGen/SelectionDAG/SelectionDAGBuild.h lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200904160133.n3G1XAxt019164@zion.cs.uiuc.edu> Author: dpatel Date: Wed Apr 15 20:33:10 2009 New Revision: 69253 URL: http://llvm.org/viewvc/llvm-project?rev=69253&view=rev Log: If FastISel is run and it has known DebugLoc then use it. Modified: llvm/trunk/include/llvm/CodeGen/FastISel.h llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Modified: llvm/trunk/include/llvm/CodeGen/FastISel.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/FastISel.h?rev=69253&r1=69252&r2=69253&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/FastISel.h (original) +++ llvm/trunk/include/llvm/CodeGen/FastISel.h Wed Apr 15 20:33:10 2009 @@ -83,6 +83,9 @@ /// void setCurDebugLoc(DebugLoc dl) { DL = dl; } + /// getCurDebugLoc() - Return current debug location information. + DebugLoc getCurDebugLoc() const { return DL; } + /// SelectInstruction - Do "fast" instruction selection for the given /// LLVM IR instruction, and append generated machine instructions to /// the current block. Return true if selection was successful. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h?rev=69253&r1=69252&r2=69253&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h Wed Apr 15 20:33:10 2009 @@ -392,6 +392,7 @@ SDValue getControlRoot(); DebugLoc getCurDebugLoc() const { return CurDebugLoc; } + void setCurDebugLoc(DebugLoc dl) { CurDebugLoc = dl; } void CopyValueToVirtualRegister(Value *V, unsigned Reg); @@ -542,8 +543,6 @@ const char *implVisitBinaryAtomic(CallInst& I, ISD::NodeType Op); const char *implVisitAluOverflow(CallInst &I, ISD::NodeType Op); - - void setCurDebugLoc(DebugLoc dl) { CurDebugLoc = dl; } }; /// AddCatchInfo - Extract the personality and type infos from an eh.selector Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=69253&r1=69252&r2=69253&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Wed Apr 15 20:33:10 2009 @@ -824,6 +824,7 @@ R = FuncInfo->CreateRegForValue(BI); } + SDL->setCurDebugLoc(FastIS->getCurDebugLoc()); SelectBasicBlock(LLVMBB, BI, next(BI)); // If the instruction was codegen'd with multiple blocks, // inform the FastISel object where to resume inserting. @@ -850,8 +851,12 @@ // Run SelectionDAG instruction selection on the remainder of the block // not handled by FastISel. If FastISel is not run, this is the entire // block. - if (BI != End) + if (BI != End) { + // If FastISel is run and it has known DebugLoc then use it. + if (FastIS && !FastIS->getCurDebugLoc().isUnknown()) + SDL->setCurDebugLoc(FastIS->getCurDebugLoc()); SelectBasicBlock(LLVMBB, BI, End); + } FinishBasicBlock(); } From dpatel at apple.com Wed Apr 15 21:33:41 2009 From: dpatel at apple.com (Devang Patel) Date: Thu, 16 Apr 2009 02:33:41 -0000 Subject: [llvm-commits] [llvm] r69254 - in /llvm/trunk/lib/CodeGen/SelectionDAG: SelectionDAGBuild.cpp SelectionDAGISel.cpp Message-ID: <200904160233.n3G2XfuY020692@zion.cs.uiuc.edu> Author: dpatel Date: Wed Apr 15 21:33:41 2009 New Revision: 69254 URL: http://llvm.org/viewvc/llvm-project?rev=69254&view=rev Log: In -fast mode do what FastISel does. This code could use some refactoring help! Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp?rev=69254&r1=69253&r2=69254&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Wed Apr 15 21:33:41 2009 @@ -3961,8 +3961,14 @@ Subprogram.getLinkageName(SPName); if (!SPName.empty() && strcmp(SPName.c_str(), MF.getFunction()->getNameStart())) { - // This is end of inlined function. Debugging information for - // inlined function is not handled yet (only supported by FastISel). + // This is end of inlined function. Debugging information for + // inlined function is not handled yet (only supported by FastISel). + if (Fast) { + unsigned ID = DW->RecordInlinedFnEnd(Subprogram); + if (ID != 0) + DAG.setRoot(DAG.getLabel(ISD::DBG_LABEL, getCurDebugLoc(), + getRoot(), ID)); + } return 0; } @@ -3980,38 +3986,67 @@ DbgFuncStartInst &FSI = cast(I); Value *SP = FSI.getSubprogram(); if (SP && DW->ValidDebugInfo(SP, Fast)) { - // llvm.dbg.func.start implicitly defines a dbg_stoppoint which is - // what (most?) gdb expects. - MachineFunction &MF = DAG.getMachineFunction(); - DISubprogram Subprogram(cast(SP)); - - std::string SPName; - Subprogram.getLinkageName(SPName); - if (!SPName.empty() - && strcmp(SPName.c_str(), MF.getFunction()->getNameStart())) { - // This is beginning of inlined function. Debugging information for - // inlined function is not handled yet (only supported by FastISel). - return 0; - } - - DICompileUnit CompileUnit = Subprogram.getCompileUnit(); - std::string Dir, FN; - unsigned SrcFile = DW->getOrCreateSourceID(CompileUnit.getDirectory(Dir), - CompileUnit.getFilename(FN)); - - // Record the source line but does not create a label for the normal - // function start. It will be emitted at asm emission time. However, - // create a label if this is a beginning of inlined function. - unsigned Line = Subprogram.getLineNumber(); - + MachineFunction &MF = DAG.getMachineFunction(); if (Fast) { - unsigned LabelID = DW->RecordSourceLine(Line, 0, SrcFile); - if (DW->getRecordSourceLineCount() != 1) + // llvm.dbg.func.start implicitly defines a dbg_stoppoint which is what + // (most?) gdb expects. + DebugLoc PrevLoc = CurDebugLoc; + DISubprogram Subprogram(cast(SP)); + DICompileUnit CompileUnit = Subprogram.getCompileUnit(); + std::string Dir, FN; + unsigned SrcFile = DW->getOrCreateSourceID(CompileUnit.getDirectory(Dir), + CompileUnit.getFilename(FN)); + + if (!Subprogram.describes(MF.getFunction())) { + // This is a beginning of an inlined function. + + // Record the source line. + unsigned Line = Subprogram.getLineNumber(); + unsigned LabelID = DW->RecordSourceLine(Line, 0, SrcFile); + setCurDebugLoc(DebugLoc::get(MF.getOrCreateDebugLocID(SrcFile, Line, 0))); + DAG.setRoot(DAG.getLabel(ISD::DBG_LABEL, getCurDebugLoc(), getRoot(), LabelID)); - } + DebugLocTuple PrevLocTpl = MF.getDebugLocTuple(PrevLoc); + DW->RecordInlinedFnStart(&FSI, Subprogram, LabelID, + PrevLocTpl.Src, + PrevLocTpl.Line, + PrevLocTpl.Col); + } else { + // Record the source line. + unsigned Line = Subprogram.getLineNumber(); + setCurDebugLoc(DebugLoc::get(MF.getOrCreateDebugLocID(SrcFile, Line, 0))); - setCurDebugLoc(DebugLoc::get(MF.getOrCreateDebugLocID(SrcFile, Line, 0))); + // llvm.dbg.func_start also defines beginning of function scope. + DW->RecordRegionStart(cast(FSI.getSubprogram())); + } + } else { + DISubprogram Subprogram(cast(SP)); + + std::string SPName; + Subprogram.getLinkageName(SPName); + if (!SPName.empty() + && strcmp(SPName.c_str(), MF.getFunction()->getNameStart())) { + // This is beginning of inlined function. Debugging information for + // inlined function is not handled yet (only supported by FastISel). + return 0; + } + + // llvm.dbg.func.start implicitly defines a dbg_stoppoint which is + // what (most?) gdb expects. + DICompileUnit CompileUnit = Subprogram.getCompileUnit(); + std::string Dir, FN; + unsigned SrcFile = DW->getOrCreateSourceID(CompileUnit.getDirectory(Dir), + CompileUnit.getFilename(FN)); + + // Record the source line but does not create a label for the normal + // function start. It will be emitted at asm emission time. However, + // create a label if this is a beginning of inlined function. + unsigned Line = Subprogram.getLineNumber(); + setCurDebugLoc(DebugLoc::get(MF.getOrCreateDebugLocID(SrcFile, Line, 0))); + // FIXME - Start new region because llvm.dbg.func_start also defines + // beginning of function scope. + } } return 0; Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=69254&r1=69253&r2=69254&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Wed Apr 15 21:33:41 2009 @@ -296,6 +296,12 @@ assert((!EnableFastISelAbort || EnableFastISel) && "-fast-isel-abort requires -fast-isel"); + // Do not codegen any 'available_externally' functions at all, they have + // definitions outside the translation unit. + if (Fn.hasAvailableExternallyLinkage()) + return false; + + // Get alias analysis for load/store combining. AA = &getAnalysis(); From clattner at apple.com Wed Apr 15 21:39:43 2009 From: clattner at apple.com (Chris Lattner) Date: Wed, 15 Apr 2009 19:39:43 -0700 Subject: [llvm-commits] [llvm] r69247 - /llvm/trunk/test/Transforms/IndVarSimplify/2009-04-15-shorten-iv-vars-2.ll In-Reply-To: <200904160045.n3G0jOa4017484@zion.cs.uiuc.edu> References: <200904160045.n3G0jOa4017484@zion.cs.uiuc.edu> Message-ID: <3A7F9778-45D8-42DA-9BDC-B310B5909CD0@apple.com> On Apr 15, 2009, at 5:45 PM, Dale Johannesen wrote: > Author: johannes > Date: Wed Apr 15 19:45:21 2009 > New Revision: 69247 > > URL: http://llvm.org/viewvc/llvm-project?rev=69247&view=rev > Log: > Another testcase for IV shortening. Thanks Dale! -Chris From dpatel at apple.com Wed Apr 15 21:45:32 2009 From: dpatel at apple.com (Devang Patel) Date: Wed, 15 Apr 2009 19:45:32 -0700 Subject: [llvm-commits] Fwd: [llvm] r69254 - in /llvm/trunk/lib/CodeGen/SelectionDAG: SelectionDAGBuild.cpp SelectionDAGISel.cpp References: <200904160233.n3G2XfuY020692@zion.cs.uiuc.edu> Message-ID: This patch also disables SelectionDAGLowering for functions with available_external linkage. - Devang Begin forwarded message: > Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=69254&r1=69253&r2=69254&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp > (original) > +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Wed Apr > 15 21:33:41 2009 > @@ -296,6 +296,12 @@ > assert((!EnableFastISelAbort || EnableFastISel) && > "-fast-isel-abort requires -fast-isel"); > > + // Do not codegen any 'available_externally' functions at all, > they have > + // definitions outside the translation unit. > + if (Fn.hasAvailableExternallyLinkage()) > + return false; > + > + > // Get alias analysis for load/store combining. > AA = &getAnalysis(); > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20090415/29f5402d/attachment.html From sabre at nondot.org Wed Apr 15 22:16:16 2009 From: sabre at nondot.org (Chris Lattner) Date: Thu, 16 Apr 2009 03:16:16 -0000 Subject: [llvm-commits] [llvm] r69257 - /llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp Message-ID: <200904160316.n3G3GGHu022037@zion.cs.uiuc.edu> Author: lattner Date: Wed Apr 15 22:16:12 2009 New Revision: 69257 URL: http://llvm.org/viewvc/llvm-project?rev=69257&view=rev Log: encode subgroups into the clang .inc file. -Wall now works! Modified: llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp Modified: llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp?rev=69257&r1=69256&r2=69257&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp Wed Apr 15 22:16:12 2009 @@ -64,6 +64,7 @@ struct GroupInfo { std::vector DiagsInGroup; std::vector SubGroups; + unsigned IDNo; }; void ClangDiagGroupsEmitter::run(std::ostream &OS) { @@ -93,29 +94,44 @@ GI.SubGroups.push_back(SubGroups[j]->getValueAsString("GroupName")); } + // Assign unique ID numbers to the groups. + unsigned IDNo = 0; + for (std::map::iterator + I = DiagsInGroup.begin(), E = DiagsInGroup.end(); I != E; ++I, ++IDNo) + I->second.IDNo = IDNo; + // Walk through the groups emitting an array for each diagnostic of the diags // that are mapped to. OS << "\n#ifdef GET_DIAG_ARRAYS\n"; - unsigned IDNo = 0; unsigned MaxLen = 0; for (std::map::iterator I = DiagsInGroup.begin(), E = DiagsInGroup.end(); I != E; ++I) { MaxLen = std::max(MaxLen, (unsigned)I->first.size()); std::vector &V = I->second.DiagsInGroup; - if (V.empty()) continue; + if (!V.empty()) { + OS << "static const short DiagArray" << I->second.IDNo << "[] = { "; + for (unsigned i = 0, e = V.size(); i != e; ++i) + OS << "diag::" << V[i]->getName() << ", "; + OS << "-1 };\n"; + } - OS << "static const short DiagArray" << IDNo++ - << "[] = { "; - for (unsigned i = 0, e = V.size(); i != e; ++i) - OS << "diag::" << V[i]->getName() << ", "; - OS << "-1 };\n"; + const std::vector &SubGroups = I->second.SubGroups; + if (!SubGroups.empty()) { + OS << "static const char DiagSubGroup" << I->second.IDNo << "[] = { "; + for (unsigned i = 0, e = SubGroups.size(); i != e; ++i) { + std::map::iterator RI = + DiagsInGroup.find(SubGroups[i]); + assert(RI != DiagsInGroup.end() && "Referenced without existing?"); + OS << RI->second.IDNo << ", "; + } + OS << "-1 };\n"; + } } OS << "#endif // GET_DIAG_ARRAYS\n\n"; // Emit the table now. OS << "\n#ifdef GET_DIAG_TABLE\n"; - IDNo = 0; for (std::map::iterator I = DiagsInGroup.begin(), E = DiagsInGroup.end(); I != E; ++I) { std::string S = I->first; @@ -128,10 +144,13 @@ if (I->second.DiagsInGroup.empty()) OS << "0, "; else - OS << "DiagArray" << IDNo++ << ", "; + OS << "DiagArray" << I->second.IDNo << ", "; - // FIXME: Subgroups. - OS << 0; + // Subgroups. + if (I->second.SubGroups.empty()) + OS << 0; + else + OS << "DiagSubGroup" << I->second.IDNo; OS << " },\n"; } OS << "#endif // GET_DIAG_TABLE\n\n"; From gohman at apple.com Wed Apr 15 22:18:22 2009 From: gohman at apple.com (Dan Gohman) Date: Thu, 16 Apr 2009 03:18:22 -0000 Subject: [llvm-commits] [llvm] r69258 - in /llvm/trunk: include/llvm/Analysis/ScalarEvolution.h include/llvm/Analysis/ScalarEvolutionExpander.h lib/Analysis/ScalarEvolution.cpp lib/Analysis/ScalarEvolutionExpander.cpp lib/Transforms/Scalar/IndVarSimplify.cpp lib/Transforms/Scalar/LoopStrengthReduce.cpp test/CodeGen/ARM/2007-03-13-InstrSched.ll test/CodeGen/X86/iv-users-in-other-loops.ll test/CodeGen/X86/pr3495.ll test/CodeGen/X86/stride-nine-with-base-reg.ll Message-ID: <200904160318.n3G3INnx022121@zion.cs.uiuc.edu> Author: djg Date: Wed Apr 15 22:18:22 2009 New Revision: 69258 URL: http://llvm.org/viewvc/llvm-project?rev=69258&view=rev Log: Expand GEPs in ScalarEvolution expressions. SCEV expressions can now have pointer types, though in contrast to C pointer types, SCEV addition is never implicitly scaled. This not only eliminates the need for special code like IndVars' EliminatePointerRecurrence and LSR's own GEP expansion code, it also does a better job because it lets the normal optimizations handle pointer expressions just like integer expressions. Also, since LLVM IR GEPs can't directly index into multi-dimensional VLAs, moving the GEP analysis out of client code and into the SCEV framework makes it easier for clients to handle multi-dimensional VLAs the same way as other arrays. Some existing regression tests show improved optimization. test/CodeGen/ARM/2007-03-13-InstrSched.ll in particular improved to the point where if-conversion started kicking in; I turned it off for this test to preserve the intent of the test. Modified: llvm/trunk/include/llvm/Analysis/ScalarEvolution.h llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpander.h llvm/trunk/lib/Analysis/ScalarEvolution.cpp llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp llvm/trunk/test/CodeGen/ARM/2007-03-13-InstrSched.ll llvm/trunk/test/CodeGen/X86/iv-users-in-other-loops.ll llvm/trunk/test/CodeGen/X86/pr3495.ll llvm/trunk/test/CodeGen/X86/stride-nine-with-base-reg.ll Modified: llvm/trunk/include/llvm/Analysis/ScalarEvolution.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ScalarEvolution.h?rev=69258&r1=69257&r2=69258&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/ScalarEvolution.h (original) +++ llvm/trunk/include/llvm/Analysis/ScalarEvolution.h Wed Apr 15 22:18:22 2009 @@ -32,6 +32,7 @@ class Type; class SCEVHandle; class ScalarEvolution; + class TargetData; /// SCEV - This class represent an analyzed expression in the program. These /// are reference counted opaque objects that the client is not allowed to @@ -71,10 +72,6 @@ /// virtual const Type *getType() const = 0; - /// getBitWidth - Get the bit width of the type, if it has one, 0 otherwise. - /// - uint32_t getBitWidth() const; - /// isZero - Return true if the expression is a constant zero. /// bool isZero() const; @@ -199,6 +196,10 @@ static char ID; // Pass identification, replacement for typeid ScalarEvolution() : FunctionPass(&ID), Impl(0) {} + // getTargetData - Return the TargetData object contained in this + // ScalarEvolution. + const TargetData &getTargetData() const; + /// getSCEV - Return a SCEV expression handle for the full generality of the /// specified expression. SCEVHandle getSCEV(Value *V) const; Modified: llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpander.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpander.h?rev=69258&r1=69257&r2=69258&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpander.h (original) +++ llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpander.h Wed Apr 15 22:18:22 2009 @@ -20,6 +20,8 @@ #include "llvm/Analysis/ScalarEvolutionExpressions.h" namespace llvm { + class TargetData; + /// SCEVExpander - This class uses information about analyze scalars to /// rewrite expressions in canonical form. /// @@ -29,6 +31,7 @@ struct SCEVExpander : public SCEVVisitor { ScalarEvolution &SE; LoopInfo &LI; + const TargetData &TD; std::map InsertedExpressions; std::set InsertedInstructions; @@ -36,7 +39,8 @@ friend struct SCEVVisitor; public: - SCEVExpander(ScalarEvolution &se, LoopInfo &li) : SE(se), LI(li) {} + SCEVExpander(ScalarEvolution &se, LoopInfo &li, const TargetData &td) + : SE(se), LI(li), TD(td) {} LoopInfo &getLoopInfo() const { return LI; } @@ -75,7 +79,7 @@ /// expandCodeFor - Insert code to directly compute the specified SCEV /// expression into the program. The inserted code is inserted into the /// specified block. - Value *expandCodeFor(SCEVHandle SH, Instruction *IP); + Value *expandCodeFor(SCEVHandle SH, const Type *Ty, Instruction *IP); /// InsertCastOfTo - Insert a cast of V to the specified type, doing what /// we can to share the casts. @@ -87,7 +91,7 @@ Value *RHS, Instruction *InsertPt); protected: Value *expand(SCEV *S); - + Value *visitConstant(SCEVConstant *S) { return S->getValue(); } Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=69258&r1=69257&r2=69258&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original) +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Wed Apr 15 22:18:22 2009 @@ -69,16 +69,19 @@ #include "llvm/Analysis/Dominators.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/Assembly/Writer.h" +#include "llvm/Target/TargetData.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Support/CFG.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/ConstantRange.h" +#include "llvm/Support/GetElementPtrTypeIterator.h" #include "llvm/Support/InstIterator.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/Streams.h" #include "llvm/ADT/Statistic.h" +#include "llvm/ADT/STLExtras.h" #include #include #include @@ -116,12 +119,6 @@ cerr << '\n'; } -uint32_t SCEV::getBitWidth() const { - if (const IntegerType* ITy = dyn_cast(getType())) - return ITy->getBitWidth(); - return 0; -} - bool SCEV::isZero() const { if (const SCEVConstant *SC = dyn_cast(this)) return SC->getValue()->isZero(); @@ -196,10 +193,13 @@ SCEVTruncateExpr::SCEVTruncateExpr(const SCEVHandle &op, const Type *ty) : SCEV(scTruncate), Op(op), Ty(ty) { - assert(Op->getType()->isInteger() && Ty->isInteger() && + assert((Op->getType()->isInteger() || isa(Op->getType())) && + (Ty->isInteger() || isa(Ty)) && "Cannot truncate non-integer value!"); - assert(Op->getType()->getPrimitiveSizeInBits() > Ty->getPrimitiveSizeInBits() - && "This is not a truncating conversion!"); + assert((!Op->getType()->isInteger() || !Ty->isInteger() || + Op->getType()->getPrimitiveSizeInBits() > + Ty->getPrimitiveSizeInBits()) && + "This is not a truncating conversion!"); } SCEVTruncateExpr::~SCEVTruncateExpr() { @@ -222,7 +222,8 @@ SCEVZeroExtendExpr::SCEVZeroExtendExpr(const SCEVHandle &op, const Type *ty) : SCEV(scZeroExtend), Op(op), Ty(ty) { - assert(Op->getType()->isInteger() && Ty->isInteger() && + assert((Op->getType()->isInteger() || isa(Op->getType())) && + (Ty->isInteger() || isa(Ty)) && "Cannot zero extend non-integer value!"); assert(Op->getType()->getPrimitiveSizeInBits() < Ty->getPrimitiveSizeInBits() && "This is not an extending conversion!"); @@ -248,7 +249,8 @@ SCEVSignExtendExpr::SCEVSignExtendExpr(const SCEVHandle &op, const Type *ty) : SCEV(scSignExtend), Op(op), Ty(ty) { - assert(Op->getType()->isInteger() && Ty->isInteger() && + assert((Op->getType()->isInteger() || isa(Op->getType())) && + (Ty->isInteger() || isa(Ty)) && "Cannot sign extend non-integer value!"); assert(Op->getType()->getPrimitiveSizeInBits() < Ty->getPrimitiveSizeInBits() && "This is not an extending conversion!"); @@ -436,7 +438,11 @@ } void SCEVUnknown::print(std::ostream &OS) const { + if (isa(V->getType())) + OS << "(ptrtoint " << *V->getType() << " "; WriteAsOperand(OS, V, false); + if (isa(V->getType())) + OS << " to iPTR)"; } //===----------------------------------------------------------------------===// @@ -504,52 +510,11 @@ // Simple SCEV method implementations //===----------------------------------------------------------------------===// -/// getIntegerSCEV - Given an integer or FP type, create a constant for the -/// specified signed integer value and return a SCEV for the constant. -SCEVHandle ScalarEvolution::getIntegerSCEV(int Val, const Type *Ty) { - Constant *C; - if (Val == 0) - C = Constant::getNullValue(Ty); - else if (Ty->isFloatingPoint()) - C = ConstantFP::get(APFloat(Ty==Type::FloatTy ? APFloat::IEEEsingle : - APFloat::IEEEdouble, Val)); - else - C = ConstantInt::get(Ty, Val); - return getUnknown(C); -} - -/// getNegativeSCEV - Return a SCEV corresponding to -V = -1*V -/// -SCEVHandle ScalarEvolution::getNegativeSCEV(const SCEVHandle &V) { - if (SCEVConstant *VC = dyn_cast(V)) - return getUnknown(ConstantExpr::getNeg(VC->getValue())); - - return getMulExpr(V, getConstant(ConstantInt::getAllOnesValue(V->getType()))); -} - -/// getNotSCEV - Return a SCEV corresponding to ~V = -1-V -SCEVHandle ScalarEvolution::getNotSCEV(const SCEVHandle &V) { - if (SCEVConstant *VC = dyn_cast(V)) - return getUnknown(ConstantExpr::getNot(VC->getValue())); - - SCEVHandle AllOnes = getConstant(ConstantInt::getAllOnesValue(V->getType())); - return getMinusSCEV(AllOnes, V); -} - -/// getMinusSCEV - Return a SCEV corresponding to LHS - RHS. -/// -SCEVHandle ScalarEvolution::getMinusSCEV(const SCEVHandle &LHS, - const SCEVHandle &RHS) { - // X - Y --> X + -Y - return getAddExpr(LHS, getNegativeSCEV(RHS)); -} - - /// BinomialCoefficient - Compute BC(It, K). The result has width W. // Assume, K > 0. static SCEVHandle BinomialCoefficient(SCEVHandle It, unsigned K, ScalarEvolution &SE, - const IntegerType* ResultTy) { + const Type* ResultTy) { // Handle the simplest case efficiently. if (K == 1) return SE.getTruncateOrZeroExtend(It, ResultTy); @@ -608,7 +573,7 @@ if (K > 1000) return new SCEVCouldNotCompute(); - unsigned W = ResultTy->getBitWidth(); + unsigned W = SE.getTargetData().getTypeSizeInBits(ResultTy); // Calculate K! / 2^T and T; we divide out the factors of two before // multiplying for calculating K! / 2^T to avoid overflow. @@ -672,8 +637,7 @@ // The computation is correct in the face of overflow provided that the // multiplication is performed _after_ the evaluation of the binomial // coefficient. - SCEVHandle Coeff = BinomialCoefficient(It, i, SE, - cast(getType())); + SCEVHandle Coeff = BinomialCoefficient(It, i, SE, getType()); if (isa(Coeff)) return Coeff; @@ -711,9 +675,13 @@ } SCEVHandle ScalarEvolution::getZeroExtendExpr(const SCEVHandle &Op, const Type *Ty) { - if (SCEVConstant *SC = dyn_cast(Op)) - return getUnknown( - ConstantExpr::getZExt(SC->getValue(), Ty)); + if (SCEVConstant *SC = dyn_cast(Op)) { + const Type *IntTy = Ty; + if (isa(IntTy)) IntTy = getTargetData().getIntPtrType(); + Constant *C = ConstantExpr::getZExt(SC->getValue(), IntTy); + if (IntTy != Ty) C = ConstantExpr::getIntToPtr(C, Ty); + return getUnknown(C); + } // FIXME: If the input value is a chrec scev, and we can prove that the value // did not overflow the old, smaller, value, we can zero extend all of the @@ -726,9 +694,13 @@ } SCEVHandle ScalarEvolution::getSignExtendExpr(const SCEVHandle &Op, const Type *Ty) { - if (SCEVConstant *SC = dyn_cast(Op)) - return getUnknown( - ConstantExpr::getSExt(SC->getValue(), Ty)); + if (SCEVConstant *SC = dyn_cast(Op)) { + const Type *IntTy = Ty; + if (isa(IntTy)) IntTy = getTargetData().getIntPtrType(); + Constant *C = ConstantExpr::getSExt(SC->getValue(), IntTy); + if (IntTy != Ty) C = ConstantExpr::getIntToPtr(C, Ty); + return getUnknown(C); + } // FIXME: If the input value is a chrec scev, and we can prove that the value // did not overflow the old, smaller, value, we can sign extend all of the @@ -740,36 +712,6 @@ return Result; } -/// getTruncateOrZeroExtend - Return a SCEV corresponding to a conversion -/// of the input value to the specified type. If the type must be -/// extended, it is zero extended. -SCEVHandle ScalarEvolution::getTruncateOrZeroExtend(const SCEVHandle &V, - const Type *Ty) { - const Type *SrcTy = V->getType(); - assert(SrcTy->isInteger() && Ty->isInteger() && - "Cannot truncate or zero extend with non-integer arguments!"); - if (SrcTy->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits()) - return V; // No conversion - if (SrcTy->getPrimitiveSizeInBits() > Ty->getPrimitiveSizeInBits()) - return getTruncateExpr(V, Ty); - return getZeroExtendExpr(V, Ty); -} - -/// getTruncateOrSignExtend - Return a SCEV corresponding to a conversion -/// of the input value to the specified type. If the type must be -/// extended, it is sign extended. -SCEVHandle ScalarEvolution::getTruncateOrSignExtend(const SCEVHandle &V, - const Type *Ty) { - const Type *SrcTy = V->getType(); - assert(SrcTy->isInteger() && Ty->isInteger() && - "Cannot truncate or sign extend with non-integer arguments!"); - if (SrcTy->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits()) - return V; // No conversion - if (SrcTy->getPrimitiveSizeInBits() > Ty->getPrimitiveSizeInBits()) - return getTruncateExpr(V, Ty); - return getSignExtendExpr(V, Ty); -} - // get - Get a canonical add expression, or something simpler if possible. SCEVHandle ScalarEvolution::getAddExpr(std::vector &Ops) { assert(!Ops.empty() && "Cannot get empty add!"); @@ -1385,6 +1327,8 @@ SCEVHandle ScalarEvolution::getUnknown(Value *V) { if (ConstantInt *CI = dyn_cast(V)) return getConstant(CI); + if (isa(V)) + return getIntegerSCEV(0, V->getType()); SCEVUnknown *&Result = (*SCEVUnknowns)[V]; if (Result == 0) Result = new SCEVUnknown(V); return Result; @@ -1411,6 +1355,10 @@ /// LoopInfo &LI; + /// TD - The target data information for the target we are targetting. + /// + TargetData &TD; + /// UnknownValue - This SCEV is used to represent unknown trip counts and /// things. SCEVHandle UnknownValue; @@ -1431,8 +1379,35 @@ std::map ConstantEvolutionLoopExitValue; public: - ScalarEvolutionsImpl(ScalarEvolution &se, Function &f, LoopInfo &li) - : SE(se), F(f), LI(li), UnknownValue(new SCEVCouldNotCompute()) {} + ScalarEvolutionsImpl(ScalarEvolution &se, Function &f, LoopInfo &li, + TargetData &td) + : SE(se), F(f), LI(li), TD(td), UnknownValue(new SCEVCouldNotCompute()) {} + + /// getIntegerSCEV - Given an integer or FP type, create a constant for the + /// specified signed integer value and return a SCEV for the constant. + SCEVHandle getIntegerSCEV(int Val, const Type *Ty); + + /// getNegativeSCEV - Return a SCEV corresponding to -V = -1*V + /// + SCEVHandle getNegativeSCEV(const SCEVHandle &V); + + /// getNotSCEV - Return a SCEV corresponding to ~V = -1-V + /// + SCEVHandle getNotSCEV(const SCEVHandle &V); + + /// getMinusSCEV - Return a SCEV corresponding to LHS - RHS. + /// + SCEVHandle getMinusSCEV(const SCEVHandle &LHS, const SCEVHandle &RHS); + + /// getTruncateOrZeroExtend - Return a SCEV corresponding to a conversion + /// of the input value to the specified type. If the type must be extended, + /// it is zero extended. + SCEVHandle getTruncateOrZeroExtend(const SCEVHandle &V, const Type *Ty); + + /// getTruncateOrSignExtend - Return a SCEV corresponding to a conversion + /// of the input value to the specified type. If the type must be extended, + /// it is sign extended. + SCEVHandle getTruncateOrSignExtend(const SCEVHandle &V, const Type *Ty); /// getSCEV - Return an existing SCEV if it exists, otherwise analyze the /// expression and create a new one. @@ -1492,6 +1467,9 @@ /// that no dangling references are left around. void deleteValueFromRecords(Value *V); + /// getTargetData - Return the TargetData. + const TargetData &getTargetData() const; + private: /// createSCEV - We know that there is no SCEV for the specified value. /// Analyze the expression. @@ -1592,6 +1570,9 @@ } } +const TargetData &ScalarEvolutionsImpl::getTargetData() const { + return TD; +} /// getSCEV - Return an existing SCEV if it exists, otherwise analyze the /// expression and create a new one. @@ -1605,6 +1586,88 @@ return S; } +/// getIntegerSCEV - Given an integer or FP type, create a constant for the +/// specified signed integer value and return a SCEV for the constant. +SCEVHandle ScalarEvolutionsImpl::getIntegerSCEV(int Val, const Type *Ty) { + if (isa(Ty)) + Ty = TD.getIntPtrType(); + Constant *C; + if (Val == 0) + C = Constant::getNullValue(Ty); + else if (Ty->isFloatingPoint()) + C = ConstantFP::get(APFloat(Ty==Type::FloatTy ? APFloat::IEEEsingle : + APFloat::IEEEdouble, Val)); + else + C = ConstantInt::get(Ty, Val); + return SE.getUnknown(C); +} + +/// getNegativeSCEV - Return a SCEV corresponding to -V = -1*V +/// +SCEVHandle ScalarEvolutionsImpl::getNegativeSCEV(const SCEVHandle &V) { + if (SCEVConstant *VC = dyn_cast(V)) + return SE.getUnknown(ConstantExpr::getNeg(VC->getValue())); + + const Type *Ty = V->getType(); + if (isa(Ty)) + Ty = TD.getIntPtrType(); + return SE.getMulExpr(V, SE.getConstant(ConstantInt::getAllOnesValue(Ty))); +} + +/// getNotSCEV - Return a SCEV corresponding to ~V = -1-V +SCEVHandle ScalarEvolutionsImpl::getNotSCEV(const SCEVHandle &V) { + if (SCEVConstant *VC = dyn_cast(V)) + return SE.getUnknown(ConstantExpr::getNot(VC->getValue())); + + const Type *Ty = V->getType(); + if (isa(Ty)) + Ty = TD.getIntPtrType(); + SCEVHandle AllOnes = SE.getConstant(ConstantInt::getAllOnesValue(Ty)); + return getMinusSCEV(AllOnes, V); +} + +/// getMinusSCEV - Return a SCEV corresponding to LHS - RHS. +/// +SCEVHandle ScalarEvolutionsImpl::getMinusSCEV(const SCEVHandle &LHS, + const SCEVHandle &RHS) { + // X - Y --> X + -Y + return SE.getAddExpr(LHS, SE.getNegativeSCEV(RHS)); +} + +/// getTruncateOrZeroExtend - Return a SCEV corresponding to a conversion of the +/// input value to the specified type. If the type must be extended, it is zero +/// extended. +SCEVHandle +ScalarEvolutionsImpl::getTruncateOrZeroExtend(const SCEVHandle &V, + const Type *Ty) { + const Type *SrcTy = V->getType(); + assert((SrcTy->isInteger() || isa(SrcTy)) && + (Ty->isInteger() || isa(Ty)) && + "Cannot truncate or zero extend with non-integer arguments!"); + if (TD.getTypeSizeInBits(SrcTy) == TD.getTypeSizeInBits(Ty)) + return V; // No conversion + if (TD.getTypeSizeInBits(SrcTy) > TD.getTypeSizeInBits(Ty)) + return SE.getTruncateExpr(V, Ty); + return SE.getZeroExtendExpr(V, Ty); +} + +/// getTruncateOrSignExtend - Return a SCEV corresponding to a conversion of the +/// input value to the specified type. If the type must be extended, it is sign +/// extended. +SCEVHandle +ScalarEvolutionsImpl::getTruncateOrSignExtend(const SCEVHandle &V, + const Type *Ty) { + const Type *SrcTy = V->getType(); + assert((SrcTy->isInteger() || isa(SrcTy)) && + (Ty->isInteger() || isa(Ty)) && + "Cannot truncate or zero extend with non-integer arguments!"); + if (TD.getTypeSizeInBits(SrcTy) == TD.getTypeSizeInBits(Ty)) + return V; // No conversion + if (TD.getTypeSizeInBits(SrcTy) > TD.getTypeSizeInBits(Ty)) + return SE.getTruncateExpr(V, Ty); + return SE.getSignExtendExpr(V, Ty); +} + /// ReplaceSymbolicValueWithConcrete - This looks up the computed SCEV value for /// the specified instruction and replaces any references to the symbolic value /// SymName with the specified value. This is used during PHI resolution. @@ -1728,63 +1791,66 @@ /// guaranteed to end in (at every loop iteration). It is, at the same time, /// the minimum number of times S is divisible by 2. For example, given {4,+,8} /// it returns 2. If S is guaranteed to be 0, it returns the bitwidth of S. -static uint32_t GetMinTrailingZeros(SCEVHandle S) { +static uint32_t GetMinTrailingZeros(SCEVHandle S, const TargetData &TD) { if (SCEVConstant *C = dyn_cast(S)) return C->getValue()->getValue().countTrailingZeros(); if (SCEVTruncateExpr *T = dyn_cast(S)) - return std::min(GetMinTrailingZeros(T->getOperand()), T->getBitWidth()); + return std::min(GetMinTrailingZeros(T->getOperand(), TD), + (uint32_t)TD.getTypeSizeInBits(T->getType())); if (SCEVZeroExtendExpr *E = dyn_cast(S)) { - uint32_t OpRes = GetMinTrailingZeros(E->getOperand()); - return OpRes == E->getOperand()->getBitWidth() ? E->getBitWidth() : OpRes; + uint32_t OpRes = GetMinTrailingZeros(E->getOperand(), TD); + return OpRes == TD.getTypeSizeInBits(E->getOperand()->getType()) ? + TD.getTypeSizeInBits(E->getOperand()->getType()) : OpRes; } if (SCEVSignExtendExpr *E = dyn_cast(S)) { - uint32_t OpRes = GetMinTrailingZeros(E->getOperand()); - return OpRes == E->getOperand()->getBitWidth() ? E->getBitWidth() : OpRes; + uint32_t OpRes = GetMinTrailingZeros(E->getOperand(), TD); + return OpRes == TD.getTypeSizeInBits(E->getOperand()->getType()) ? + TD.getTypeSizeInBits(E->getOperand()->getType()) : OpRes; } if (SCEVAddExpr *A = dyn_cast(S)) { // The result is the min of all operands results. - uint32_t MinOpRes = GetMinTrailingZeros(A->getOperand(0)); + uint32_t MinOpRes = GetMinTrailingZeros(A->getOperand(0), TD); for (unsigned i = 1, e = A->getNumOperands(); MinOpRes && i != e; ++i) - MinOpRes = std::min(MinOpRes, GetMinTrailingZeros(A->getOperand(i))); + MinOpRes = std::min(MinOpRes, GetMinTrailingZeros(A->getOperand(i), TD)); return MinOpRes; } if (SCEVMulExpr *M = dyn_cast(S)) { // The result is the sum of all operands results. - uint32_t SumOpRes = GetMinTrailingZeros(M->getOperand(0)); - uint32_t BitWidth = M->getBitWidth(); + uint32_t SumOpRes = GetMinTrailingZeros(M->getOperand(0), TD); + uint32_t BitWidth = TD.getTypeSizeInBits(M->getType()); for (unsigned i = 1, e = M->getNumOperands(); SumOpRes != BitWidth && i != e; ++i) - SumOpRes = std::min(SumOpRes + GetMinTrailingZeros(M->getOperand(i)), + SumOpRes = std::min(SumOpRes + GetMinTrailingZeros(M->getOperand(i), TD), BitWidth); return SumOpRes; } if (SCEVAddRecExpr *A = dyn_cast(S)) { // The result is the min of all operands results. - uint32_t MinOpRes = GetMinTrailingZeros(A->getOperand(0)); + uint32_t MinOpRes = GetMinTrailingZeros(A->getOperand(0), TD); for (unsigned i = 1, e = A->getNumOperands(); MinOpRes && i != e; ++i) - MinOpRes = std::min(MinOpRes, GetMinTrailingZeros(A->getOperand(i))); + MinOpRes = std::min(MinOpRes, GetMinTrailingZeros(A->getOperand(i), TD)); return MinOpRes; } if (SCEVSMaxExpr *M = dyn_cast(S)) { // The result is the min of all operands results. - uint32_t MinOpRes = GetMinTrailingZeros(M->getOperand(0)); + uint32_t MinOpRes = GetMinTrailingZeros(M->getOperand(0), TD); for (unsigned i = 1, e = M->getNumOperands(); MinOpRes && i != e; ++i) - MinOpRes = std::min(MinOpRes, GetMinTrailingZeros(M->getOperand(i))); + MinOpRes = std::min(MinOpRes, GetMinTrailingZeros(M->getOperand(i), TD)); return MinOpRes; } if (SCEVUMaxExpr *M = dyn_cast(S)) { // The result is the min of all operands results. - uint32_t MinOpRes = GetMinTrailingZeros(M->getOperand(0)); + uint32_t MinOpRes = GetMinTrailingZeros(M->getOperand(0), TD); for (unsigned i = 1, e = M->getNumOperands(); MinOpRes && i != e; ++i) - MinOpRes = std::min(MinOpRes, GetMinTrailingZeros(M->getOperand(i))); + MinOpRes = std::min(MinOpRes, GetMinTrailingZeros(M->getOperand(i), TD)); return MinOpRes; } @@ -1796,9 +1862,10 @@ /// Analyze the expression. /// SCEVHandle ScalarEvolutionsImpl::createSCEV(Value *V) { - if (!isa(V->getType())) + if (!isa(V->getType()) && + !isa(V->getType())) return SE.getUnknown(V); - + unsigned Opcode = Instruction::UserOp1; if (Instruction *I = dyn_cast(V)) Opcode = I->getOpcode(); @@ -1831,7 +1898,7 @@ if (ConstantInt *CI = dyn_cast(U->getOperand(1))) { SCEVHandle LHS = getSCEV(U->getOperand(0)); const APInt &CIVal = CI->getValue(); - if (GetMinTrailingZeros(LHS) >= + if (GetMinTrailingZeros(LHS, TD) >= (CIVal.getBitWidth() - CIVal.countLeadingZeros())) return SE.getAddExpr(LHS, getSCEV(U->getOperand(1))); } @@ -1881,11 +1948,55 @@ case Instruction::BitCast: // BitCasts are no-op casts so we just eliminate the cast. - if (U->getType()->isInteger() && - U->getOperand(0)->getType()->isInteger()) + if ((U->getType()->isInteger() || + isa(U->getType())) && + (U->getOperand(0)->getType()->isInteger() || + isa(U->getOperand(0)->getType()))) return getSCEV(U->getOperand(0)); break; + case Instruction::IntToPtr: + return getTruncateOrZeroExtend(getSCEV(U->getOperand(0)), + TD.getIntPtrType()); + + case Instruction::PtrToInt: + return getTruncateOrZeroExtend(getSCEV(U->getOperand(0)), + U->getType()); + + case Instruction::GetElementPtr: { + const Type *IntPtrTy = TD.getIntPtrType(); + Value *Base = U->getOperand(0); + SCEVHandle TotalOffset = SE.getIntegerSCEV(0, IntPtrTy); + gep_type_iterator GTI = gep_type_begin(U); + for (GetElementPtrInst::op_iterator I = next(U->op_begin()), + E = U->op_end(); + I != E; ++I) { + Value *Index = *I; + // Compute the (potentially symbolic) offset in bytes for this index. + if (const StructType *STy = dyn_cast(*GTI++)) { + // For a struct, add the member offset. + const StructLayout &SL = *TD.getStructLayout(STy); + unsigned FieldNo = cast(Index)->getZExtValue(); + uint64_t Offset = SL.getElementOffset(FieldNo); + TotalOffset = SE.getAddExpr(TotalOffset, + SE.getIntegerSCEV(Offset, IntPtrTy)); + } else { + // For an array, add the element offset, explicitly scaled. + SCEVHandle LocalOffset = getSCEV(Index); + if (!isa(LocalOffset->getType())) + // Getelementptr indicies are signed. + LocalOffset = getTruncateOrSignExtend(LocalOffset, + IntPtrTy); + LocalOffset = + SE.getMulExpr(LocalOffset, + SE.getIntegerSCEV(TD.getTypePaddedSize(*GTI), + IntPtrTy)); + TotalOffset = SE.getAddExpr(TotalOffset, LocalOffset); + } + } + return SE.getAddExpr(getSCEV(Base), TotalOffset); + } + case Instruction::PHI: return createNodeForPHI(cast(U)); @@ -2324,6 +2435,7 @@ static Constant *EvaluateExpression(Value *V, Constant *PHIVal) { if (isa(V)) return PHIVal; if (Constant *C = dyn_cast(V)) return C; + if (GlobalValue *GV = dyn_cast(V)) return GV; Instruction *I = cast(V); std::vector Operands; @@ -2490,10 +2602,12 @@ Operands.push_back(C); } else { // If any of the operands is non-constant and if they are - // non-integer, don't even try to analyze them with scev techniques. - if (!isa(Op->getType())) + // non-integer and non-pointer, don't even try to analyze them + // with scev techniques. + if (!isa(Op->getType()) && + !isa(Op->getType())) return V; - + SCEVHandle OpV = getSCEVAtScope(getSCEV(Op), L); if (SCEVConstant *SC = dyn_cast(OpV)) Operands.push_back(ConstantExpr::getIntegerCast(SC->getValue(), @@ -3003,7 +3117,8 @@ // First check to see if the range contains zero. If not, the first // iteration exits. - if (!Range.contains(APInt(getBitWidth(),0))) + unsigned BitWidth = SE.getTargetData().getTypeSizeInBits(getType()); + if (!Range.contains(APInt(BitWidth, 0))) return SE.getConstant(ConstantInt::get(getType(),0)); if (isAffine()) { @@ -3014,7 +3129,7 @@ // the upper value of the range must be the first possible exit value. // If A is negative then the lower of the range is the last possible loop // value. Also note that we already checked for a full range. - APInt One(getBitWidth(),1); + APInt One(BitWidth,1); APInt A = cast(getOperand(1))->getValue()->getValue(); APInt End = A.sge(One) ? (Range.getUpper() - One) : Range.getLower(); @@ -3094,7 +3209,9 @@ //===----------------------------------------------------------------------===// bool ScalarEvolution::runOnFunction(Function &F) { - Impl = new ScalarEvolutionsImpl(*this, F, getAnalysis()); + Impl = new ScalarEvolutionsImpl(*this, F, + getAnalysis(), + getAnalysis()); return false; } @@ -3106,6 +3223,15 @@ void ScalarEvolution::getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); AU.addRequiredTransitive(); + AU.addRequiredTransitive(); +} + +const TargetData &ScalarEvolution::getTargetData() const { + return ((ScalarEvolutionsImpl*)Impl)->getTargetData(); +} + +SCEVHandle ScalarEvolution::getIntegerSCEV(int Val, const Type *Ty) { + return ((ScalarEvolutionsImpl*)Impl)->getIntegerSCEV(Val, Ty); } SCEVHandle ScalarEvolution::getSCEV(Value *V) const { @@ -3125,6 +3251,41 @@ ((ScalarEvolutionsImpl*)Impl)->setSCEV(V, H); } +/// getNegativeSCEV - Return a SCEV corresponding to -V = -1*V +/// +SCEVHandle ScalarEvolution::getNegativeSCEV(const SCEVHandle &V) { + return ((ScalarEvolutionsImpl*)Impl)->getNegativeSCEV(V); +} + +/// getNotSCEV - Return a SCEV corresponding to ~V = -1-V +/// +SCEVHandle ScalarEvolution::getNotSCEV(const SCEVHandle &V) { + return ((ScalarEvolutionsImpl*)Impl)->getNotSCEV(V); +} + +/// getMinusSCEV - Return a SCEV corresponding to LHS - RHS. +/// +SCEVHandle ScalarEvolution::getMinusSCEV(const SCEVHandle &LHS, + const SCEVHandle &RHS) { + return ((ScalarEvolutionsImpl*)Impl)->getMinusSCEV(LHS, RHS); +} + +/// getTruncateOrZeroExtend - Return a SCEV corresponding to a conversion +/// of the input value to the specified type. If the type must be +/// extended, it is zero extended. +SCEVHandle ScalarEvolution::getTruncateOrZeroExtend(const SCEVHandle &V, + const Type *Ty) { + return ((ScalarEvolutionsImpl*)Impl)->getTruncateOrZeroExtend(V, Ty); +} + +/// getTruncateOrSignExtend - Return a SCEV corresponding to a conversion +/// of the input value to the specified type. If the type must be +/// extended, it is sign extended. +SCEVHandle ScalarEvolution::getTruncateOrSignExtend(const SCEVHandle &V, + const Type *Ty) { + return ((ScalarEvolutionsImpl*)Impl)->getTruncateOrSignExtend(V, Ty); +} + bool ScalarEvolution::isLoopGuardedByCond(const Loop *L, ICmpInst::Predicate Pred, Modified: llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp?rev=69258&r1=69257&r2=69258&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp (original) +++ llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp Wed Apr 15 22:18:22 2009 @@ -15,12 +15,17 @@ #include "llvm/Analysis/ScalarEvolutionExpander.h" #include "llvm/Analysis/LoopInfo.h" +#include "llvm/Target/TargetData.h" using namespace llvm; /// InsertCastOfTo - Insert a cast of V to the specified type, doing what /// we can to share the casts. Value *SCEVExpander::InsertCastOfTo(Instruction::CastOps opcode, Value *V, const Type *Ty) { + // Short-circuit unnecessary bitcasts. + if (opcode == Instruction::BitCast && V->getType() == Ty) + return V; + // FIXME: keep track of the cast instruction. if (Constant *C = dyn_cast(V)) return ConstantExpr::getCast(opcode, C, Ty); @@ -100,16 +105,23 @@ } Value *SCEVExpander::visitAddExpr(SCEVAddExpr *S) { + const Type *Ty = S->getType(); + if (isa(Ty)) Ty = TD.getIntPtrType(); Value *V = expand(S->getOperand(S->getNumOperands()-1)); + V = InsertCastOfTo(CastInst::getCastOpcode(V, false, Ty, false), V, Ty); // Emit a bunch of add instructions - for (int i = S->getNumOperands()-2; i >= 0; --i) - V = InsertBinop(Instruction::Add, V, expand(S->getOperand(i)), - InsertPt); + for (int i = S->getNumOperands()-2; i >= 0; --i) { + Value *W = expand(S->getOperand(i)); + W = InsertCastOfTo(CastInst::getCastOpcode(W, false, Ty, false), W, Ty); + V = InsertBinop(Instruction::Add, V, W, InsertPt); + } return V; } Value *SCEVExpander::visitMulExpr(SCEVMulExpr *S) { + const Type *Ty = S->getType(); + if (isa(Ty)) Ty = TD.getIntPtrType(); int FirstOp = 0; // Set if we should emit a subtract. if (SCEVConstant *SC = dyn_cast(S->getOperand(0))) if (SC->getValue()->isAllOnesValue()) @@ -117,29 +129,37 @@ int i = S->getNumOperands()-2; Value *V = expand(S->getOperand(i+1)); + V = InsertCastOfTo(CastInst::getCastOpcode(V, false, Ty, false), V, Ty); // Emit a bunch of multiply instructions - for (; i >= FirstOp; --i) - V = InsertBinop(Instruction::Mul, V, expand(S->getOperand(i)), - InsertPt); + for (; i >= FirstOp; --i) { + Value *W = expand(S->getOperand(i)); + W = InsertCastOfTo(CastInst::getCastOpcode(W, false, Ty, false), W, Ty); + V = InsertBinop(Instruction::Mul, V, W, InsertPt); + } + // -1 * ... ---> 0 - ... if (FirstOp == 1) - V = InsertBinop(Instruction::Sub, Constant::getNullValue(V->getType()), V, - InsertPt); + V = InsertBinop(Instruction::Sub, Constant::getNullValue(Ty), V, InsertPt); return V; } Value *SCEVExpander::visitUDivExpr(SCEVUDivExpr *S) { + const Type *Ty = S->getType(); + if (isa(Ty)) Ty = TD.getIntPtrType(); + Value *LHS = expand(S->getLHS()); + LHS = InsertCastOfTo(CastInst::getCastOpcode(LHS, false, Ty, false), LHS, Ty); if (SCEVConstant *SC = dyn_cast(S->getRHS())) { const APInt &RHS = SC->getValue()->getValue(); if (RHS.isPowerOf2()) return InsertBinop(Instruction::LShr, LHS, - ConstantInt::get(S->getType(), RHS.logBase2()), + ConstantInt::get(Ty, RHS.logBase2()), InsertPt); } Value *RHS = expand(S->getRHS()); + RHS = InsertCastOfTo(CastInst::getCastOpcode(RHS, false, Ty, false), RHS, Ty); return InsertBinop(Instruction::UDiv, LHS, RHS, InsertPt); } @@ -147,14 +167,19 @@ const Type *Ty = S->getType(); const Loop *L = S->getLoop(); // We cannot yet do fp recurrences, e.g. the xform of {X,+,F} --> X+{0,+,F} - assert(Ty->isInteger() && "Cannot expand fp recurrences yet!"); + assert((Ty->isInteger() || isa(Ty)) && + "Cannot expand fp recurrences yet!"); // {X,+,F} --> X + {0,+,F} if (!S->getStart()->isZero()) { Value *Start = expand(S->getStart()); + if (isa(Start->getType())) + Start = InsertCastOfTo(Instruction::PtrToInt, Start, TD.getIntPtrType()); std::vector NewOps(S->op_begin(), S->op_end()); NewOps[0] = SE.getIntegerSCEV(0, Ty); Value *Rest = expand(SE.getAddRecExpr(NewOps, L)); + if (isa(Rest->getType())) + Rest = InsertCastOfTo(Instruction::PtrToInt, Rest, TD.getIntPtrType()); // FIXME: look for an existing add to use. return InsertBinop(Instruction::Add, Rest, Start, InsertPt); @@ -242,16 +267,22 @@ Value *SCEVExpander::visitTruncateExpr(SCEVTruncateExpr *S) { Value *V = expand(S->getOperand()); + if (isa(V->getType())) + V = InsertCastOfTo(Instruction::PtrToInt, V, TD.getIntPtrType()); return CastInst::CreateTruncOrBitCast(V, S->getType(), "tmp.", InsertPt); } Value *SCEVExpander::visitZeroExtendExpr(SCEVZeroExtendExpr *S) { Value *V = expand(S->getOperand()); + if (isa(V->getType())) + V = InsertCastOfTo(Instruction::PtrToInt, V, TD.getIntPtrType()); return CastInst::CreateZExtOrBitCast(V, S->getType(), "tmp.", InsertPt); } Value *SCEVExpander::visitSignExtendExpr(SCEVSignExtendExpr *S) { Value *V = expand(S->getOperand()); + if (isa(V->getType())) + V = InsertCastOfTo(Instruction::PtrToInt, V, TD.getIntPtrType()); return CastInst::CreateSExtOrBitCast(V, S->getType(), "tmp.", InsertPt); } @@ -275,10 +306,14 @@ return LHS; } -Value *SCEVExpander::expandCodeFor(SCEVHandle SH, Instruction *IP) { +Value *SCEVExpander::expandCodeFor(SCEVHandle SH, const Type *Ty, + Instruction *IP) { // Expand the code for this SCEV. + assert(TD.getTypeSizeInBits(Ty) == TD.getTypeSizeInBits(SH->getType()) && + "non-trivial casts should be done with the SCEVs directly!"); this->InsertPt = IP; - return expand(SH); + Value *V = expand(SH); + return InsertCastOfTo(CastInst::getCastOpcode(V, false, Ty, false), V, Ty); } Value *SCEVExpander::expand(SCEV *S) { Modified: llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp?rev=69258&r1=69257&r2=69258&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp Wed Apr 15 22:18:22 2009 @@ -50,6 +50,7 @@ #include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" #include "llvm/Support/GetElementPtrTypeIterator.h" +#include "llvm/Target/TargetData.h" #include "llvm/Transforms/Utils/Local.h" #include "llvm/Support/CommandLine.h" #include "llvm/ADT/SmallVector.h" @@ -59,7 +60,6 @@ using namespace llvm; STATISTIC(NumRemoved , "Number of aux indvars removed"); -STATISTIC(NumPointer , "Number of pointer indvars promoted"); STATISTIC(NumInserted, "Number of canonical indvars added"); STATISTIC(NumReplaced, "Number of exit values replaced"); STATISTIC(NumLFTR , "Number of loop exit tests replaced"); @@ -67,6 +67,7 @@ namespace { class VISIBILITY_HIDDEN IndVarSimplify : public LoopPass { LoopInfo *LI; + TargetData *TD; ScalarEvolution *SE; bool Changed; public: @@ -81,6 +82,7 @@ AU.addRequiredID(LCSSAID); AU.addRequiredID(LoopSimplifyID); AU.addRequired(); + AU.addRequired(); AU.addPreserved(); AU.addPreservedID(LoopSimplifyID); AU.addPreservedID(LCSSAID); @@ -91,8 +93,6 @@ void RewriteNonIntegerIVs(Loop *L); - void EliminatePointerRecurrence(PHINode *PN, BasicBlock *Preheader, - SmallPtrSet &DeadInsts); void LinearFunctionTestReplace(Loop *L, SCEVHandle BackedgeTakenCount, Value *IndVar, BasicBlock *ExitingBlock, @@ -135,97 +135,6 @@ } } - -/// EliminatePointerRecurrence - Check to see if this is a trivial GEP pointer -/// recurrence. If so, change it into an integer recurrence, permitting -/// analysis by the SCEV routines. -void IndVarSimplify::EliminatePointerRecurrence(PHINode *PN, - BasicBlock *Preheader, - SmallPtrSet &DeadInsts) { - assert(PN->getNumIncomingValues() == 2 && "Noncanonicalized loop!"); - unsigned PreheaderIdx = PN->getBasicBlockIndex(Preheader); - unsigned BackedgeIdx = PreheaderIdx^1; - if (GetElementPtrInst *GEPI = - dyn_cast(PN->getIncomingValue(BackedgeIdx))) - if (GEPI->getOperand(0) == PN) { - assert(GEPI->getNumOperands() == 2 && "GEP types must match!"); - DOUT << "INDVARS: Eliminating pointer recurrence: " << *GEPI; - - // Okay, we found a pointer recurrence. Transform this pointer - // recurrence into an integer recurrence. Compute the value that gets - // added to the pointer at every iteration. - Value *AddedVal = GEPI->getOperand(1); - - // Insert a new integer PHI node into the top of the block. - PHINode *NewPhi = PHINode::Create(AddedVal->getType(), - PN->getName()+".rec", PN); - NewPhi->addIncoming(Constant::getNullValue(NewPhi->getType()), Preheader); - - // Create the new add instruction. - Value *NewAdd = BinaryOperator::CreateAdd(NewPhi, AddedVal, - GEPI->getName()+".rec", GEPI); - NewPhi->addIncoming(NewAdd, PN->getIncomingBlock(BackedgeIdx)); - - // Update the existing GEP to use the recurrence. - GEPI->setOperand(0, PN->getIncomingValue(PreheaderIdx)); - - // Update the GEP to use the new recurrence we just inserted. - GEPI->setOperand(1, NewAdd); - - // If the incoming value is a constant expr GEP, try peeling out the array - // 0 index if possible to make things simpler. - if (ConstantExpr *CE = dyn_cast(GEPI->getOperand(0))) - if (CE->getOpcode() == Instruction::GetElementPtr) { - unsigned NumOps = CE->getNumOperands(); - assert(NumOps > 1 && "CE folding didn't work!"); - if (CE->getOperand(NumOps-1)->isNullValue()) { - // Check to make sure the last index really is an array index. - gep_type_iterator GTI = gep_type_begin(CE); - for (unsigned i = 1, e = CE->getNumOperands()-1; - i != e; ++i, ++GTI) - /*empty*/; - if (isa(*GTI)) { - // Pull the last index out of the constant expr GEP. - SmallVector CEIdxs(CE->op_begin()+1, CE->op_end()-1); - Constant *NCE = ConstantExpr::getGetElementPtr(CE->getOperand(0), - &CEIdxs[0], - CEIdxs.size()); - Value *Idx[2]; - Idx[0] = Constant::getNullValue(Type::Int32Ty); - Idx[1] = NewAdd; - GetElementPtrInst *NGEPI = GetElementPtrInst::Create( - NCE, Idx, Idx + 2, - GEPI->getName(), GEPI); - SE->deleteValueFromRecords(GEPI); - GEPI->replaceAllUsesWith(NGEPI); - GEPI->eraseFromParent(); - GEPI = NGEPI; - } - } - } - - - // Finally, if there are any other users of the PHI node, we must - // insert a new GEP instruction that uses the pre-incremented version - // of the induction amount. - if (!PN->use_empty()) { - BasicBlock::iterator InsertPos = PN; ++InsertPos; - while (isa(InsertPos)) ++InsertPos; - Value *PreInc = - GetElementPtrInst::Create(PN->getIncomingValue(PreheaderIdx), - NewPhi, "", InsertPos); - PreInc->takeName(PN); - PN->replaceAllUsesWith(PreInc); - } - - // Delete the old PHI for sure, and the GEP if its otherwise unused. - DeadInsts.insert(PN); - - ++NumPointer; - Changed = true; - } -} - /// LinearFunctionTestReplace - This method rewrites the exit condition of the /// loop to be a canonical != comparison against the incremented loop induction /// variable. This pass is able to rewrite the exit tests of any loop where the @@ -275,7 +184,7 @@ // Expand the code for the iteration count into the preheader of the loop. BasicBlock *Preheader = L->getLoopPreheader(); - Value *ExitCnt = Rewriter.expandCodeFor(RHS, + Value *ExitCnt = Rewriter.expandCodeFor(RHS, IndVar->getType(), Preheader->getTerminator()); // Insert a new icmp_ne or icmp_eq instruction before the branch. @@ -307,7 +216,7 @@ // Scan all of the instructions in the loop, looking at those that have // extra-loop users and which are recurrences. - SCEVExpander Rewriter(*SE, *LI); + SCEVExpander Rewriter(*SE, *LI, *TD); // We insert the code into the preheader of the loop if the loop contains // multiple exit blocks, or in the exit block if there is exactly one. @@ -349,7 +258,8 @@ Value *InVal = PN->getIncomingValue(i); if (!isa(InVal) || // SCEV only supports integer expressions for now. - !isa(InVal->getType())) + (!isa(InVal->getType()) && + !isa(InVal->getType()))) continue; // If this pred is for a subloop, not L itself, skip it. @@ -384,7 +294,7 @@ // just reuse it. Value *&ExitVal = ExitValues[Inst]; if (!ExitVal) - ExitVal = Rewriter.expandCodeFor(ExitValue, InsertPt); + ExitVal = Rewriter.expandCodeFor(ExitValue, PN->getType(), InsertPt); DOUT << "INDVARS: RLEV: AfterLoopVal = " << *ExitVal << " LoopVal = " << *Inst << "\n"; @@ -413,23 +323,19 @@ } void IndVarSimplify::RewriteNonIntegerIVs(Loop *L) { - // First step. Check to see if there are any trivial GEP pointer recurrences. + // First step. Check to see if there are any floating-point recurrences. // If there are, change them into integer recurrences, permitting analysis by // the SCEV routines. // BasicBlock *Header = L->getHeader(); - BasicBlock *Preheader = L->getLoopPreheader(); SmallPtrSet DeadInsts; for (BasicBlock::iterator I = Header->begin(); isa(I); ++I) { PHINode *PN = cast(I); - if (isa(PN->getType())) - EliminatePointerRecurrence(PN, Preheader, DeadInsts); - else - HandleFloatingPointIV(L, PN, DeadInsts); + HandleFloatingPointIV(L, PN, DeadInsts); } - // If the loop previously had a pointer or floating-point IV, ScalarEvolution + // If the loop previously had floating-point IV, ScalarEvolution // may not have been able to compute a trip count. Now that we've done some // re-writing, the trip count may be computable. if (Changed) @@ -442,7 +348,8 @@ /// getEffectiveIndvarType - Determine the widest type that the /// induction-variable PHINode Phi is cast to. /// -static const Type *getEffectiveIndvarType(const PHINode *Phi) { +static const Type *getEffectiveIndvarType(const PHINode *Phi, + const TargetData *TD) { const Type *Ty = Phi->getType(); for (Value::use_const_iterator UI = Phi->use_begin(), UE = Phi->use_end(); @@ -453,8 +360,7 @@ else if (const SExtInst *SI = dyn_cast(UI)) CandidateType = SI->getDestTy(); if (CandidateType && - CandidateType->getPrimitiveSizeInBits() > - Ty->getPrimitiveSizeInBits()) + TD->getTypeSizeInBits(CandidateType) > TD->getTypeSizeInBits(Ty)) Ty = CandidateType; } @@ -482,6 +388,7 @@ static const PHINode *TestOrigIVForWrap(const Loop *L, const BranchInst *BI, const Instruction *OrigCond, + const TargetData *TD, bool &NoSignedWrap, bool &NoUnsignedWrap, const ConstantInt* &InitialVal, @@ -554,7 +461,7 @@ if (const SExtInst *SI = dyn_cast(CmpLHS)) { if (!isa(CmpRHS) || !cast(CmpRHS)->getValue() - .isSignedIntN(IncrInst->getType()->getPrimitiveSizeInBits())) + .isSignedIntN(TD->getTypeSizeInBits(IncrInst->getType()))) return 0; IncrInst = SI->getOperand(0); } @@ -562,7 +469,7 @@ if (const ZExtInst *ZI = dyn_cast(CmpLHS)) { if (!isa(CmpRHS) || !cast(CmpRHS)->getValue() - .isIntN(IncrInst->getType()->getPrimitiveSizeInBits())) + .isIntN(TD->getTypeSizeInBits(IncrInst->getType()))) return 0; IncrInst = ZI->getOperand(0); } @@ -643,7 +550,7 @@ SE->getAddRecExpr(ExtendedStart, ExtendedStep, L); if (LargestType != myType) ExtendedAddRec = SE->getTruncateExpr(ExtendedAddRec, myType); - return Rewriter.expandCodeFor(ExtendedAddRec, InsertPt); + return Rewriter.expandCodeFor(ExtendedAddRec, myType, InsertPt); } static Value *getZeroExtendedTruncVar(const SCEVAddRecExpr *AR, @@ -660,7 +567,7 @@ SE->getAddRecExpr(ExtendedStart, ExtendedStep, L); if (LargestType != myType) ExtendedAddRec = SE->getTruncateExpr(ExtendedAddRec, myType); - return Rewriter.expandCodeFor(ExtendedAddRec, InsertPt); + return Rewriter.expandCodeFor(ExtendedAddRec, myType, InsertPt); } /// allUsesAreSameTyped - See whether all Uses of I are instructions @@ -682,10 +589,11 @@ bool IndVarSimplify::runOnLoop(Loop *L, LPPassManager &LPM) { LI = &getAnalysis(); + TD = &getAnalysis(); SE = &getAnalysis(); Changed = false; - // If there are any floating-point or pointer recurrences, attempt to + // If there are any floating-point recurrences, attempt to // transform them to use integer recurrences. RewriteNonIntegerIVs(L); @@ -712,7 +620,7 @@ for (BasicBlock::iterator I = Header->begin(); isa(I); ++I) { PHINode *PN = cast(I); - if (PN->getType()->isInteger()) { // FIXME: when we have fast-math, enable! + if (PN->getType()->isInteger() || isa(PN->getType())) { SCEVHandle SCEV = SE->getSCEV(PN); // FIXME: It is an extremely bad idea to indvar substitute anything more // complex than affine induction variables. Doing so will put expensive @@ -731,21 +639,26 @@ SmallSetVector SizesToInsert; if (!isa(BackedgeTakenCount)) { LargestType = BackedgeTakenCount->getType(); - SizesToInsert.insert(BackedgeTakenCount->getType()); + if (isa(LargestType)) + LargestType = TD->getIntPtrType(); + SizesToInsert.insert(LargestType); } for (unsigned i = 0, e = IndVars.size(); i != e; ++i) { const PHINode *PN = IndVars[i].first; - SizesToInsert.insert(PN->getType()); - const Type *EffTy = getEffectiveIndvarType(PN); + const Type *PNTy = PN->getType(); + if (isa(PNTy)) PNTy = TD->getIntPtrType(); + SizesToInsert.insert(PNTy); + const Type *EffTy = getEffectiveIndvarType(PN, TD); + if (isa(EffTy)) EffTy = TD->getIntPtrType(); SizesToInsert.insert(EffTy); if (!LargestType || - EffTy->getPrimitiveSizeInBits() > - LargestType->getPrimitiveSizeInBits()) + TD->getTypeSizeInBits(EffTy) > + TD->getTypeSizeInBits(LargestType)) LargestType = EffTy; } // Create a rewriter object which we'll use to transform the code with. - SCEVExpander Rewriter(*SE, *LI); + SCEVExpander Rewriter(*SE, *LI, *TD); // Now that we know the largest of of the induction variables in this loop, // insert a canonical induction variable of the largest size. @@ -769,7 +682,7 @@ if (Instruction *OrigCond = dyn_cast(BI->getCondition())) { // Determine if the OrigIV will ever undergo overflow. OrigControllingPHI = - TestOrigIVForWrap(L, BI, OrigCond, + TestOrigIVForWrap(L, BI, OrigCond, TD, NoSignedWrap, NoUnsignedWrap, InitialVal, IncrVal, LimitVal); @@ -804,7 +717,7 @@ while (!IndVars.empty()) { PHINode *PN = IndVars.back().first; SCEVAddRecExpr *AR = cast(IndVars.back().second); - Value *NewVal = Rewriter.expandCodeFor(AR, InsertPt); + Value *NewVal = Rewriter.expandCodeFor(AR, PN->getType(), InsertPt); DOUT << "INDVARS: Rewrote IV '" << *AR << "' " << *PN << " into = " << *NewVal << "\n"; NewVal->takeName(PN); Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp?rev=69258&r1=69257&r2=69258&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Wed Apr 15 22:18:22 2009 @@ -1,4 +1,4 @@ -//===- LoopStrengthReduce.cpp - Strength Reduce GEPs in Loops -------------===// +//===- LoopStrengthReduce.cpp - Strength Reduce IVs in Loops --------------===// // // The LLVM Compiler Infrastructure // @@ -8,10 +8,7 @@ //===----------------------------------------------------------------------===// // // This pass performs a strength reduction on array references inside loops that -// have as one or more of their components the loop induction variable. This is -// accomplished by creating a new Value to hold the initial value of the array -// access for the first iteration, and then creating a new GEP instruction in -// the loop to increment the value by the appropriate amount. +// have as one or more of their components the loop induction variable. // //===----------------------------------------------------------------------===// @@ -133,17 +130,6 @@ /// dependent on random ordering of pointers in the process. SmallVector StrideOrder; - /// GEPlist - A list of the GEP's that have been remembered in the SCEV - /// data structures. SCEV does not know to update these when the operands - /// of the GEP are changed, which means we cannot leave them live across - /// loops. - SmallVector GEPlist; - - /// CastedValues - As we need to cast values to uintptr_t, this keeps track - /// of the casted version of each value. This is accessed by - /// getCastedVersionOf. - DenseMap CastedPointers; - /// DeadInsts - Keep track of instructions we may have made dead, so that /// we can remove them after we are done working. SmallVector DeadInsts; @@ -175,14 +161,10 @@ AU.addRequired(); AU.addPreserved(); } - - /// getCastedVersionOf - Return the specified value casted to uintptr_t. - /// - Value *getCastedVersionOf(Instruction::CastOps opcode, Value *V); + private: bool AddUsersIfInteresting(Instruction *I, Loop *L, SmallPtrSet &Processed); - SCEVHandle GetExpressionSCEV(Instruction *E); ICmpInst *ChangeCompareStride(Loop *L, ICmpInst *Cond, IVStrideUse* &CondUse, const SCEVHandle* &CondStride); @@ -249,24 +231,6 @@ return new LoopStrengthReduce(TLI); } -/// getCastedVersionOf - Return the specified value casted to uintptr_t. This -/// assumes that the Value* V is of integer or pointer type only. -/// -Value *LoopStrengthReduce::getCastedVersionOf(Instruction::CastOps opcode, - Value *V) { - if (V->getType() == UIntPtrTy) return V; - if (Constant *CB = dyn_cast(V)) - return ConstantExpr::getCast(opcode, CB, UIntPtrTy); - - Value *&New = CastedPointers[V]; - if (New) return New; - - New = SCEVExpander::InsertCastOfTo(opcode, V, UIntPtrTy); - DeadInsts.push_back(cast(New)); - return New; -} - - /// DeleteTriviallyDeadInstructions - If any of the instructions is the /// specified set are trivially dead, delete them and see if this makes any of /// their operands subsequently dead. @@ -308,74 +272,6 @@ } } - -/// GetExpressionSCEV - Compute and return the SCEV for the specified -/// instruction. -SCEVHandle LoopStrengthReduce::GetExpressionSCEV(Instruction *Exp) { - // Pointer to pointer bitcast instructions return the same value as their - // operand. - if (BitCastInst *BCI = dyn_cast(Exp)) { - if (SE->hasSCEV(BCI) || !isa(BCI->getOperand(0))) - return SE->getSCEV(BCI); - SCEVHandle R = GetExpressionSCEV(cast(BCI->getOperand(0))); - SE->setSCEV(BCI, R); - return R; - } - - // Scalar Evolutions doesn't know how to compute SCEV's for GEP instructions. - // If this is a GEP that SE doesn't know about, compute it now and insert it. - // If this is not a GEP, or if we have already done this computation, just let - // SE figure it out. - GetElementPtrInst *GEP = dyn_cast(Exp); - if (!GEP || SE->hasSCEV(GEP)) - return SE->getSCEV(Exp); - - // Analyze all of the subscripts of this getelementptr instruction, looking - // for uses that are determined by the trip count of the loop. First, skip - // all operands the are not dependent on the IV. - - // Build up the base expression. Insert an LLVM cast of the pointer to - // uintptr_t first. - SCEVHandle GEPVal = SE->getUnknown( - getCastedVersionOf(Instruction::PtrToInt, GEP->getOperand(0))); - - gep_type_iterator GTI = gep_type_begin(GEP); - - for (User::op_iterator i = GEP->op_begin() + 1, e = GEP->op_end(); - i != e; ++i, ++GTI) { - // If this is a use of a recurrence that we can analyze, and it comes before - // Op does in the GEP operand list, we will handle this when we process this - // operand. - if (const StructType *STy = dyn_cast(*GTI)) { - const StructLayout *SL = TD->getStructLayout(STy); - unsigned Idx = cast(*i)->getZExtValue(); - uint64_t Offset = SL->getElementOffset(Idx); - GEPVal = SE->getAddExpr(GEPVal, - SE->getIntegerSCEV(Offset, UIntPtrTy)); - } else { - unsigned GEPOpiBits = - (*i)->getType()->getPrimitiveSizeInBits(); - unsigned IntPtrBits = UIntPtrTy->getPrimitiveSizeInBits(); - Instruction::CastOps opcode = (GEPOpiBits < IntPtrBits ? - Instruction::SExt : (GEPOpiBits > IntPtrBits ? Instruction::Trunc : - Instruction::BitCast)); - Value *OpVal = getCastedVersionOf(opcode, *i); - SCEVHandle Idx = SE->getSCEV(OpVal); - - uint64_t TypeSize = TD->getTypePaddedSize(GTI.getIndexedType()); - if (TypeSize != 1) - Idx = SE->getMulExpr(Idx, - SE->getConstant(ConstantInt::get(UIntPtrTy, - TypeSize))); - GEPVal = SE->getAddExpr(GEPVal, Idx); - } - } - - SE->setSCEV(GEP, GEPVal); - GEPlist.push_back(GEP); - return GEPVal; -} - /// containsAddRecFromDifferentLoop - Determine whether expression S involves a /// subexpression that is an AddRec from a loop other than L. An outer loop /// of L is OK, but not an inner loop nor a disjoint loop. @@ -602,7 +498,7 @@ return true; // Instruction already handled. // Get the symbolic expression for this instruction. - SCEVHandle ISE = GetExpressionSCEV(I); + SCEVHandle ISE = SE->getSCEV(I); if (isa(ISE)) return false; // Get the start and stride for this expression. @@ -722,6 +618,7 @@ SmallVectorImpl &DeadInsts); Value *InsertCodeForBaseAtPosition(const SCEVHandle &NewBase, + const Type *Ty, SCEVExpander &Rewriter, Instruction *IP, Loop *L); void dump() const; @@ -735,6 +632,7 @@ } Value *BasedUser::InsertCodeForBaseAtPosition(const SCEVHandle &NewBase, + const Type *Ty, SCEVExpander &Rewriter, Instruction *IP, Loop *L) { // Figure out where we *really* want to insert this code. In particular, if @@ -755,7 +653,7 @@ InsertLoop = InsertLoop->getParentLoop(); } - Value *Base = Rewriter.expandCodeFor(NewBase, BaseInsertPt); + Value *Base = Rewriter.expandCodeFor(NewBase, Ty, BaseInsertPt); // If there is no immediate value, skip the next part. if (Imm->isZero()) @@ -768,8 +666,7 @@ // Always emit the immediate (if non-zero) into the same block as the user. SCEVHandle NewValSCEV = SE->getAddExpr(SE->getUnknown(Base), Imm); - return Rewriter.expandCodeFor(NewValSCEV, IP); - + return Rewriter.expandCodeFor(NewValSCEV, Ty, IP); } @@ -809,15 +706,9 @@ while (isa(InsertPt)) ++InsertPt; } } - Value *NewVal = InsertCodeForBaseAtPosition(NewBase, Rewriter, InsertPt, L); - // Adjust the type back to match the Inst. Note that we can't use InsertPt - // here because the SCEVExpander may have inserted the instructions after - // that point, in its efforts to avoid inserting redundant expressions. - if (isa(OperandValToReplace->getType())) { - NewVal = SCEVExpander::InsertCastOfTo(Instruction::IntToPtr, - NewVal, - OperandValToReplace->getType()); - } + Value *NewVal = InsertCodeForBaseAtPosition(NewBase, + OperandValToReplace->getType(), + Rewriter, InsertPt, L); // Replace the use of the operand Value with the new Phi we just created. Inst->replaceUsesOfWith(OperandValToReplace, NewVal); @@ -875,17 +766,8 @@ Instruction *InsertPt = (L->contains(OldLoc->getParent())) ? PN->getIncomingBlock(i)->getTerminator() : OldLoc->getParent()->getTerminator(); - Code = InsertCodeForBaseAtPosition(NewBase, Rewriter, InsertPt, L); - - // Adjust the type back to match the PHI. Note that we can't use - // InsertPt here because the SCEVExpander may have inserted its - // instructions after that point, in its efforts to avoid inserting - // redundant expressions. - if (isa(PN->getType())) { - Code = SCEVExpander::InsertCastOfTo(Instruction::IntToPtr, - Code, - PN->getType()); - } + Code = InsertCodeForBaseAtPosition(NewBase, PN->getType(), + Rewriter, InsertPt, L); DOUT << " Changing PHI use to "; DEBUG(WriteAsOperand(*DOUT, Code, /*PrintType=*/false)); @@ -921,16 +803,13 @@ } if (SCEVUnknown *SU = dyn_cast(V)) - if (ConstantExpr *CE = dyn_cast(SU->getValue())) - if (TLI && CE->getOpcode() == Instruction::PtrToInt) { - Constant *Op0 = CE->getOperand(0); - if (GlobalValue *GV = dyn_cast(Op0)) { - TargetLowering::AddrMode AM; - AM.BaseGV = GV; - AM.HasBaseReg = HasBaseReg; - return TLI->isLegalAddressingMode(AM, UseTy); - } - } + if (GlobalValue *GV = dyn_cast(SU->getValue())) { + TargetLowering::AddrMode AM; + AM.BaseGV = GV; + AM.HasBaseReg = HasBaseReg; + return TLI->isLegalAddressingMode(AM, UseTy); + } + return false; } @@ -1591,6 +1470,7 @@ /// static PHINode *InsertAffinePhi(SCEVHandle Start, SCEVHandle Step, const Loop *L, + const TargetData *TD, SCEVExpander &Rewriter) { assert(Start->isLoopInvariant(L) && "New PHI start is not loop invariant!"); assert(Step->isLoopInvariant(L) && "New PHI stride is not loop invariant!"); @@ -1598,9 +1478,11 @@ BasicBlock *Header = L->getHeader(); BasicBlock *Preheader = L->getLoopPreheader(); BasicBlock *LatchBlock = L->getLoopLatch(); + const Type *Ty = Start->getType(); + if (isa(Ty)) Ty = TD->getIntPtrType(); - PHINode *PN = PHINode::Create(Start->getType(), "lsr.iv", Header->begin()); - PN->addIncoming(Rewriter.expandCodeFor(Start, Preheader->getTerminator()), + PHINode *PN = PHINode::Create(Ty, "lsr.iv", Header->begin()); + PN->addIncoming(Rewriter.expandCodeFor(Start, Ty, Preheader->getTerminator()), Preheader); // If the stride is negative, insert a sub instead of an add for the @@ -1612,7 +1494,8 @@ // Insert an add instruction right before the terminator corresponding // to the back-edge. - Value *StepV = Rewriter.expandCodeFor(IncAmount, Preheader->getTerminator()); + Value *StepV = Rewriter.expandCodeFor(IncAmount, Ty, + Preheader->getTerminator()); Instruction *IncV; if (isNegative) { IncV = BinaryOperator::CreateSub(PN, StepV, "lsr.iv.next", @@ -1683,7 +1566,7 @@ SCEVHandle Imm = UsersToProcess[i].Imm; SCEVHandle Base = UsersToProcess[i].Base; SCEVHandle Start = SE->getAddExpr(CommonExprs, Base, Imm); - PHINode *Phi = InsertAffinePhi(Start, Stride, L, + PHINode *Phi = InsertAffinePhi(Start, Stride, L, TD, PreheaderRewriter); // Loop over all the users with the same base. do { @@ -1710,7 +1593,7 @@ DOUT << " Inserting new PHI:\n"; PHINode *Phi = InsertAffinePhi(SE->getUnknown(CommonBaseV), - Stride, L, + Stride, L, TD, PreheaderRewriter); // Remember this in case a later stride is multiple of this. @@ -1816,6 +1699,7 @@ bool HaveCommonExprs = !CommonExprs->isZero(); const Type *ReplacedTy = CommonExprs->getType(); + if (isa(ReplacedTy)) ReplacedTy = TD->getIntPtrType(); // If all uses are addresses, consider sinking the immediate part of the // common expression back into uses if they can fit in the immediate fields. @@ -1829,11 +1713,8 @@ // If the immediate part of the common expression is a GV, check if it's // possible to fold it into the target addressing mode. GlobalValue *GV = 0; - if (SCEVUnknown *SU = dyn_cast(Imm)) { - if (ConstantExpr *CE = dyn_cast(SU->getValue())) - if (CE->getOpcode() == Instruction::PtrToInt) - GV = dyn_cast(CE->getOperand(0)); - } + if (SCEVUnknown *SU = dyn_cast(Imm)) + GV = dyn_cast(SU->getValue()); int64_t Offset = 0; if (SCEVConstant *SC = dyn_cast(Imm)) Offset = SC->getValue()->getSExtValue(); @@ -1860,8 +1741,8 @@ << *Stride << ":\n" << " Common base: " << *CommonExprs << "\n"; - SCEVExpander Rewriter(*SE, *LI); - SCEVExpander PreheaderRewriter(*SE, *LI); + SCEVExpander Rewriter(*SE, *LI, *TD); + SCEVExpander PreheaderRewriter(*SE, *LI, *TD); BasicBlock *Preheader = L->getLoopPreheader(); Instruction *PreInsertPt = Preheader->getTerminator(); @@ -1882,7 +1763,8 @@ PreheaderRewriter); } else { // Emit the initial base value into the loop preheader. - CommonBaseV = PreheaderRewriter.expandCodeFor(CommonExprs, PreInsertPt); + CommonBaseV = PreheaderRewriter.expandCodeFor(CommonExprs, ReplacedTy, + PreInsertPt); // If all uses are addresses, check if it is possible to reuse an IV with a // stride that is a factor of this stride. And that the multiple is a number @@ -1910,19 +1792,21 @@ Instruction *Inst = UsersToProcess.back().Inst; // Emit the code for Base into the preheader. - Value *BaseV = PreheaderRewriter.expandCodeFor(Base, PreInsertPt); - - DOUT << " Examining uses with BASE "; - DEBUG(WriteAsOperand(*DOUT, BaseV, /*PrintType=*/false)); - DOUT << ":\n"; - - // If BaseV is a constant other than 0, make sure that it gets inserted into - // the preheader, instead of being forward substituted into the uses. We do - // this by forcing a BitCast (noop cast) to be inserted into the preheader - // in this case. - if (Constant *C = dyn_cast(BaseV)) { - if (!C->isNullValue() && !fitsInAddressMode(Base, getAccessType(Inst), - TLI, false)) { + Value *BaseV = 0; + if (!Base->isZero()) { + BaseV = PreheaderRewriter.expandCodeFor(Base, Base->getType(), + PreInsertPt); + + DOUT << " INSERTING code for BASE = " << *Base << ":"; + if (BaseV->hasName()) + DOUT << " Result value name = %" << BaseV->getNameStr(); + DOUT << "\n"; + + // If BaseV is a non-zero constant, make sure that it gets inserted into + // the preheader, instead of being forward substituted into the uses. We + // do this by forcing a BitCast (noop cast) to be inserted into the + // preheader in this case. + if (!fitsInAddressMode(Base, getAccessType(Inst), TLI, false)) { // We want this constant emitted into the preheader! This is just // using cast as a copy so BitCast (no-op cast) is appropriate BaseV = new BitCastInst(BaseV, BaseV->getType(), "preheaderinsert", @@ -1953,10 +1837,11 @@ User.Inst->moveBefore(LatchBlock->getTerminator()); } if (RewriteOp->getType() != ReplacedTy) { - Instruction::CastOps opcode = Instruction::Trunc; - if (ReplacedTy->getPrimitiveSizeInBits() == - RewriteOp->getType()->getPrimitiveSizeInBits()) - opcode = Instruction::BitCast; + Instruction::CastOps opcode = + CastInst::getCastOpcode(RewriteOp, false, ReplacedTy, false); + assert(opcode != Instruction::SExt && + opcode != Instruction::ZExt && + "Unexpected widening cast!"); RewriteOp = SCEVExpander::InsertCastOfTo(opcode, RewriteOp, ReplacedTy); } @@ -1978,8 +1863,7 @@ // If we are reusing the iv, then it must be multiplied by a constant // factor to take advantage of the addressing mode scale component. - if (!isa(RewriteFactor) || - !cast(RewriteFactor)->isZero()) { + if (!RewriteFactor->isZero()) { // If we're reusing an IV with a nonzero base (currently this happens // only when all reuses are outside the loop) subtract that base here. // The base has been used to initialize the PHI node but we don't want @@ -2010,8 +1894,7 @@ // When this use is outside the loop, we earlier subtracted the // common base, and are adding it back here. Use the same expression // as before, rather than CommonBaseV, so DAGCombiner will zap it. - if (!isa(CommonBaseV) || - !cast(CommonBaseV)->isZero()) { + if (!CommonExprs->isZero()) { if (L->contains(User.Inst->getParent())) RewriteExpr = SE->getAddExpr(RewriteExpr, SE->getUnknown(CommonBaseV)); @@ -2022,7 +1905,7 @@ // Now that we know what we need to do, insert code before User for the // immediate and any loop-variant expressions. - if (!isa(BaseV) || !cast(BaseV)->isZero()) + if (BaseV) // Add BaseV to the PHI value if needed. RewriteExpr = SE->getAddExpr(RewriteExpr, SE->getUnknown(BaseV)); @@ -2078,6 +1961,9 @@ // e.g. // 4, -1, X, 1, 2 ==> 1, -1, 2, 4, X struct StrideCompare { + const TargetData *TD; + explicit StrideCompare(const TargetData *td) : TD(td) {} + bool operator()(const SCEVHandle &LHS, const SCEVHandle &RHS) { SCEVConstant *LHSC = dyn_cast(LHS); SCEVConstant *RHSC = dyn_cast(RHS); @@ -2096,7 +1982,8 @@ // If it's the same value but different type, sort by bit width so // that we emit larger induction variables before smaller // ones, letting the smaller be re-written in terms of larger ones. - return RHS->getBitWidth() < LHS->getBitWidth(); + return TD->getTypeSizeInBits(RHS->getType()) < + TD->getTypeSizeInBits(LHS->getType()); } return LHSC && !RHSC; } @@ -2129,11 +2016,11 @@ ICmpInst::Predicate Predicate = Cond->getPredicate(); int64_t CmpSSInt = SC->getValue()->getSExtValue(); - unsigned BitWidth = (*CondStride)->getBitWidth(); + unsigned BitWidth = TD->getTypeSizeInBits((*CondStride)->getType()); uint64_t SignBit = 1ULL << (BitWidth-1); const Type *CmpTy = Cond->getOperand(0)->getType(); const Type *NewCmpTy = NULL; - unsigned TyBits = CmpTy->getPrimitiveSizeInBits(); + unsigned TyBits = TD->getTypeSizeInBits(CmpTy); unsigned NewTyBits = 0; SCEVHandle *NewStride = NULL; Value *NewCmpLHS = NULL; @@ -2185,9 +2072,7 @@ continue; NewCmpTy = NewCmpLHS->getType(); - NewTyBits = isa(NewCmpTy) - ? UIntPtrTy->getPrimitiveSizeInBits() - : NewCmpTy->getPrimitiveSizeInBits(); + NewTyBits = TD->getTypeSizeInBits(NewCmpTy); if (RequiresTypeConversion(NewCmpTy, CmpTy)) { // Check if it is possible to rewrite it using // an iv / stride of a smaller integer type. @@ -2604,7 +2489,7 @@ #endif // Sort the StrideOrder so we process larger strides first. - std::stable_sort(StrideOrder.begin(), StrideOrder.end(), StrideCompare()); + std::stable_sort(StrideOrder.begin(), StrideOrder.end(), StrideCompare(TD)); // Optimize induction variables. Some indvar uses can be transformed to use // strides that will be needed for other purposes. A common example of this @@ -2638,13 +2523,9 @@ } // We're done analyzing this loop; release all the state we built up for it. - CastedPointers.clear(); IVUsesByStride.clear(); IVsByStride.clear(); StrideOrder.clear(); - for (unsigned i=0; ideleteValueFromRecords(GEPlist[i]); - GEPlist.clear(); // Clean up after ourselves if (!DeadInsts.empty()) { Modified: llvm/trunk/test/CodeGen/ARM/2007-03-13-InstrSched.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/2007-03-13-InstrSched.ll?rev=69258&r1=69257&r2=69258&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/2007-03-13-InstrSched.ll (original) +++ llvm/trunk/test/CodeGen/ARM/2007-03-13-InstrSched.ll Wed Apr 15 22:18:22 2009 @@ -1,5 +1,5 @@ ; RUN: llvm-as < %s | llc -mtriple=arm-apple-darwin -relocation-model=pic \ -; RUN: -mattr=+v6 -stats |& grep asm-printer | grep 41 +; RUN: -mattr=+v6 -ifcvt-limit=0 -stats |& grep asm-printer | grep 35 define void @test(i32 %tmp56222, i32 %tmp36224, i32 %tmp46223, i32 %i.0196.0.ph, i32 %tmp8, i32* %tmp1011, i32** %tmp1, i32* %d2.1.out, i32* %d3.1.out, i32* %d0.1.out, i32* %d1.1.out) { newFuncRoot: Modified: llvm/trunk/test/CodeGen/X86/iv-users-in-other-loops.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/iv-users-in-other-loops.ll?rev=69258&r1=69257&r2=69258&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/iv-users-in-other-loops.ll (original) +++ llvm/trunk/test/CodeGen/X86/iv-users-in-other-loops.ll Wed Apr 15 22:18:22 2009 @@ -1,7 +1,8 @@ ; RUN: llvm-as < %s | llc -march=x86-64 -f -o %t ; RUN: grep inc %t | count 2 ; RUN: grep addq %t | count 13 -; RUN: grep leaq %t | count 9 +; RUN: grep leaq %t | count 8 +; RUN: grep leal %t | count 4 ; RUN: grep movq %t | count 5 ; IV users in each of the loops from other loops shouldn't cause LSR Modified: llvm/trunk/test/CodeGen/X86/pr3495.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/pr3495.ll?rev=69258&r1=69257&r2=69258&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/pr3495.ll (original) +++ llvm/trunk/test/CodeGen/X86/pr3495.ll Wed Apr 15 22:18:22 2009 @@ -1,5 +1,6 @@ -; RUN: llvm-as < %s | llc -march=x86 -stats |& grep {Number of reloads omited} -; RUN: llvm-as < %s | llc -march=x86 -stats |& grep {Number of available reloads turned into copies} +; RUN: llvm-as < %s | llc -march=x86 -stats |& grep {Number of reloads omited} | grep 2 +; RUN: llvm-as < %s | llc -march=x86 -stats |& not grep {Number of available reloads turned into copies} +; RUN: llvm-as < %s | llc -march=x86 -stats |& grep {Number of machine instrs printed} | grep 39 ; PR3495 target triple = "i386-pc-linux-gnu" Modified: llvm/trunk/test/CodeGen/X86/stride-nine-with-base-reg.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/stride-nine-with-base-reg.ll?rev=69258&r1=69257&r2=69258&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/stride-nine-with-base-reg.ll (original) +++ llvm/trunk/test/CodeGen/X86/stride-nine-with-base-reg.ll Wed Apr 15 22:18:22 2009 @@ -1,7 +1,7 @@ ; RUN: llvm-as < %s | llc -march=x86 -relocation-model=static | not grep lea ; RUN: llvm-as < %s | llc -march=x86-64 | not grep lea -; _P should be sunk into the loop and folded into the address mode. There +; P should be sunk into the loop and folded into the address mode. There ; shouldn't be any lea instructions inside the loop. @B = external global [1000 x i8], align 32 From sabre at nondot.org Thu Apr 16 00:52:18 2009 From: sabre at nondot.org (Chris Lattner) Date: Thu, 16 Apr 2009 05:52:18 -0000 Subject: [llvm-commits] [llvm] r69270 - /llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp Message-ID: <200904160552.n3G5qI2o027343@zion.cs.uiuc.edu> Author: lattner Date: Thu Apr 16 00:52:18 2009 New Revision: 69270 URL: http://llvm.org/viewvc/llvm-project?rev=69270&view=rev Log: prove diagnostic -> group mapping information. Modified: llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp Modified: llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp?rev=69270&r1=69269&r2=69270&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp Thu Apr 16 00:52:18 2009 @@ -50,10 +50,22 @@ OS << "DIAG(" << R.getName() << ", "; OS << R.getValueAsDef("Class")->getName(); OS << ", diag::" << R.getValueAsDef("DefaultMapping")->getName(); + + // Description string. OS << ", \""; std::string S = R.getValueAsString("Text"); EscapeString(S); - OS << S << "\")\n"; + OS << S << "\""; + + // Warning associated with the diagnostic. + if (DefInit *DI = dynamic_cast(R.getValueInit("Group"))) { + S = DI->getDef()->getValueAsString("GroupName"); + EscapeString(S); + OS << ", \"" << S << "\""; + } else { + OS << ", 0"; + } + OS << ")\n"; } } From rafael.espindola at gmail.com Thu Apr 16 07:34:54 2009 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Thu, 16 Apr 2009 12:34:54 -0000 Subject: [llvm-commits] [llvm] r69284 - in /llvm/trunk: lib/Target/X86/X86ISelDAGToDAG.cpp test/CodeGen/X86/2009-04-scale.ll Message-ID: <200904161234.n3GCYsZg018778@zion.cs.uiuc.edu> Author: rafael Date: Thu Apr 16 07:34:53 2009 New Revision: 69284 URL: http://llvm.org/viewvc/llvm-project?rev=69284&view=rev Log: fix PR3995. A scale must be 1, 2, 4 or 8. Added: llvm/trunk/test/CodeGen/X86/2009-04-scale.ll Modified: llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Modified: llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp?rev=69284&r1=69283&r2=69284&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Thu Apr 16 07:34:53 2009 @@ -1041,7 +1041,7 @@ // a scaled index. if (Shift.getOpcode() == ISD::SRL && Shift.hasOneUse()) { unsigned ScaleLog = 8 - C1->getZExtValue(); - if (ScaleLog > 0 && ScaleLog < 64 && + if (ScaleLog > 0 && ScaleLog < 4 && C2->getZExtValue() == (UINT64_C(0xff) << ScaleLog)) { SDValue Eight = CurDAG->getConstant(8, MVT::i8); SDValue Mask = CurDAG->getConstant(0xff, N.getValueType()); Added: llvm/trunk/test/CodeGen/X86/2009-04-scale.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2009-04-scale.ll?rev=69284&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/2009-04-scale.ll (added) +++ llvm/trunk/test/CodeGen/X86/2009-04-scale.ll Thu Apr 16 07:34:53 2009 @@ -0,0 +1,23 @@ +; RUN: llvm-as < %s | llc -march=x86 -mtriple=i386-unknown-linux-gnu +; PR3995 + + %struct.vtable = type { i32 (...)** } + %struct.array = type { %struct.impl, [256 x %struct.pair], [256 x %struct.pair], [256 x %struct.pair], [256 x %struct.pair], [256 x %struct.pair], [256 x %struct.pair] } + %struct.impl = type { %struct.vtable, i8, %struct.impl*, i32, i32, i64, i64 } + %struct.pair = type { i64, i64 } + +define void @test() { +entry: + %0 = load i32* null, align 4 ; [#uses=1] + %1 = lshr i32 %0, 8 ; [#uses=1] + %2 = and i32 %1, 255 ; [#uses=1] + %3 = getelementptr %struct.array* null, i32 0, i32 3 ; <[256 x %struct.pair]*> [#uses=1] + %4 = getelementptr [256 x %struct.pair]* %3, i32 0, i32 %2 ; <%struct.pair*> [#uses=1] + %5 = getelementptr %struct.pair* %4, i32 0, i32 1 ; [#uses=1] + %6 = load i64* %5, align 4 ; [#uses=1] + %7 = xor i64 0, %6 ; [#uses=1] + %8 = xor i64 %7, 0 ; [#uses=1] + %9 = xor i64 %8, 0 ; [#uses=1] + store i64 %9, i64* null, align 8 + unreachable +} From dpatel at apple.com Thu Apr 16 10:07:10 2009 From: dpatel at apple.com (Devang Patel) Date: Thu, 16 Apr 2009 15:07:10 -0000 Subject: [llvm-commits] [llvm] r69286 - in /llvm/trunk/lib/CodeGen/SelectionDAG: FastISel.cpp SelectionDAGBuild.cpp Message-ID: <200904161507.n3GF7AxH023963@zion.cs.uiuc.edu> Author: dpatel Date: Thu Apr 16 10:07:09 2009 New Revision: 69286 URL: http://llvm.org/viewvc/llvm-project?rev=69286&view=rev Log: Record line number at the beginning of a func.start. This line was accidently lost yesterday. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp?rev=69286&r1=69285&r2=69286&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp Thu Apr 16 10:07:09 2009 @@ -406,7 +406,7 @@ // Record the source line. unsigned Line = Subprogram.getLineNumber(); setCurDebugLoc(DebugLoc::get(MF.getOrCreateDebugLocID(SrcFile, Line, 0))); - + DW->RecordSourceLine(Line, 0, SrcFile); // llvm.dbg.func_start also defines beginning of function scope. DW->RecordRegionStart(cast(FSI->getSubprogram())); } Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp?rev=69286&r1=69285&r2=69286&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Thu Apr 16 10:07:09 2009 @@ -4016,7 +4016,7 @@ // Record the source line. unsigned Line = Subprogram.getLineNumber(); setCurDebugLoc(DebugLoc::get(MF.getOrCreateDebugLocID(SrcFile, Line, 0))); - + DW->RecordSourceLine(Line, 0, SrcFile); // llvm.dbg.func_start also defines beginning of function scope. DW->RecordRegionStart(cast(FSI.getSubprogram())); } From gohman at apple.com Thu Apr 16 10:39:13 2009 From: gohman at apple.com (Dan Gohman) Date: Thu, 16 Apr 2009 15:39:13 -0000 Subject: [llvm-commits] [test-suite] r69288 - in /test-suite/trunk/MultiSource/Benchmarks: PAQ8p/ mafft/ Message-ID: <200904161539.n3GFdDuc025068@zion.cs.uiuc.edu> Author: djg Date: Thu Apr 16 10:39:12 2009 New Revision: 69288 URL: http://llvm.org/viewvc/llvm-project?rev=69288&view=rev Log: Add svn:ignore properties. Modified: test-suite/trunk/MultiSource/Benchmarks/PAQ8p/ (props changed) test-suite/trunk/MultiSource/Benchmarks/mafft/ (props changed) Propchange: test-suite/trunk/MultiSource/Benchmarks/PAQ8p/ ------------------------------------------------------------------------------ --- svn:ignore (added) +++ svn:ignore Thu Apr 16 10:39:12 2009 @@ -0,0 +1 @@ +Output Propchange: test-suite/trunk/MultiSource/Benchmarks/mafft/ ------------------------------------------------------------------------------ --- svn:ignore (added) +++ svn:ignore Thu Apr 16 10:39:12 2009 @@ -0,0 +1 @@ +Output From gohman at apple.com Thu Apr 16 10:43:12 2009 From: gohman at apple.com (Dan Gohman) Date: Thu, 16 Apr 2009 15:43:12 -0000 Subject: [llvm-commits] [test-suite] r69289 - in /test-suite/trunk: External/SPEC/ MultiSource/Applications/ClamAV/inputs/rtf-test/ MultiSource/Applications/lambda-0.1.3/docs/ MultiSource/Benchmarks/MiBench/consumer-typeset/data/data/ MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/ MultiSource/Benchmarks/MiBench/consumer-typeset/data/hyph/ MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/ MultiSource/Benchmarks/MiBench/consumer-typeset/data/maps/ MultiSource/Benchmarks/MiBench/telecomm-gsm/ SingleSource/B... Message-ID: <200904161543.n3GFhIlS025472@zion.cs.uiuc.edu> Author: djg Date: Thu Apr 16 10:43:09 2009 New Revision: 69289 URL: http://llvm.org/viewvc/llvm-project?rev=69289&view=rev Log: Remove extraneous svn:executable properties. Modified: test-suite/trunk/External/SPEC/Makefile.spec.config (props changed) test-suite/trunk/External/SPEC/Makefile.spec2006 (props changed) test-suite/trunk/MultiSource/Applications/ClamAV/inputs/rtf-test/Doc1.rtf (props changed) test-suite/trunk/MultiSource/Applications/ClamAV/inputs/rtf-test/Doc11.rtf (props changed) test-suite/trunk/MultiSource/Applications/ClamAV/inputs/rtf-test/Doc2.rtf (props changed) test-suite/trunk/MultiSource/Applications/ClamAV/inputs/rtf-test/Doc22.rtf (props changed) test-suite/trunk/MultiSource/Applications/ClamAV/inputs/rtf-test/doc3.rtf (props changed) test-suite/trunk/MultiSource/Applications/ClamAV/inputs/rtf-test/docCLAMexe.rtf (props changed) test-suite/trunk/MultiSource/Applications/ClamAV/inputs/rtf-test/rtf-novirus.rtf (props changed) test-suite/trunk/MultiSource/Applications/ClamAV/inputs/rtf-test/rtf1.rtf (props changed) test-suite/trunk/MultiSource/Applications/lambda-0.1.3/docs/lambda.html (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/data/fcvt (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/data/fcvt.awk (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/data/fontdefs.ld (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/data/fontdefs.li (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/data/latin2.ld (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/data/loutrefs.ld (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/data/loutrefs.li (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/data/oldrefs.ld (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/data/refstyle.ld (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/data/refstyle.li (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/data/standard.ld (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/data/standard.li (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/00README (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/AG-Bd (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/AG-Bd+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/AG-BdO (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/AG-BdO+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/AG-Bk (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/AG-Bk+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/AG-BkO (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/AG-BkO+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/AG-CnBd (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/AG-CnBd+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/AG-CnBk (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/AG-CnBk+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/AG-CnDm (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/AG-CnDm+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/AG-CnMd (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/AG-CnMd+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/AG-Dm (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/AG-Dm+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/AG-DmO (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/AG-DmO+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/AG-ExLt (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/AG-ExLt+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/AG-ExLtO (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/AG-ExLtO+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/AG-Md (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/AG-Md+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/AG-MdO (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/AG-MdO+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Bk-Bd (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Bk-Bd+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Bk-BdIt (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Bk-BdIt+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Bk-Dm (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Bk-Dm+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Bk-DmIt (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Bk-DmIt+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Bk-Lt (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Bk-Lt+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Bk-LtIt (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Bk-LtIt+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Bk-Md (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Bk-Md+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Bk-MdIt (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Bk-MdIt+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Cr (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Cr+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Cr-Bd (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Cr-Bd+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Cr-BdO (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Cr-BdO+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Cr-O (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Cr-O+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-Bd (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-Bd+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-BdO (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-BdO+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-Bl (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-Bl+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-BlO (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-BlO+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-Cm (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-Cm+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-Cn (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-Cn+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-CnBd (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-CnBd+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-CnBdO (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-CnBdO+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-CnBl (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-CnBl+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-CnBlO (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-CnBlO+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-CnLi (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-CnLi+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-CnLiO (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-CnLiO+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-CnO (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-CnO+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-ExtC (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-ExtC+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-Lt (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-Lt+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-LtO (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-LtO+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-Nr (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-Nr+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-NrBd (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-NrBd+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-NrBdO (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-NrBdO+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-NrO (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-NrO+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-O (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-O+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-UlCm (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-UlCm+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/NCS-Bd (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/NCS-Bd+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/NCS-BdIt (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/NCS-BdIt+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/NCS-It (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/NCS-It+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/NCS-Rm (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/NCS-Rm+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Pa-Bd (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Pa-Bd+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Pa-BdF (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Pa-BdF+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Pa-BdIt (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Pa-BdIt+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Pa-BdItF (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Pa-BdItF+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Pa-It (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Pa-It+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Pa-ItF (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Pa-ItF+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Pa-Rm (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Pa-Rm+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Pa-SC (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Pa-SC+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Symbol (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Ti-Bd (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Ti-Bd+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Ti-BdIt (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Ti-BdIt+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Ti-BdItF (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Ti-BdItF+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Ti-BdSC (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Ti-BdSC+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Ti-ExBd (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Ti-ExBd+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Ti-It (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Ti-It+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Ti-ItF (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Ti-ItF+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Ti-Rm (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Ti-Rm+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Ti-RmSC (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Ti-RmSC+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Ti-Sm (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Ti-Sm+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Ti-SmIt (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Ti-SmIt+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/ZC-Bd (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/ZC-Bd+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/ZC-Dm (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/ZC-Dm+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/ZC-It (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/ZC-It+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/ZC-Lt (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/ZC-Lt+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/ZC-LtIt (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/ZC-LtIt+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/ZC-MdIt (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/ZC-MdIt+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/ZC-Rm (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/ZC-Rm+ (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/ZD (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/hyph/czech.lh (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/hyph/danish.lh (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/hyph/dutch.lh (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/hyph/english.lh (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/hyph/english.lp (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/hyph/engluk.lh (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/hyph/finnish.lh (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/hyph/french.lh (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/hyph/german.lh (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/hyph/italian.lh (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/hyph/norweg.lh (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/hyph/polish.lh (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/hyph/portugal.lh (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/hyph/russian.lh (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/hyph/slovenia.lh (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/hyph/spanish.lh (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/hyph/swedish.lh (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/blue (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/bluef (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/book (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/bookf (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/bsf (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/bsf.lpg (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/cprint (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/cprintf (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/diag (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/diagf (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/diagf.etc (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/diagf.lpg (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/doc (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/docf (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/dsf (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/eiffel (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/eiffelf (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/eq (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/eqf (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/fig (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/figf (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/figf.lpg (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/graph (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/graphf (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/graphf.etc (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/graphf.lpg (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/init (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/langdefs (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/latin2 (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/modula (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/modulaf (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/mydefs (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/pas (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/pasf (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/perl (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/perlf (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/picture (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/picturef (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/pod (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/podf (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/python (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/pythonf (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/report (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/reportf (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/russian (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/russian.fd (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/slides (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/slidesf (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/tab (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/tabf (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/tabf.lpg (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/tbl (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/tblf (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/tblf.lpg (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/ts (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/maps/00README (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/maps/Ding.LCM (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/maps/Latin1.LCM (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/maps/LtLatin1.LCM (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/maps/LtLatin2.LCM (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/maps/Std.LCM (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/maps/Symb.LCM (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/maps/koi8r.LCM (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/maps/null.LCM (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/telecomm-gsm/COPYRIGHT (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/telecomm-gsm/INSTALL (props changed) test-suite/trunk/MultiSource/Benchmarks/MiBench/telecomm-gsm/large.au (props changed) test-suite/trunk/SingleSource/Benchmarks/Adobe-C++/LICENSE_1_0_0.txt (props changed) test-suite/trunk/SingleSource/Benchmarks/Adobe-C++/README.txt (props changed) test-suite/trunk/SingleSource/Benchmarks/Adobe-C++/benchmark_stdint.hpp (props changed) Propchange: test-suite/trunk/External/SPEC/Makefile.spec.config ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/External/SPEC/Makefile.spec2006 ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Applications/ClamAV/inputs/rtf-test/Doc1.rtf ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Applications/ClamAV/inputs/rtf-test/Doc11.rtf ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Applications/ClamAV/inputs/rtf-test/Doc2.rtf ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Applications/ClamAV/inputs/rtf-test/Doc22.rtf ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Applications/ClamAV/inputs/rtf-test/doc3.rtf ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Applications/ClamAV/inputs/rtf-test/docCLAMexe.rtf ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Applications/ClamAV/inputs/rtf-test/rtf-novirus.rtf ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Applications/ClamAV/inputs/rtf-test/rtf1.rtf ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Applications/lambda-0.1.3/docs/lambda.html ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/data/fcvt ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/data/fcvt.awk ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/data/fontdefs.ld ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/data/fontdefs.li ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/data/latin2.ld ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/data/loutrefs.ld ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/data/loutrefs.li ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/data/oldrefs.ld ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/data/refstyle.ld ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/data/refstyle.li ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/data/standard.ld ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/data/standard.li ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/00README ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/AG-Bd ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/AG-Bd+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/AG-BdO ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/AG-BdO+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/AG-Bk ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/AG-Bk+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/AG-BkO ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/AG-BkO+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/AG-CnBd ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/AG-CnBd+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/AG-CnBk ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/AG-CnBk+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/AG-CnDm ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/AG-CnDm+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/AG-CnMd ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/AG-CnMd+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/AG-Dm ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/AG-Dm+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/AG-DmO ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/AG-DmO+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/AG-ExLt ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/AG-ExLt+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/AG-ExLtO ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/AG-ExLtO+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/AG-Md ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/AG-Md+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/AG-MdO ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/AG-MdO+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Bk-Bd ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Bk-Bd+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Bk-BdIt ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Bk-BdIt+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Bk-Dm ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Bk-Dm+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Bk-DmIt ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Bk-DmIt+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Bk-Lt ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Bk-Lt+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Bk-LtIt ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Bk-LtIt+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Bk-Md ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Bk-Md+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Bk-MdIt ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Bk-MdIt+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Cr ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Cr+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Cr-Bd ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Cr-Bd+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Cr-BdO ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Cr-BdO+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Cr-O ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Cr-O+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-Bd ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-Bd+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-BdO ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-BdO+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-Bl ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-Bl+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-BlO ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-BlO+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-Cm ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-Cm+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-Cn ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-Cn+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-CnBd ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-CnBd+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-CnBdO ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-CnBdO+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-CnBl ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-CnBl+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-CnBlO ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-CnBlO+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-CnLi ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-CnLi+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-CnLiO ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-CnLiO+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-CnO ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-CnO+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-ExtC ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-ExtC+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-Lt ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-Lt+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-LtO ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-LtO+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-Nr ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-Nr+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-NrBd ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-NrBd+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-NrBdO ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-NrBdO+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-NrO ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-NrO+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-O ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-O+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-UlCm ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/He-UlCm+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/NCS-Bd ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/NCS-Bd+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/NCS-BdIt ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/NCS-BdIt+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/NCS-It ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/NCS-It+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/NCS-Rm ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/NCS-Rm+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Pa-Bd ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Pa-Bd+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Pa-BdF ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Pa-BdF+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Pa-BdIt ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Pa-BdIt+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Pa-BdItF ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Pa-BdItF+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Pa-It ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Pa-It+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Pa-ItF ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Pa-ItF+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Pa-Rm ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Pa-Rm+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Pa-SC ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Pa-SC+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Symbol ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Ti-Bd ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Ti-Bd+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Ti-BdIt ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Ti-BdIt+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Ti-BdItF ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Ti-BdItF+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Ti-BdSC ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Ti-BdSC+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Ti-ExBd ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Ti-ExBd+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Ti-It ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Ti-It+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Ti-ItF ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Ti-ItF+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Ti-Rm ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Ti-Rm+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Ti-RmSC ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Ti-RmSC+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Ti-Sm ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Ti-Sm+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Ti-SmIt ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/Ti-SmIt+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/ZC-Bd ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/ZC-Bd+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/ZC-Dm ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/ZC-Dm+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/ZC-It ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/ZC-It+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/ZC-Lt ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/ZC-Lt+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/ZC-LtIt ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/ZC-LtIt+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/ZC-MdIt ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/ZC-MdIt+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/ZC-Rm ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/ZC-Rm+ ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/font/ZD ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/hyph/czech.lh ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/hyph/danish.lh ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/hyph/dutch.lh ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/hyph/english.lh ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/hyph/english.lp ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/hyph/engluk.lh ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/hyph/finnish.lh ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/hyph/french.lh ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/hyph/german.lh ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/hyph/italian.lh ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/hyph/norweg.lh ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/hyph/polish.lh ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/hyph/portugal.lh ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/hyph/russian.lh ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/hyph/slovenia.lh ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/hyph/spanish.lh ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/hyph/swedish.lh ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/blue ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/bluef ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/book ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/bookf ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/bsf ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/bsf.lpg ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/cprint ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/cprintf ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/diag ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/diagf ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/diagf.etc ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/diagf.lpg ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/doc ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/docf ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/dsf ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/eiffel ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/eiffelf ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/eq ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/eqf ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/fig ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/figf ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/figf.lpg ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/graph ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/graphf ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/graphf.etc ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/graphf.lpg ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/init ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/langdefs ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/latin2 ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/modula ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/modulaf ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/mydefs ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/pas ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/pasf ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/perl ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/perlf ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/picture ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/picturef ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/pod ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/podf ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/python ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/pythonf ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/report ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/reportf ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/russian ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/russian.fd ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/slides ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/slidesf ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/tab ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/tabf ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/tabf.lpg ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/tbl ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/tblf ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/tblf.lpg ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/include/ts ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/maps/00README ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/maps/Ding.LCM ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/maps/Latin1.LCM ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/maps/LtLatin1.LCM ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/maps/LtLatin2.LCM ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/maps/Std.LCM ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/maps/Symb.LCM ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/maps/koi8r.LCM ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/consumer-typeset/data/maps/null.LCM ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/telecomm-gsm/COPYRIGHT ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/telecomm-gsm/INSTALL ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/MultiSource/Benchmarks/MiBench/telecomm-gsm/large.au ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/SingleSource/Benchmarks/Adobe-C++/LICENSE_1_0_0.txt ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/SingleSource/Benchmarks/Adobe-C++/README.txt ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* Propchange: test-suite/trunk/SingleSource/Benchmarks/Adobe-C++/benchmark_stdint.hpp ------------------------------------------------------------------------------ --- svn:executable (original) +++ svn:executable (removed) @@ -1 +0,0 @@ -* From gohman at apple.com Thu Apr 16 10:47:35 2009 From: gohman at apple.com (Dan Gohman) Date: Thu, 16 Apr 2009 15:47:35 -0000 Subject: [llvm-commits] [llvm] r69290 - /llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Message-ID: <200904161547.n3GFlavl025647@zion.cs.uiuc.edu> Author: djg Date: Thu Apr 16 10:47:35 2009 New Revision: 69290 URL: http://llvm.org/viewvc/llvm-project?rev=69290&view=rev Log: Use a SCEV expression cast instead of immediately inserting a new instruction with SCEVExpander::InsertCastOfTo. Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp?rev=69290&r1=69289&r2=69290&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Thu Apr 16 10:47:35 2009 @@ -1836,17 +1836,17 @@ if (L->contains(User.Inst->getParent())) User.Inst->moveBefore(LatchBlock->getTerminator()); } - if (RewriteOp->getType() != ReplacedTy) { - Instruction::CastOps opcode = - CastInst::getCastOpcode(RewriteOp, false, ReplacedTy, false); - assert(opcode != Instruction::SExt && - opcode != Instruction::ZExt && - "Unexpected widening cast!"); - RewriteOp = SCEVExpander::InsertCastOfTo(opcode, RewriteOp, ReplacedTy); - } SCEVHandle RewriteExpr = SE->getUnknown(RewriteOp); + if (TD->getTypeSizeInBits(RewriteOp->getType()) != + TD->getTypeSizeInBits(ReplacedTy)) { + assert(TD->getTypeSizeInBits(RewriteOp->getType()) > + TD->getTypeSizeInBits(ReplacedTy) && + "Unexpected widening cast!"); + RewriteExpr = SE->getTruncateExpr(RewriteExpr, ReplacedTy); + } + // If we had to insert new instructions for RewriteOp, we have to // consider that they may not have been able to end up immediately // next to RewriteOp, because non-PHI instructions may never precede From gohman at apple.com Thu Apr 16 10:48:38 2009 From: gohman at apple.com (Dan Gohman) Date: Thu, 16 Apr 2009 15:48:38 -0000 Subject: [llvm-commits] [llvm] r69291 - /llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Message-ID: <200904161548.n3GFmccX025681@zion.cs.uiuc.edu> Author: djg Date: Thu Apr 16 10:48:38 2009 New Revision: 69291 URL: http://llvm.org/viewvc/llvm-project?rev=69291&view=rev Log: Use ConstantExpr::getIntToPtr instead of SCEVExpander::InsertCastOfTo, since the operand is always a constant. Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp?rev=69291&r1=69290&r2=69291&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Thu Apr 16 10:48:38 2009 @@ -2118,9 +2118,8 @@ if (!isa(NewCmpTy)) NewCmpRHS = ConstantInt::get(NewCmpTy, NewCmpVal); else { - NewCmpRHS = ConstantInt::get(UIntPtrTy, NewCmpVal); - NewCmpRHS = SCEVExpander::InsertCastOfTo(Instruction::IntToPtr, - NewCmpRHS, NewCmpTy); + ConstantInt *CI = ConstantInt::get(UIntPtrTy, NewCmpVal); + NewCmpRHS = ConstantExpr::getIntToPtr(CI, NewCmpTy); } NewOffset = TyBits == NewTyBits ? SE->getMulExpr(CondUse->Offset, From gohman at apple.com Thu Apr 16 10:52:57 2009 From: gohman at apple.com (Dan Gohman) Date: Thu, 16 Apr 2009 15:52:57 -0000 Subject: [llvm-commits] [llvm] r69293 - in /llvm/trunk: include/llvm/Analysis/ScalarEvolutionExpander.h lib/Analysis/ScalarEvolutionExpander.cpp Message-ID: <200904161552.n3GFqw7Z025896@zion.cs.uiuc.edu> Author: djg Date: Thu Apr 16 10:52:57 2009 New Revision: 69293 URL: http://llvm.org/viewvc/llvm-project?rev=69293&view=rev Log: Teach SCEVExpander::InsertCastOfTo to avoid creating inttoptr-of-ptrtoint and ptrtoint-of-inttoptr expressions. This fixes a regression in 300.twolf. Modified: llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpander.h llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp Modified: llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpander.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpander.h?rev=69293&r1=69292&r2=69293&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpander.h (original) +++ llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpander.h Thu Apr 16 10:52:57 2009 @@ -83,8 +83,8 @@ /// InsertCastOfTo - Insert a cast of V to the specified type, doing what /// we can to share the casts. - static Value *InsertCastOfTo(Instruction::CastOps opcode, Value *V, - const Type *Ty); + Value *InsertCastOfTo(Instruction::CastOps opcode, Value *V, + const Type *Ty); /// InsertBinop - Insert the specified binary operator, doing a small amount /// of work to avoid inserting an obviously redundant operation. static Value *InsertBinop(Instruction::BinaryOps Opcode, Value *LHS, Modified: llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp?rev=69293&r1=69292&r2=69293&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp (original) +++ llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp Thu Apr 16 10:52:57 2009 @@ -26,6 +26,14 @@ if (opcode == Instruction::BitCast && V->getType() == Ty) return V; + // Short-circuit unnecessary inttoptr<->ptrtoint casts. + if (opcode == Instruction::PtrToInt && Ty == TD.getIntPtrType()) + if (IntToPtrInst *ITP = dyn_cast(V)) + return ITP->getOperand(0); + if (opcode == Instruction::IntToPtr && V->getType() == TD.getIntPtrType()) + if (PtrToIntInst *PTI = dyn_cast(V)) + return PTI->getOperand(0); + // FIXME: keep track of the cast instruction. if (Constant *C = dyn_cast(V)) return ConstantExpr::getCast(opcode, C, Ty); From gohman at apple.com Thu Apr 16 11:15:27 2009 From: gohman at apple.com (Dan Gohman) Date: Thu, 16 Apr 2009 16:15:27 -0000 Subject: [llvm-commits] [llvm] r69294 - /llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp Message-ID: <200904161615.n3GGFR5R026613@zion.cs.uiuc.edu> Author: djg Date: Thu Apr 16 11:15:25 2009 New Revision: 69294 URL: http://llvm.org/viewvc/llvm-project?rev=69294&view=rev Log: Fix SCEVExpander::visitSMaxExpr and SCEVExpander::visitUMaxExpr to not create ICmpInsts with operands of different types. This fixes a regression in Applications/d/make_dparser. Modified: llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp Modified: llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp?rev=69294&r1=69293&r2=69294&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp (original) +++ llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp Thu Apr 16 11:15:25 2009 @@ -295,9 +295,13 @@ } Value *SCEVExpander::visitSMaxExpr(SCEVSMaxExpr *S) { + const Type *Ty = S->getType(); Value *LHS = expand(S->getOperand(0)); + LHS = InsertCastOfTo(CastInst::getCastOpcode(LHS, false, Ty, false), LHS, Ty); for (unsigned i = 1; i < S->getNumOperands(); ++i) { Value *RHS = expand(S->getOperand(i)); + RHS = InsertCastOfTo(CastInst::getCastOpcode(RHS, false, Ty, false), + RHS, Ty); Value *ICmp = new ICmpInst(ICmpInst::ICMP_SGT, LHS, RHS, "tmp", InsertPt); LHS = SelectInst::Create(ICmp, LHS, RHS, "smax", InsertPt); } @@ -305,9 +309,13 @@ } Value *SCEVExpander::visitUMaxExpr(SCEVUMaxExpr *S) { + const Type *Ty = S->getType(); Value *LHS = expand(S->getOperand(0)); + LHS = InsertCastOfTo(CastInst::getCastOpcode(LHS, false, Ty, false), LHS, Ty); for (unsigned i = 1; i < S->getNumOperands(); ++i) { Value *RHS = expand(S->getOperand(i)); + RHS = InsertCastOfTo(CastInst::getCastOpcode(RHS, false, Ty, false), + RHS, Ty); Value *ICmp = new ICmpInst(ICmpInst::ICMP_UGT, LHS, RHS, "tmp", InsertPt); LHS = SelectInst::Create(ICmp, LHS, RHS, "umax", InsertPt); } From gohman at apple.com Thu Apr 16 11:46:02 2009 From: gohman at apple.com (Dan Gohman) Date: Thu, 16 Apr 2009 16:46:02 -0000 Subject: [llvm-commits] [llvm] r69295 - /llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Message-ID: <200904161646.n3GGk26R027546@zion.cs.uiuc.edu> Author: djg Date: Thu Apr 16 11:46:01 2009 New Revision: 69295 URL: http://llvm.org/viewvc/llvm-project?rev=69295&view=rev Log: LSR is no longer a GEP optimizer. It is now an IV expression optimizer, which just happen to frequently involve optimizing GEPs. Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp?rev=69295&r1=69294&r2=69295&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Thu Apr 16 11:46:01 2009 @@ -33,12 +33,11 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/CommandLine.h" -#include "llvm/Support/GetElementPtrTypeIterator.h" #include "llvm/Target/TargetLowering.h" #include using namespace llvm; -STATISTIC(NumReduced , "Number of GEPs strength reduced"); +STATISTIC(NumReduced , "Number of IV uses strength reduced"); STATISTIC(NumInserted, "Number of PHIs inserted"); STATISTIC(NumVariable, "Number of PHIs with variable strides"); STATISTIC(NumEliminated, "Number of strides eliminated"); From gohman at apple.com Thu Apr 16 11:49:49 2009 From: gohman at apple.com (Dan Gohman) Date: Thu, 16 Apr 2009 16:49:49 -0000 Subject: [llvm-commits] [llvm] r69296 - /llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Message-ID: <200904161649.n3GGnn9k027687@zion.cs.uiuc.edu> Author: djg Date: Thu Apr 16 11:49:48 2009 New Revision: 69296 URL: http://llvm.org/viewvc/llvm-project?rev=69296&view=rev Log: Minor code simplifications. Don't attempt LSR on theoretical targets with pointers larger than 64 bits, due to the code not yet being APInt clean. Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp?rev=69296&r1=69295&r2=69296&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Thu Apr 16 11:49:48 2009 @@ -489,8 +489,7 @@ return false; // Void and FP expressions cannot be reduced. // LSR is not APInt clean, do not touch integers bigger than 64-bits. - if (I->getType()->isInteger() && - I->getType()->getPrimitiveSizeInBits() > 64) + if (TD->getTypeSizeInBits(I->getType()) > 64) return false; if (!Processed.insert(I)) @@ -2075,16 +2074,11 @@ if (RequiresTypeConversion(NewCmpTy, CmpTy)) { // Check if it is possible to rewrite it using // an iv / stride of a smaller integer type. - bool TruncOk = false; - if (NewCmpTy->isInteger()) { - unsigned Bits = NewTyBits; - if (ICmpInst::isSignedPredicate(Predicate)) - --Bits; - uint64_t Mask = (1ULL << Bits) - 1; - if (((uint64_t)NewCmpVal & Mask) == (uint64_t)NewCmpVal) - TruncOk = true; - } - if (!TruncOk) + unsigned Bits = NewTyBits; + if (ICmpInst::isSignedPredicate(Predicate)) + --Bits; + uint64_t Mask = (1ULL << Bits) - 1; + if (((uint64_t)NewCmpVal & Mask) != (uint64_t)NewCmpVal) continue; } From dpatel at apple.com Thu Apr 16 12:55:30 2009 From: dpatel at apple.com (Devang Patel) Date: Thu, 16 Apr 2009 17:55:30 -0000 Subject: [llvm-commits] [llvm] r69300 - in /llvm/trunk/lib/CodeGen/SelectionDAG: FastISel.cpp SelectionDAGBuild.cpp Message-ID: <200904161755.n3GHtUP1029821@zion.cs.uiuc.edu> Author: dpatel Date: Thu Apr 16 12:55:30 2009 New Revision: 69300 URL: http://llvm.org/viewvc/llvm-project?rev=69300&view=rev Log: Do not treat beginning of inlined scope as beginning of normal function scope if the location info is missing. Insetad of doing ... if (inlined_subroutine && known_location) DW_TAG_inline_subroutine else DW_TAG_subprogram do if (inlined_subroutine) { if (known_location) DW_TAG_inline_subroutine } else { DW_TAG_subprogram } Modified: llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp?rev=69300&r1=69299&r2=69300&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp Thu Apr 16 12:55:30 2009 @@ -362,7 +362,10 @@ const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL); ID = DW->RecordInlinedFnEnd(Subprogram); if (ID) - // If ID is 0 then this was n