From: patrick Date: Sun, 24 Dec 2017 23:15:17 +0000 (+0000) Subject: Import LLVM 5.0.1 release including clang, lld and lldb. X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=34091ed6d5747c7d4acdc1ef6af75ce9b7a8adba;p=openbsd Import LLVM 5.0.1 release including clang, lld and lldb. --- diff --git a/gnu/llvm/CMakeLists.txt b/gnu/llvm/CMakeLists.txt index 8c0f5114513..960febf6007 100644 --- a/gnu/llvm/CMakeLists.txt +++ b/gnu/llvm/CMakeLists.txt @@ -26,7 +26,7 @@ if(NOT DEFINED LLVM_VERSION_MINOR) set(LLVM_VERSION_MINOR 0) endif() if(NOT DEFINED LLVM_VERSION_PATCH) - set(LLVM_VERSION_PATCH 0) + set(LLVM_VERSION_PATCH 1) endif() if(NOT DEFINED LLVM_VERSION_SUFFIX) set(LLVM_VERSION_SUFFIX "") @@ -208,10 +208,6 @@ include(VersionFromVCS) option(LLVM_APPEND_VC_REV "Embed the version control system revision id in LLVM" ON) -if( LLVM_APPEND_VC_REV ) - add_version_info_from_vcs(PACKAGE_VERSION) -endif() - set(PACKAGE_NAME LLVM) set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") set(PACKAGE_BUGREPORT "http://llvm.org/bugs/") diff --git a/gnu/llvm/docs/CMake.rst b/gnu/llvm/docs/CMake.rst index bf97e917315..b6ebf37adc9 100644 --- a/gnu/llvm/docs/CMake.rst +++ b/gnu/llvm/docs/CMake.rst @@ -248,9 +248,10 @@ LLVM-specific variables **LLVM_APPEND_VC_REV**:BOOL Embed version control revision info (svn revision number or Git revision id). - This is used among other things in the LLVM version string (stored in the - PACKAGE_VERSION macro). For this to work cmake must be invoked before the - build. Defaults to ON. + The version info is provided by the ``LLVM_REVISION`` macro in + ``llvm/include/llvm/Support/VCSRevision.h``. Developers using git who don't + need revision info can disable this option to avoid re-linking most binaries + after a branch switch. Defaults to ON. **LLVM_ENABLE_THREADS**:BOOL Build with threads support, if available. Defaults to ON. diff --git a/gnu/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h b/gnu/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h index 0b07fe9aa23..9bbda718aca 100644 --- a/gnu/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h +++ b/gnu/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h @@ -652,6 +652,12 @@ public: auto GTI = gep_type_begin(PointeeType, Operands); Type *TargetType; + + // Handle the case where the GEP instruction has a single operand, + // the basis, therefore TargetType is a nullptr. + if (Operands.empty()) + return !BaseGV ? TTI::TCC_Free : TTI::TCC_Basic; + for (auto I = Operands.begin(); I != Operands.end(); ++I, ++GTI) { TargetType = GTI.getIndexedType(); // We assume that the cost of Scalar GEP with constant index and the diff --git a/gnu/llvm/include/llvm/CodeGen/MachineRegisterInfo.h b/gnu/llvm/include/llvm/CodeGen/MachineRegisterInfo.h index 8347f00cbc7..5ef0ac90e3c 100644 --- a/gnu/llvm/include/llvm/CodeGen/MachineRegisterInfo.h +++ b/gnu/llvm/include/llvm/CodeGen/MachineRegisterInfo.h @@ -807,6 +807,14 @@ public: return getReservedRegs().test(PhysReg); } + /// Returns true when the given register unit is considered reserved. + /// + /// Register units are considered reserved when for at least one of their + /// root registers, the root register and all super registers are reserved. + /// This currently iterates the register hierarchy and may be slower than + /// expected. + bool isReservedRegUnit(unsigned Unit) const; + /// isAllocatable - Returns true when PhysReg belongs to an allocatable /// register class and it hasn't been reserved. /// diff --git a/gnu/llvm/include/llvm/IR/AutoUpgrade.h b/gnu/llvm/include/llvm/IR/AutoUpgrade.h index b42a3d3ad95..3f406f0cf19 100644 --- a/gnu/llvm/include/llvm/IR/AutoUpgrade.h +++ b/gnu/llvm/include/llvm/IR/AutoUpgrade.h @@ -51,6 +51,8 @@ namespace llvm { /// module is modified. bool UpgradeModuleFlags(Module &M); + void UpgradeSectionAttributes(Module &M); + /// If the given TBAA tag uses the scalar TBAA format, create a new node /// corresponding to the upgrade to the struct-path aware TBAA format. /// Otherwise return the \p TBAANode itself. diff --git a/gnu/llvm/include/llvm/Support/FormatVariadic.h b/gnu/llvm/include/llvm/Support/FormatVariadic.h index c1153e84dfb..408c6d8b2e0 100644 --- a/gnu/llvm/include/llvm/Support/FormatVariadic.h +++ b/gnu/llvm/include/llvm/Support/FormatVariadic.h @@ -94,6 +94,15 @@ public: Adapters.reserve(ParamCount); } + formatv_object_base(formatv_object_base const &rhs) = delete; + + formatv_object_base(formatv_object_base &&rhs) + : Fmt(std::move(rhs.Fmt)), + Adapters(), // Adapters are initialized by formatv_object + Replacements(std::move(rhs.Replacements)) { + Adapters.reserve(rhs.Adapters.size()); + }; + void format(raw_ostream &S) const { for (auto &R : Replacements) { if (R.Type == ReplacementType::Empty) @@ -149,6 +158,14 @@ public: Parameters(std::move(Params)) { Adapters = apply_tuple(create_adapters(), Parameters); } + + formatv_object(formatv_object const &rhs) = delete; + + formatv_object(formatv_object &&rhs) + : formatv_object_base(std::move(rhs)), + Parameters(std::move(rhs.Parameters)) { + Adapters = apply_tuple(create_adapters(), Parameters); + } }; // \brief Format text given a format string and replacement parameters. diff --git a/gnu/llvm/lib/AsmParser/LLParser.cpp b/gnu/llvm/lib/AsmParser/LLParser.cpp index 13679ce1d25..234805a0524 100644 --- a/gnu/llvm/lib/AsmParser/LLParser.cpp +++ b/gnu/llvm/lib/AsmParser/LLParser.cpp @@ -240,6 +240,7 @@ bool LLParser::ValidateEndOfModule() { UpgradeDebugInfo(*M); UpgradeModuleFlags(*M); + UpgradeSectionAttributes(*M); if (!Slots) return false; diff --git a/gnu/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/gnu/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 2b4970a80cd..048e3672f47 100644 --- a/gnu/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/gnu/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -264,7 +264,7 @@ Expected hasObjCCategoryInModule(BitstreamCursor &Stream) { if (convertToString(Record, 0, S)) return error("Invalid record"); // Check for the i386 and other (x86_64, ARM) conventions - if (S.find("__DATA, __objc_catlist") != std::string::npos || + if (S.find("__DATA,__objc_catlist") != std::string::npos || S.find("__OBJC,__category") != std::string::npos) return true; break; diff --git a/gnu/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/gnu/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp index 676c48fe5c6..333d14a11af 100644 --- a/gnu/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ b/gnu/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -621,6 +621,7 @@ void DwarfCompileUnit::constructAbstractSubprogramScopeDIE( auto *SP = cast(Scope->getScopeNode()); DIE *ContextDIE; + DwarfCompileUnit *ContextCU = this; if (includeMinimalInlineScopes()) ContextDIE = &getUnitDie(); @@ -631,18 +632,23 @@ void DwarfCompileUnit::constructAbstractSubprogramScopeDIE( else if (auto *SPDecl = SP->getDeclaration()) { ContextDIE = &getUnitDie(); getOrCreateSubprogramDIE(SPDecl); - } else + } else { ContextDIE = getOrCreateContextDIE(resolve(SP->getScope())); + // The scope may be shared with a subprogram that has already been + // constructed in another CU, in which case we need to construct this + // subprogram in the same CU. + ContextCU = DD->lookupCU(ContextDIE->getUnitDie()); + } // Passing null as the associated node because the abstract definition // shouldn't be found by lookup. - AbsDef = &createAndAddDIE(dwarf::DW_TAG_subprogram, *ContextDIE, nullptr); - applySubprogramAttributesToDefinition(SP, *AbsDef); + AbsDef = &ContextCU->createAndAddDIE(dwarf::DW_TAG_subprogram, *ContextDIE, nullptr); + ContextCU->applySubprogramAttributesToDefinition(SP, *AbsDef); - if (!includeMinimalInlineScopes()) - addUInt(*AbsDef, dwarf::DW_AT_inline, None, dwarf::DW_INL_inlined); - if (DIE *ObjectPointer = createAndAddScopeChildren(Scope, *AbsDef)) - addDIEEntry(*AbsDef, dwarf::DW_AT_object_pointer, *ObjectPointer); + if (!ContextCU->includeMinimalInlineScopes()) + ContextCU->addUInt(*AbsDef, dwarf::DW_AT_inline, None, dwarf::DW_INL_inlined); + if (DIE *ObjectPointer = ContextCU->createAndAddScopeChildren(Scope, *AbsDef)) + ContextCU->addDIEEntry(*AbsDef, dwarf::DW_AT_object_pointer, *ObjectPointer); } DIE *DwarfCompileUnit::constructImportedEntityDIE( diff --git a/gnu/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h b/gnu/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h index 5dfe06c64ec..78ee9a16202 100644 --- a/gnu/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/gnu/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -283,7 +283,7 @@ class DwarfDebug : public DebugHandlerBase { // 0, referencing the comp_dir of all the type units that use it. MCDwarfDwoLineTable SplitTypeUnitFileTable; /// @} - + /// True iff there are multiple CUs in this module. bool SingleCU; bool IsDarwin; @@ -562,6 +562,9 @@ public: bool isLexicalScopeDIENull(LexicalScope *Scope); bool hasDwarfPubSections(bool includeMinimalInlineScopes) const; + + /// Find the matching DwarfCompileUnit for the given CU DIE. + DwarfCompileUnit *lookupCU(const DIE *Die) { return CUDieMap.lookup(Die); } }; } // End of namespace llvm diff --git a/gnu/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp b/gnu/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp index fe38ee80568..3a8568cf39a 100644 --- a/gnu/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp +++ b/gnu/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp @@ -131,13 +131,12 @@ bool DwarfExpression::addMachineReg(const TargetRegisterInfo &TRI, // Intersection between the bits we already emitted and the bits // covered by this subregister. - SmallBitVector Intersection(RegSize, false); - Intersection.set(Offset, Offset + Size); - Intersection ^= Coverage; + SmallBitVector CurSubReg(RegSize, false); + CurSubReg.set(Offset, Offset + Size); // If this sub-register has a DWARF number and we haven't covered // its range, emit a DWARF piece for it. - if (Reg >= 0 && Intersection.any()) { + if (Reg >= 0 && CurSubReg.test(Coverage)) { // Emit a piece for any gap in the coverage. if (Offset > CurPos) DwarfRegs.push_back({-1, Offset - CurPos, nullptr}); diff --git a/gnu/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp b/gnu/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp index 471dcea4bb3..0e240f482a1 100644 --- a/gnu/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp +++ b/gnu/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp @@ -269,8 +269,9 @@ void LiveIntervals::computeRegUnitRange(LiveRange &LR, unsigned Unit) { // may share super-registers. That's OK because createDeadDefs() is // idempotent. It is very rare for a register unit to have multiple roots, so // uniquing super-registers is probably not worthwhile. - bool IsReserved = true; + bool IsReserved = false; for (MCRegUnitRootIterator Root(Unit, TRI); Root.isValid(); ++Root) { + bool IsRootReserved = true; for (MCSuperRegIterator Super(*Root, TRI, /*IncludeSelf=*/true); Super.isValid(); ++Super) { unsigned Reg = *Super; @@ -279,9 +280,12 @@ void LiveIntervals::computeRegUnitRange(LiveRange &LR, unsigned Unit) { // A register unit is considered reserved if all its roots and all their // super registers are reserved. if (!MRI->isReserved(Reg)) - IsReserved = false; + IsRootReserved = false; } + IsReserved |= IsRootReserved; } + assert(IsReserved == MRI->isReservedRegUnit(Unit) && + "reserved computation mismatch"); // Now extend LR to reach all uses. // Ignore uses of reserved registers. We only track defs of those. @@ -924,7 +928,7 @@ public: // kill flags. This is wasteful. Eventually, LiveVariables will strip all kill // flags, and postRA passes will use a live register utility instead. LiveRange *getRegUnitLI(unsigned Unit) { - if (UpdateFlags) + if (UpdateFlags && !MRI.isReservedRegUnit(Unit)) return &LIS.getRegUnit(Unit); return LIS.getCachedRegUnit(Unit); } diff --git a/gnu/llvm/lib/CodeGen/MachineRegisterInfo.cpp b/gnu/llvm/lib/CodeGen/MachineRegisterInfo.cpp index 9a92ee279cd..be06053f004 100644 --- a/gnu/llvm/lib/CodeGen/MachineRegisterInfo.cpp +++ b/gnu/llvm/lib/CodeGen/MachineRegisterInfo.cpp @@ -601,3 +601,21 @@ void MachineRegisterInfo::setCalleeSavedRegs(ArrayRef CSRs) { UpdatedCSRs.push_back(0); IsUpdatedCSRsInitialized = true; } + +bool MachineRegisterInfo::isReservedRegUnit(unsigned Unit) const { + const TargetRegisterInfo *TRI = getTargetRegisterInfo(); + for (MCRegUnitRootIterator Root(Unit, TRI); Root.isValid(); ++Root) { + bool IsRootReserved = true; + for (MCSuperRegIterator Super(*Root, TRI, /*IncludeSelf=*/true); + Super.isValid(); ++Super) { + unsigned Reg = *Super; + if (!isReserved(Reg)) { + IsRootReserved = false; + break; + } + } + if (IsRootReserved) + return true; + } + return false; +} diff --git a/gnu/llvm/lib/CodeGen/MachineVerifier.cpp b/gnu/llvm/lib/CodeGen/MachineVerifier.cpp index fcb544806dd..c50a95a0650 100644 --- a/gnu/llvm/lib/CodeGen/MachineVerifier.cpp +++ b/gnu/llvm/lib/CodeGen/MachineVerifier.cpp @@ -1316,6 +1316,8 @@ void MachineVerifier::checkLiveness(const MachineOperand *MO, unsigned MONum) { // Check the cached regunit intervals. if (TargetRegisterInfo::isPhysicalRegister(Reg) && !isReserved(Reg)) { for (MCRegUnitIterator Units(Reg, TRI); Units.isValid(); ++Units) { + if (MRI->isReservedRegUnit(*Units)) + continue; if (const LiveRange *LR = LiveInts->getCachedRegUnit(*Units)) checkLivenessAtUse(MO, MONum, UseIdx, *LR, *Units); } diff --git a/gnu/llvm/lib/IR/AutoUpgrade.cpp b/gnu/llvm/lib/IR/AutoUpgrade.cpp index a501799b479..80640def955 100644 --- a/gnu/llvm/lib/IR/AutoUpgrade.cpp +++ b/gnu/llvm/lib/IR/AutoUpgrade.cpp @@ -2271,6 +2271,24 @@ bool llvm::UpgradeModuleFlags(Module &M) { } } } + // Upgrade Objective-C Image Info Section. Removed the whitespce in the + // section name so that llvm-lto will not complain about mismatching + // module flags that is functionally the same. + if (ID->getString() == "Objective-C Image Info Section") { + if (auto *Value = dyn_cast_or_null(Op->getOperand(2))) { + SmallVector ValueComp; + Value->getString().split(ValueComp, " "); + if (ValueComp.size() != 1) { + std::string NewValue; + for (auto &S : ValueComp) + NewValue += S.str(); + Metadata *Ops[3] = {Op->getOperand(0), Op->getOperand(1), + MDString::get(M.getContext(), NewValue)}; + ModFlags->setOperand(I, MDNode::get(M.getContext(), Ops)); + Changed = true; + } + } + } } // "Objective-C Class Properties" is recently added for Objective-C. We @@ -2287,6 +2305,35 @@ bool llvm::UpgradeModuleFlags(Module &M) { return Changed; } +void llvm::UpgradeSectionAttributes(Module &M) { + auto TrimSpaces = [](StringRef Section) -> std::string { + SmallVector Components; + Section.split(Components, ','); + + SmallString<32> Buffer; + raw_svector_ostream OS(Buffer); + + for (auto Component : Components) + OS << ',' << Component.trim(); + + return OS.str().substr(1); + }; + + for (auto &GV : M.globals()) { + if (!GV.hasSection()) + continue; + + StringRef Section = GV.getSection(); + + if (!Section.startswith("__DATA, __objc_catlist")) + continue; + + // __DATA, __objc_catlist, regular, no_dead_strip + // __DATA,__objc_catlist,regular,no_dead_strip + GV.setSection(TrimSpaces(Section)); + } +} + static bool isOldLoopArgument(Metadata *MD) { auto *T = dyn_cast_or_null(MD); if (!T) diff --git a/gnu/llvm/lib/IR/ConstantFold.cpp b/gnu/llvm/lib/IR/ConstantFold.cpp index 311b0a76ce8..996331e68e8 100644 --- a/gnu/llvm/lib/IR/ConstantFold.cpp +++ b/gnu/llvm/lib/IR/ConstantFold.cpp @@ -2199,6 +2199,9 @@ Constant *llvm::ConstantFoldGetElementPtr(Type *PointeeTy, Constant *C, Unknown = true; continue; } + if (!isa(Idxs[i - 1])) + // FIXME: add the support of cosntant vector index. + continue; if (InRangeIndex && i == *InRangeIndex + 1) { // If an index is marked inrange, we cannot apply this canonicalization to // the following index, as that will cause the inrange index to point to diff --git a/gnu/llvm/lib/Linker/IRMover.cpp b/gnu/llvm/lib/Linker/IRMover.cpp index f486e525b5e..ee067a912e3 100644 --- a/gnu/llvm/lib/Linker/IRMover.cpp +++ b/gnu/llvm/lib/Linker/IRMover.cpp @@ -640,6 +640,10 @@ GlobalValue *IRLinker::copyGlobalValueProto(const GlobalValue *SGV, } else { if (ForDefinition) NewGV = copyGlobalAliasProto(cast(SGV)); + else if (SGV->getValueType()->isFunctionTy()) + NewGV = + Function::Create(cast(TypeMap.get(SGV->getValueType())), + GlobalValue::ExternalLinkage, SGV->getName(), &DstM); else NewGV = new GlobalVariable( DstM, TypeMap.get(SGV->getValueType()), diff --git a/gnu/llvm/lib/Linker/LinkModules.cpp b/gnu/llvm/lib/Linker/LinkModules.cpp index c0ce4bf76b9..25f31a3401a 100644 --- a/gnu/llvm/lib/Linker/LinkModules.cpp +++ b/gnu/llvm/lib/Linker/LinkModules.cpp @@ -329,8 +329,18 @@ bool ModuleLinker::shouldLinkFromSource(bool &LinkFromSrc, bool ModuleLinker::linkIfNeeded(GlobalValue &GV) { GlobalValue *DGV = getLinkedToGlobal(&GV); - if (shouldLinkOnlyNeeded() && !(DGV && DGV->isDeclaration())) - return false; + if (shouldLinkOnlyNeeded()) { + // Always import variables with appending linkage. + if (!GV.hasAppendingLinkage()) { + // Don't import globals unless they are referenced by the destination + // module. + if (!DGV) + return false; + // Don't import globals that are already defined in the destination module + if (!DGV->isDeclaration()) + return false; + } + } if (DGV && !GV.hasLocalLinkage() && !GV.hasAppendingLinkage()) { auto *DGVar = dyn_cast(DGV); diff --git a/gnu/llvm/lib/Support/Host.cpp b/gnu/llvm/lib/Support/Host.cpp index 5cf0316d4d7..f1c0d3ac32d 100644 --- a/gnu/llvm/lib/Support/Host.cpp +++ b/gnu/llvm/lib/Support/Host.cpp @@ -208,6 +208,7 @@ StringRef sys::detail::getHostCPUNameForARM( .Case("0x06f", "krait") // APQ8064 .Case("0x201", "kryo") .Case("0x205", "kryo") + .Case("0xc00", "falkor") .Default("generic"); return "generic"; diff --git a/gnu/llvm/lib/Target/AArch64/AArch64FalkorHWPFFix.cpp b/gnu/llvm/lib/Target/AArch64/AArch64FalkorHWPFFix.cpp index c0e22355a9f..2c887a9ca5d 100644 --- a/gnu/llvm/lib/Target/AArch64/AArch64FalkorHWPFFix.cpp +++ b/gnu/llvm/lib/Target/AArch64/AArch64FalkorHWPFFix.cpp @@ -220,27 +220,27 @@ static Optional getLoadInfo(const MachineInstr &MI) { default: return None; + case AArch64::LD1i64: + case AArch64::LD2i64: + DestRegIdx = 0; + BaseRegIdx = 3; + OffsetIdx = -1; + IsPrePost = false; + break; + case AArch64::LD1i8: case AArch64::LD1i16: case AArch64::LD1i32: - case AArch64::LD1i64: case AArch64::LD2i8: case AArch64::LD2i16: case AArch64::LD2i32: - case AArch64::LD2i64: case AArch64::LD3i8: case AArch64::LD3i16: case AArch64::LD3i32: + case AArch64::LD3i64: case AArch64::LD4i8: case AArch64::LD4i16: case AArch64::LD4i32: - DestRegIdx = 0; - BaseRegIdx = 3; - OffsetIdx = -1; - IsPrePost = false; - break; - - case AArch64::LD3i64: case AArch64::LD4i64: DestRegIdx = -1; BaseRegIdx = 3; @@ -264,23 +264,16 @@ static Optional getLoadInfo(const MachineInstr &MI) { case AArch64::LD1Rv4s: case AArch64::LD1Rv8h: case AArch64::LD1Rv16b: - case AArch64::LD1Twov1d: - case AArch64::LD1Twov2s: - case AArch64::LD1Twov4h: - case AArch64::LD1Twov8b: - case AArch64::LD2Twov2s: - case AArch64::LD2Twov4s: - case AArch64::LD2Twov8b: - case AArch64::LD2Rv1d: - case AArch64::LD2Rv2s: - case AArch64::LD2Rv4s: - case AArch64::LD2Rv8b: DestRegIdx = 0; BaseRegIdx = 1; OffsetIdx = -1; IsPrePost = false; break; + case AArch64::LD1Twov1d: + case AArch64::LD1Twov2s: + case AArch64::LD1Twov4h: + case AArch64::LD1Twov8b: case AArch64::LD1Twov2d: case AArch64::LD1Twov4s: case AArch64::LD1Twov8h: @@ -301,10 +294,17 @@ static Optional getLoadInfo(const MachineInstr &MI) { case AArch64::LD1Fourv4s: case AArch64::LD1Fourv8h: case AArch64::LD1Fourv16b: + case AArch64::LD2Twov2s: + case AArch64::LD2Twov4s: + case AArch64::LD2Twov8b: case AArch64::LD2Twov2d: case AArch64::LD2Twov4h: case AArch64::LD2Twov8h: case AArch64::LD2Twov16b: + case AArch64::LD2Rv1d: + case AArch64::LD2Rv2s: + case AArch64::LD2Rv4s: + case AArch64::LD2Rv8b: case AArch64::LD2Rv2d: case AArch64::LD2Rv4h: case AArch64::LD2Rv8h: @@ -345,32 +345,32 @@ static Optional getLoadInfo(const MachineInstr &MI) { IsPrePost = false; break; + case AArch64::LD1i64_POST: + case AArch64::LD2i64_POST: + DestRegIdx = 1; + BaseRegIdx = 4; + OffsetIdx = 5; + IsPrePost = true; + break; + case AArch64::LD1i8_POST: case AArch64::LD1i16_POST: case AArch64::LD1i32_POST: - case AArch64::LD1i64_POST: case AArch64::LD2i8_POST: case AArch64::LD2i16_POST: case AArch64::LD2i32_POST: - case AArch64::LD2i64_POST: case AArch64::LD3i8_POST: case AArch64::LD3i16_POST: case AArch64::LD3i32_POST: + case AArch64::LD3i64_POST: case AArch64::LD4i8_POST: case AArch64::LD4i16_POST: case AArch64::LD4i32_POST: - DestRegIdx = 1; - BaseRegIdx = 4; - OffsetIdx = 5; - IsPrePost = false; - break; - - case AArch64::LD3i64_POST: case AArch64::LD4i64_POST: DestRegIdx = -1; BaseRegIdx = 4; OffsetIdx = 5; - IsPrePost = false; + IsPrePost = true; break; case AArch64::LD1Onev1d_POST: @@ -389,23 +389,16 @@ static Optional getLoadInfo(const MachineInstr &MI) { case AArch64::LD1Rv4s_POST: case AArch64::LD1Rv8h_POST: case AArch64::LD1Rv16b_POST: - case AArch64::LD1Twov1d_POST: - case AArch64::LD1Twov2s_POST: - case AArch64::LD1Twov4h_POST: - case AArch64::LD1Twov8b_POST: - case AArch64::LD2Twov2s_POST: - case AArch64::LD2Twov4s_POST: - case AArch64::LD2Twov8b_POST: - case AArch64::LD2Rv1d_POST: - case AArch64::LD2Rv2s_POST: - case AArch64::LD2Rv4s_POST: - case AArch64::LD2Rv8b_POST: DestRegIdx = 1; BaseRegIdx = 2; OffsetIdx = 3; - IsPrePost = false; + IsPrePost = true; break; + case AArch64::LD1Twov1d_POST: + case AArch64::LD1Twov2s_POST: + case AArch64::LD1Twov4h_POST: + case AArch64::LD1Twov8b_POST: case AArch64::LD1Twov2d_POST: case AArch64::LD1Twov4s_POST: case AArch64::LD1Twov8h_POST: @@ -426,10 +419,17 @@ static Optional getLoadInfo(const MachineInstr &MI) { case AArch64::LD1Fourv4s_POST: case AArch64::LD1Fourv8h_POST: case AArch64::LD1Fourv16b_POST: + case AArch64::LD2Twov2s_POST: + case AArch64::LD2Twov4s_POST: + case AArch64::LD2Twov8b_POST: case AArch64::LD2Twov2d_POST: case AArch64::LD2Twov4h_POST: case AArch64::LD2Twov8h_POST: case AArch64::LD2Twov16b_POST: + case AArch64::LD2Rv1d_POST: + case AArch64::LD2Rv2s_POST: + case AArch64::LD2Rv4s_POST: + case AArch64::LD2Rv8b_POST: case AArch64::LD2Rv2d_POST: case AArch64::LD2Rv4h_POST: case AArch64::LD2Rv8h_POST: @@ -467,7 +467,7 @@ static Optional getLoadInfo(const MachineInstr &MI) { DestRegIdx = -1; BaseRegIdx = 2; OffsetIdx = 3; - IsPrePost = false; + IsPrePost = true; break; case AArch64::LDRBBroW: @@ -572,8 +572,12 @@ static Optional getLoadInfo(const MachineInstr &MI) { IsPrePost = true; break; - case AArch64::LDPDi: + case AArch64::LDNPDi: + case AArch64::LDNPQi: + case AArch64::LDNPSi: case AArch64::LDPQi: + case AArch64::LDPDi: + case AArch64::LDPSi: DestRegIdx = -1; BaseRegIdx = 2; OffsetIdx = 3; @@ -581,7 +585,6 @@ static Optional getLoadInfo(const MachineInstr &MI) { break; case AArch64::LDPSWi: - case AArch64::LDPSi: case AArch64::LDPWi: case AArch64::LDPXi: DestRegIdx = 0; @@ -592,18 +595,18 @@ static Optional getLoadInfo(const MachineInstr &MI) { case AArch64::LDPQpost: case AArch64::LDPQpre: + case AArch64::LDPDpost: + case AArch64::LDPDpre: + case AArch64::LDPSpost: + case AArch64::LDPSpre: DestRegIdx = -1; BaseRegIdx = 3; OffsetIdx = 4; IsPrePost = true; break; - case AArch64::LDPDpost: - case AArch64::LDPDpre: case AArch64::LDPSWpost: case AArch64::LDPSWpre: - case AArch64::LDPSpost: - case AArch64::LDPSpre: case AArch64::LDPWpost: case AArch64::LDPWpre: case AArch64::LDPXpost: @@ -687,9 +690,14 @@ void FalkorHWPFFix::runOnLoop(MachineLoop &L, MachineFunction &Fn) { if (!TII->isStridedAccess(MI)) continue; - LoadInfo LdI = *getLoadInfo(MI); - unsigned OldTag = *getTag(TRI, MI, LdI); - auto &OldCollisions = TagMap[OldTag]; + Optional OptLdI = getLoadInfo(MI); + if (!OptLdI) + continue; + LoadInfo LdI = *OptLdI; + Optional OptOldTag = getTag(TRI, MI, LdI); + if (!OptOldTag) + continue; + auto &OldCollisions = TagMap[*OptOldTag]; if (OldCollisions.size() <= 1) continue; diff --git a/gnu/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/gnu/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp index c0c6055c358..13c80a46e5b 100644 --- a/gnu/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp +++ b/gnu/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp @@ -940,6 +940,12 @@ bool AArch64InstrInfo::areMemAccessesTriviallyDisjoint( bool AArch64InstrInfo::analyzeCompare(const MachineInstr &MI, unsigned &SrcReg, unsigned &SrcReg2, int &CmpMask, int &CmpValue) const { + // The first operand can be a frame index where we'd normally expect a + // register. + assert(MI.getNumOperands() >= 2 && "All AArch64 cmps should have 2 operands"); + if (!MI.getOperand(1).isReg()) + return false; + switch (MI.getOpcode()) { default: break; diff --git a/gnu/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/gnu/llvm/lib/Target/AArch64/AArch64InstrInfo.td index 5049a39814f..59719978a3a 100644 --- a/gnu/llvm/lib/Target/AArch64/AArch64InstrInfo.td +++ b/gnu/llvm/lib/Target/AArch64/AArch64InstrInfo.td @@ -441,8 +441,7 @@ def MSRpstateImm1 : MSRpstateImm0_1; def MSRpstateImm4 : MSRpstateImm0_15; // The thread pointer (on Linux, at least, where this has been implemented) is -// TPIDR_EL0. Add pseudo op so we can mark it as not having any side effects. -let hasSideEffects = 0 in +// TPIDR_EL0. def MOVbaseTLS : Pseudo<(outs GPR64:$dst), (ins), [(set GPR64:$dst, AArch64threadpointer)]>, Sched<[WriteSys]>; diff --git a/gnu/llvm/lib/Target/AArch64/AArch64RedundantCopyElimination.cpp b/gnu/llvm/lib/Target/AArch64/AArch64RedundantCopyElimination.cpp index 4e65c0ab601..22c11c7276d 100644 --- a/gnu/llvm/lib/Target/AArch64/AArch64RedundantCopyElimination.cpp +++ b/gnu/llvm/lib/Target/AArch64/AArch64RedundantCopyElimination.cpp @@ -167,6 +167,9 @@ AArch64RedundantCopyElimination::knownRegValInBlock( // CMP is an alias for SUBS with a dead destination register. case AArch64::SUBSWri: case AArch64::SUBSXri: { + // Sometimes the first operand is a FrameIndex. Bail if tht happens. + if (!PredI.getOperand(1).isReg()) + return None; MCPhysReg SrcReg = PredI.getOperand(1).getReg(); // Must not be a symbolic immediate. diff --git a/gnu/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.cpp b/gnu/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.cpp index cd9e7fb04f1..025397b1eac 100644 --- a/gnu/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.cpp +++ b/gnu/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.cpp @@ -218,12 +218,17 @@ void GCNHazardRecognizer::RecedeCycle() { int GCNHazardRecognizer::getWaitStatesSince( function_ref IsHazard) { - int WaitStates = -1; + int WaitStates = 0; for (MachineInstr *MI : EmittedInstrs) { + if (MI) { + if (IsHazard(MI)) + return WaitStates; + + unsigned Opcode = MI->getOpcode(); + if (Opcode == AMDGPU::DBG_VALUE || Opcode == AMDGPU::IMPLICIT_DEF) + continue; + } ++WaitStates; - if (!MI || !IsHazard(MI)) - continue; - return WaitStates; } return std::numeric_limits::max(); } diff --git a/gnu/llvm/lib/Target/ARM/ARMAsmPrinter.cpp b/gnu/llvm/lib/Target/ARM/ARMAsmPrinter.cpp index 582153daebd..b24d3420d1d 100644 --- a/gnu/llvm/lib/Target/ARM/ARMAsmPrinter.cpp +++ b/gnu/llvm/lib/Target/ARM/ARMAsmPrinter.cpp @@ -1276,6 +1276,7 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) { // Add 's' bit operand (always reg0 for this) .addReg(0)); + assert(Subtarget->hasV4TOps()); EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::BX) .addReg(MI->getOperand(0).getReg())); return; @@ -1896,6 +1897,7 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) { .addImm(ARMCC::AL) .addReg(0)); + assert(Subtarget->hasV4TOps()); EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::BX) .addReg(ScratchReg) // Predicate. diff --git a/gnu/llvm/lib/Target/ARM/ARMCallLowering.cpp b/gnu/llvm/lib/Target/ARM/ARMCallLowering.cpp index 051827a6a6a..a1a31e1e7fa 100644 --- a/gnu/llvm/lib/Target/ARM/ARMCallLowering.cpp +++ b/gnu/llvm/lib/Target/ARM/ARMCallLowering.cpp @@ -251,7 +251,9 @@ bool ARMCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder, const Value *Val, unsigned VReg) const { assert(!Val == !VReg && "Return value without a vreg"); - auto Ret = MIRBuilder.buildInstrNoInsert(ARM::BX_RET).add(predOps(ARMCC::AL)); + auto const &ST = MIRBuilder.getMF().getSubtarget(); + unsigned Opcode = ST.getReturnOpcode(); + auto Ret = MIRBuilder.buildInstrNoInsert(Opcode).add(predOps(ARMCC::AL)); if (!lowerReturnVal(MIRBuilder, Val, VReg, Ret)) return false; diff --git a/gnu/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp b/gnu/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp index 46d8f0dba69..376727729d8 100644 --- a/gnu/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp +++ b/gnu/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp @@ -1030,8 +1030,11 @@ bool ARMExpandPseudo::ExpandMI(MachineBasicBlock &MBB, if (STI->isThumb()) MIB.add(predOps(ARMCC::AL)); } else if (RetOpcode == ARM::TCRETURNri) { + unsigned Opcode = + STI->isThumb() ? ARM::tTAILJMPr + : (STI->hasV4TOps() ? ARM::TAILJMPr : ARM::TAILJMPr4); BuildMI(MBB, MBBI, dl, - TII.get(STI->isThumb() ? ARM::tTAILJMPr : ARM::TAILJMPr)) + TII.get(Opcode)) .addReg(JumpTarget.getReg(), RegState::Kill); } diff --git a/gnu/llvm/lib/Target/ARM/ARMFastISel.cpp b/gnu/llvm/lib/Target/ARM/ARMFastISel.cpp index bf00ef61c2d..5dc93734ab5 100644 --- a/gnu/llvm/lib/Target/ARM/ARMFastISel.cpp +++ b/gnu/llvm/lib/Target/ARM/ARMFastISel.cpp @@ -1332,6 +1332,8 @@ bool ARMFastISel::SelectIndirectBr(const Instruction *I) { if (AddrReg == 0) return false; unsigned Opc = isThumb2 ? ARM::tBRIND : ARM::BX; + assert(isThumb2 || Subtarget->hasV4TOps()); + AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc)).addReg(AddrReg)); @@ -2168,9 +2170,8 @@ bool ARMFastISel::SelectRet(const Instruction *I) { RetRegs.push_back(VA.getLocReg()); } - unsigned RetOpc = isThumb2 ? ARM::tBX_RET : ARM::BX_RET; MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, - TII.get(RetOpc)); + TII.get(Subtarget->getReturnOpcode())); AddOptionalDefs(MIB); for (unsigned R : RetRegs) MIB.addReg(R, RegState::Implicit); diff --git a/gnu/llvm/lib/Target/ARM/ARMFrameLowering.cpp b/gnu/llvm/lib/Target/ARM/ARMFrameLowering.cpp index 16b54e8848c..00b788a1b53 100644 --- a/gnu/llvm/lib/Target/ARM/ARMFrameLowering.cpp +++ b/gnu/llvm/lib/Target/ARM/ARMFrameLowering.cpp @@ -479,7 +479,7 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF, if (DPRCSSize > 0) { // Since vpush register list cannot have gaps, there may be multiple vpush // instructions in the prologue. - while (MBBI->getOpcode() == ARM::VSTMDDB_UPD) { + while (MBBI != MBB.end() && MBBI->getOpcode() == ARM::VSTMDDB_UPD) { DefCFAOffsetCandidates.addInst(MBBI, sizeOfSPAdjustment(*MBBI)); LastPush = MBBI++; } @@ -2397,9 +2397,8 @@ void ARMFrameLowering::adjustForSegmentedStacks( BuildMI(AllocMBB, DL, TII.get(TargetOpcode::CFI_INSTRUCTION)) .addCFIIndex(CFIIndex); - // bx lr - Return from this function. - Opcode = Thumb ? ARM::tBX_RET : ARM::BX_RET; - BuildMI(AllocMBB, DL, TII.get(Opcode)).add(predOps(ARMCC::AL)); + // Return from this function. + BuildMI(AllocMBB, DL, TII.get(ST->getReturnOpcode())).add(predOps(ARMCC::AL)); // Restore SR0 and SR1 in case of __morestack() was not called. // pop {SR0, SR1} diff --git a/gnu/llvm/lib/Target/ARM/ARMInstrInfo.td b/gnu/llvm/lib/Target/ARM/ARMInstrInfo.td index 7206083a707..c488cd347fe 100644 --- a/gnu/llvm/lib/Target/ARM/ARMInstrInfo.td +++ b/gnu/llvm/lib/Target/ARM/ARMInstrInfo.td @@ -2425,7 +2425,7 @@ let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [SP] in { def TAILJMPr : ARMPseudoExpand<(outs), (ins tcGPR:$dst), 4, IIC_Br, [], (BX GPR:$dst)>, Sched<[WriteBr]>, - Requires<[IsARM]>; + Requires<[IsARM, HasV4T]>; } // Secure Monitor Call is a system instruction. @@ -5589,6 +5589,12 @@ let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in (MOVr PC, GPR:$dst, (ops 14, zero_reg), zero_reg)>, Requires<[IsARM, NoV4T]>, Sched<[WriteBr]>; +let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [SP] in + def TAILJMPr4 : ARMPseudoExpand<(outs), (ins GPR:$dst), + 4, IIC_Br, [], + (MOVr PC, GPR:$dst, (ops 14, zero_reg), zero_reg)>, + Requires<[IsARM, NoV4T]>, Sched<[WriteBr]>; + // Large immediate handling. // 32-bit immediate using two piece mod_imms or movw + movt. diff --git a/gnu/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp b/gnu/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp index 7a452d4a209..5d57b6803c0 100644 --- a/gnu/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp +++ b/gnu/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp @@ -1909,6 +1909,7 @@ bool ARMLoadStoreOpt::CombineMovBx(MachineBasicBlock &MBB) { for (auto Use : Prev->uses()) if (Use.isKill()) { + assert(STI->hasV4TOps()); BuildMI(MBB, MBBI, MBBI->getDebugLoc(), TII->get(ARM::tBX)) .addReg(Use.getReg(), RegState::Kill) .add(predOps(ARMCC::AL)) diff --git a/gnu/llvm/lib/Target/ARM/ARMSubtarget.h b/gnu/llvm/lib/Target/ARM/ARMSubtarget.h index e15b17512c9..9d749537dc3 100644 --- a/gnu/llvm/lib/Target/ARM/ARMSubtarget.h +++ b/gnu/llvm/lib/Target/ARM/ARMSubtarget.h @@ -729,6 +729,17 @@ public: /// True if fast-isel is used. bool useFastISel() const; + + /// Returns the correct return opcode for the current feature set. + /// Use BX if available to allow mixing thumb/arm code, but fall back + /// to plain mov pc,lr on ARMv4. + unsigned getReturnOpcode() const { + if (isThumb()) + return ARM::tBX_RET; + if (hasV4TOps()) + return ARM::BX_RET; + return ARM::MOVPCLR; + } }; } // end namespace llvm diff --git a/gnu/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp b/gnu/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp index b8a8b1f7619..2ab7bfe4410 100644 --- a/gnu/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp +++ b/gnu/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp @@ -142,9 +142,9 @@ std::string ARM_MC::ParseARMTriple(const Triple &TT, StringRef CPU) { if (isThumb) { if (ARMArchFeature.empty()) - ARMArchFeature = "+thumb-mode"; + ARMArchFeature = "+thumb-mode,+v4t"; else - ARMArchFeature += ",+thumb-mode"; + ARMArchFeature += ",+thumb-mode,+v4t"; } if (TT.isOSNaCl()) { diff --git a/gnu/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp b/gnu/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp index 540e05a9299..d6f85edae47 100644 --- a/gnu/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp +++ b/gnu/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp @@ -583,8 +583,8 @@ bool AVRExpandPseudo::expand(Block &MBB, BlockIt MBBI) { unsigned TmpReg = 0; // 0 for no temporary register unsigned SrcReg = MI.getOperand(1).getReg(); bool SrcIsKill = MI.getOperand(1).isKill(); - OpLo = AVR::LDRdPtr; - OpHi = AVR::LDDRdPtrQ; + OpLo = AVR::LDRdPtrPi; + OpHi = AVR::LDRdPtr; TRI->splitReg(DstReg, DstLoReg, DstHiReg); // Use a temporary register if src and dst registers are the same. @@ -597,6 +597,7 @@ bool AVRExpandPseudo::expand(Block &MBB, BlockIt MBBI) { // Load low byte. auto MIBLO = buildMI(MBB, MBBI, OpLo) .addReg(CurDstLoReg, RegState::Define) + .addReg(SrcReg, RegState::Define) .addReg(SrcReg); // Push low byte onto stack if necessary. @@ -606,8 +607,7 @@ bool AVRExpandPseudo::expand(Block &MBB, BlockIt MBBI) { // Load high byte. auto MIBHI = buildMI(MBB, MBBI, OpHi) .addReg(CurDstHiReg, RegState::Define) - .addReg(SrcReg, getKillRegState(SrcIsKill)) - .addImm(1); + .addReg(SrcReg, getKillRegState(SrcIsKill)); if (TmpReg) { // Move the high byte into the final destination. @@ -699,7 +699,9 @@ bool AVRExpandPseudo::expand(Block &MBB, BlockIt MBBI) { OpHi = AVR::LDDRdPtrQ; TRI->splitReg(DstReg, DstLoReg, DstHiReg); - assert(Imm <= 63 && "Offset is out of range"); + // Since we add 1 to the Imm value for the high byte below, and 63 is the highest Imm value + // allowed for the instruction, 62 is the limit here. + assert(Imm <= 62 && "Offset is out of range"); // Use a temporary register if src and dst registers are the same. if (DstReg == SrcReg) @@ -741,7 +743,50 @@ bool AVRExpandPseudo::expand(Block &MBB, BlockIt MBBI) { template <> bool AVRExpandPseudo::expand(Block &MBB, BlockIt MBBI) { - llvm_unreachable("wide LPM is unimplemented"); + MachineInstr &MI = *MBBI; + unsigned OpLo, OpHi, DstLoReg, DstHiReg; + unsigned DstReg = MI.getOperand(0).getReg(); + unsigned TmpReg = 0; // 0 for no temporary register + unsigned SrcReg = MI.getOperand(1).getReg(); + bool SrcIsKill = MI.getOperand(1).isKill(); + OpLo = AVR::LPMRdZPi; + OpHi = AVR::LPMRdZ; + TRI->splitReg(DstReg, DstLoReg, DstHiReg); + + // Use a temporary register if src and dst registers are the same. + if (DstReg == SrcReg) + TmpReg = scavengeGPR8(MI); + + unsigned CurDstLoReg = (DstReg == SrcReg) ? TmpReg : DstLoReg; + unsigned CurDstHiReg = (DstReg == SrcReg) ? TmpReg : DstHiReg; + + // Load low byte. + auto MIBLO = buildMI(MBB, MBBI, OpLo) + .addReg(CurDstLoReg, RegState::Define) + .addReg(SrcReg); + + // Push low byte onto stack if necessary. + if (TmpReg) + buildMI(MBB, MBBI, AVR::PUSHRr).addReg(TmpReg); + + // Load high byte. + auto MIBHI = buildMI(MBB, MBBI, OpHi) + .addReg(CurDstHiReg, RegState::Define) + .addReg(SrcReg, getKillRegState(SrcIsKill)); + + if (TmpReg) { + // Move the high byte into the final destination. + buildMI(MBB, MBBI, AVR::MOVRdRr).addReg(DstHiReg).addReg(TmpReg); + + // Move the low byte from the scratch space into the final destination. + buildMI(MBB, MBBI, AVR::POPRd).addReg(DstLoReg); + } + + MIBLO->setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); + MIBHI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); + + MI.eraseFromParent(); + return true; } template <> @@ -1074,7 +1119,9 @@ bool AVRExpandPseudo::expand(Block &MBB, BlockIt MBBI) { OpHi = AVR::STDPtrQRr; TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg); - assert(Imm <= 63 && "Offset is out of range"); + // Since we add 1 to the Imm value for the high byte below, and 63 is the highest Imm value + // allowed for the instruction, 62 is the limit here. + assert(Imm <= 62 && "Offset is out of range"); auto MIBLO = buildMI(MBB, MBBI, OpLo) .addReg(DstReg) @@ -1104,7 +1151,9 @@ bool AVRExpandPseudo::expand(Block &MBB, BlockIt MBBI) { OpHi = AVR::INRdA; TRI->splitReg(DstReg, DstLoReg, DstHiReg); - assert(Imm <= 63 && "Address is out of range"); + // Since we add 1 to the Imm value for the high byte below, and 63 is the highest Imm value + // allowed for the instruction, 62 is the limit here. + assert(Imm <= 62 && "Address is out of range"); auto MIBLO = buildMI(MBB, MBBI, OpLo) .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead)) @@ -1132,7 +1181,9 @@ bool AVRExpandPseudo::expand(Block &MBB, BlockIt MBBI) { OpHi = AVR::OUTARr; TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg); - assert(Imm <= 63 && "Address is out of range"); + // Since we add 1 to the Imm value for the high byte below, and 63 is the highest Imm value + // allowed for the instruction, 62 is the limit here. + assert(Imm <= 62 && "Address is out of range"); // 16 bit I/O writes need the high byte first auto MIBHI = buildMI(MBB, MBBI, OpHi) diff --git a/gnu/llvm/lib/Target/AVR/AVRISelLowering.cpp b/gnu/llvm/lib/Target/AVR/AVRISelLowering.cpp index 7d3faac1dcc..d8e8bc1ff55 100644 --- a/gnu/llvm/lib/Target/AVR/AVRISelLowering.cpp +++ b/gnu/llvm/lib/Target/AVR/AVRISelLowering.cpp @@ -1469,8 +1469,10 @@ MachineBasicBlock *AVRTargetLowering::insertShift(MachineInstr &MI, } const BasicBlock *LLVM_BB = BB->getBasicBlock(); - MachineFunction::iterator I = BB->getParent()->begin(); - ++I; + + MachineFunction::iterator I; + for (I = F->begin(); I != F->end() && &(*I) != BB; ++I); + if (I != F->end()) ++I; // Create loop block. MachineBasicBlock *LoopBB = F->CreateMachineBasicBlock(LLVM_BB); diff --git a/gnu/llvm/lib/Target/AVR/AVRISelLowering.h b/gnu/llvm/lib/Target/AVR/AVRISelLowering.h index b44c62a21ac..85f9552cd75 100644 --- a/gnu/llvm/lib/Target/AVR/AVRISelLowering.h +++ b/gnu/llvm/lib/Target/AVR/AVRISelLowering.h @@ -75,6 +75,11 @@ public: MVT getScalarShiftAmountTy(const DataLayout &, EVT LHSTy) const override { return MVT::i8; } + + MVT::SimpleValueType getCmpLibcallReturnType() const override { + return MVT::i8; + } + const char *getTargetNodeName(unsigned Opcode) const override; SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override; diff --git a/gnu/llvm/lib/Target/AVR/AVRInstrInfo.cpp b/gnu/llvm/lib/Target/AVR/AVRInstrInfo.cpp index 744aa723c41..1a89a13693e 100644 --- a/gnu/llvm/lib/Target/AVR/AVRInstrInfo.cpp +++ b/gnu/llvm/lib/Target/AVR/AVRInstrInfo.cpp @@ -537,8 +537,7 @@ bool AVRInstrInfo::isBranchOffsetInRange(unsigned BranchOp, llvm_unreachable("unexpected opcode!"); case AVR::JMPk: case AVR::CALLk: - assert(BrOffset >= 0 && "offset must be absolute address"); - return isUIntN(16, BrOffset); + return true; case AVR::RCALLk: case AVR::RJMPk: return isIntN(13, BrOffset); @@ -556,5 +555,20 @@ bool AVRInstrInfo::isBranchOffsetInRange(unsigned BranchOp, } } +unsigned AVRInstrInfo::insertIndirectBranch(MachineBasicBlock &MBB, + MachineBasicBlock &NewDestBB, + const DebugLoc &DL, + int64_t BrOffset, + RegScavenger *RS) const { + // This method inserts a *direct* branch (JMP), despite its name. + // LLVM calls this method to fixup unconditional branches; it never calls + // insertBranch or some hypothetical "insertDirectBranch". + // See lib/CodeGen/RegisterRelaxation.cpp for details. + // We end up here when a jump is too long for a RJMP instruction. + auto &MI = *BuildMI(&MBB, DL, get(AVR::JMPk)).addMBB(&NewDestBB); + + return getInstSizeInBytes(MI); +} + } // end of namespace llvm diff --git a/gnu/llvm/lib/Target/AVR/AVRInstrInfo.h b/gnu/llvm/lib/Target/AVR/AVRInstrInfo.h index f42d34fb284..eee8a92c619 100644 --- a/gnu/llvm/lib/Target/AVR/AVRInstrInfo.h +++ b/gnu/llvm/lib/Target/AVR/AVRInstrInfo.h @@ -107,6 +107,12 @@ public: bool isBranchOffsetInRange(unsigned BranchOpc, int64_t BrOffset) const override; + + unsigned insertIndirectBranch(MachineBasicBlock &MBB, + MachineBasicBlock &NewDestBB, + const DebugLoc &DL, + int64_t BrOffset, + RegScavenger *RS) const override; private: const AVRRegisterInfo RI; }; diff --git a/gnu/llvm/lib/Target/AVR/AVRInstrInfo.td b/gnu/llvm/lib/Target/AVR/AVRInstrInfo.td index 184e4d53f7c..7d1bfc8d85e 100644 --- a/gnu/llvm/lib/Target/AVR/AVRInstrInfo.td +++ b/gnu/llvm/lib/Target/AVR/AVRInstrInfo.td @@ -1152,10 +1152,10 @@ isReMaterializable = 1 in // // Expands to: // ld Rd, P+ - // ld Rd+1, P+ + // ld Rd+1, P let Constraints = "@earlyclobber $reg" in def LDWRdPtr : Pseudo<(outs DREGS:$reg), - (ins PTRDISPREGS:$ptrreg), + (ins PTRREGS:$ptrreg), "ldw\t$reg, $ptrreg", [(set i16:$reg, (load i16:$ptrreg))]>, Requires<[HasSRAM]>; @@ -1164,7 +1164,7 @@ isReMaterializable = 1 in // Indirect loads (with postincrement or predecrement). let mayLoad = 1, hasSideEffects = 0, -Constraints = "$ptrreg = $base_wb,@earlyclobber $reg,@earlyclobber $base_wb" in +Constraints = "$ptrreg = $base_wb,@earlyclobber $reg" in { def LDRdPtrPi : FSTLD<0, 0b01, @@ -1238,35 +1238,55 @@ isReMaterializable = 1 in Requires<[HasSRAM]>; } -class AtomicLoad : - Pseudo<(outs DRC:$rd), (ins PTRREGS:$rr), "atomic_op", +class AtomicLoad : + Pseudo<(outs DRC:$rd), (ins PTRRC:$rr), "atomic_op", [(set DRC:$rd, (Op i16:$rr))]>; -class AtomicStore : - Pseudo<(outs), (ins PTRDISPREGS:$rd, DRC:$rr), "atomic_op", +class AtomicStore : + Pseudo<(outs), (ins PTRRC:$rd, DRC:$rr), "atomic_op", [(Op i16:$rd, DRC:$rr)]>; -class AtomicLoadOp : - Pseudo<(outs DRC:$rd), (ins PTRREGS:$rr, DRC:$operand), +class AtomicLoadOp : + Pseudo<(outs DRC:$rd), (ins PTRRC:$rr, DRC:$operand), "atomic_op", [(set DRC:$rd, (Op i16:$rr, DRC:$operand))]>; -def AtomicLoad8 : AtomicLoad; -def AtomicLoad16 : AtomicLoad; - -def AtomicStore8 : AtomicStore; -def AtomicStore16 : AtomicStore; - -def AtomicLoadAdd8 : AtomicLoadOp; -def AtomicLoadAdd16 : AtomicLoadOp; -def AtomicLoadSub8 : AtomicLoadOp; -def AtomicLoadSub16 : AtomicLoadOp; -def AtomicLoadAnd8 : AtomicLoadOp; -def AtomicLoadAnd16 : AtomicLoadOp; -def AtomicLoadOr8 : AtomicLoadOp; -def AtomicLoadOr16 : AtomicLoadOp; -def AtomicLoadXor8 : AtomicLoadOp; -def AtomicLoadXor16 : AtomicLoadOp; +// FIXME: I think 16-bit atomic binary ops need to mark +// r0 as clobbered. + +// Atomic instructions +// =================== +// +// These are all expanded by AVRExpandPseudoInsts +// +// 8-bit operations can use any pointer register because +// they are expanded directly into an LD/ST instruction. +// +// 16-bit operations use 16-bit load/store postincrement instructions, +// which require PTRDISPREGS. + +def AtomicLoad8 : AtomicLoad; +def AtomicLoad16 : AtomicLoad; + +def AtomicStore8 : AtomicStore; +def AtomicStore16 : AtomicStore; + +class AtomicLoadOp8 : AtomicLoadOp; +class AtomicLoadOp16 : AtomicLoadOp; + +def AtomicLoadAdd8 : AtomicLoadOp8; +def AtomicLoadAdd16 : AtomicLoadOp16; +def AtomicLoadSub8 : AtomicLoadOp8; +def AtomicLoadSub16 : AtomicLoadOp16; +def AtomicLoadAnd8 : AtomicLoadOp8; +def AtomicLoadAnd16 : AtomicLoadOp16; +def AtomicLoadOr8 : AtomicLoadOp8; +def AtomicLoadOr16 : AtomicLoadOp16; +def AtomicLoadXor8 : AtomicLoadOp8; +def AtomicLoadXor16 : AtomicLoadOp16; def AtomicFence : Pseudo<(outs), (ins), "atomic_fence", [(atomic_fence imm, imm)]>; @@ -1397,6 +1417,7 @@ def STDWPtrQRr : Pseudo<(outs), // Load program memory operations. let canFoldAsLoad = 1, isReMaterializable = 1, +mayLoad = 1, hasSideEffects = 0 in { let Defs = [R0], @@ -1417,8 +1438,7 @@ hasSideEffects = 0 in Requires<[HasLPMX]>; // Load program memory, while postincrementing the Z register. - let mayLoad = 1, - Defs = [R31R30] in + let Defs = [R31R30] in { def LPMRdZPi : FLPMX<0, 1, diff --git a/gnu/llvm/lib/Target/AVR/AVRRegisterInfo.cpp b/gnu/llvm/lib/Target/AVR/AVRRegisterInfo.cpp index 249dc5512c2..7099b29a8bc 100644 --- a/gnu/llvm/lib/Target/AVR/AVRRegisterInfo.cpp +++ b/gnu/llvm/lib/Target/AVR/AVRRegisterInfo.cpp @@ -203,7 +203,7 @@ void AVRRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, // If the offset is too big we have to adjust and restore the frame pointer // to materialize a valid load/store with displacement. //:TODO: consider using only one adiw/sbiw chain for more than one frame index - if (Offset > 63) { + if (Offset > 62) { unsigned AddOpc = AVR::ADIWRdK, SubOpc = AVR::SBIWRdK; int AddOffset = Offset - 63 + 1; diff --git a/gnu/llvm/lib/Target/AVR/AVRTargetMachine.cpp b/gnu/llvm/lib/Target/AVR/AVRTargetMachine.cpp index a9d61ffc952..e698b6e694c 100644 --- a/gnu/llvm/lib/Target/AVR/AVRTargetMachine.cpp +++ b/gnu/llvm/lib/Target/AVR/AVRTargetMachine.cpp @@ -25,7 +25,7 @@ namespace llvm { -static const char *AVRDataLayout = "e-p:16:16:16-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-n8"; +static const char *AVRDataLayout = "e-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8"; /// Processes a CPU name. static StringRef getCPU(StringRef CPU) { diff --git a/gnu/llvm/lib/Target/AVR/MCTargetDesc/AVRTargetStreamer.cpp b/gnu/llvm/lib/Target/AVR/MCTargetDesc/AVRTargetStreamer.cpp index a2d8c16eeb8..2b45d9adc7e 100644 --- a/gnu/llvm/lib/Target/AVR/MCTargetDesc/AVRTargetStreamer.cpp +++ b/gnu/llvm/lib/Target/AVR/MCTargetDesc/AVRTargetStreamer.cpp @@ -13,6 +13,8 @@ #include "AVRTargetStreamer.h" +#include "llvm/MC/MCContext.h" + namespace llvm { AVRTargetStreamer::AVRTargetStreamer(MCStreamer &S) : MCTargetStreamer(S) {} @@ -20,5 +22,23 @@ AVRTargetStreamer::AVRTargetStreamer(MCStreamer &S) : MCTargetStreamer(S) {} AVRTargetAsmStreamer::AVRTargetAsmStreamer(MCStreamer &S) : AVRTargetStreamer(S) {} +void AVRTargetStreamer::finish() { + MCStreamer &OS = getStreamer(); + MCContext &Context = OS.getContext(); + + MCSymbol *DoCopyData = Context.getOrCreateSymbol("__do_copy_data"); + MCSymbol *DoClearBss = Context.getOrCreateSymbol("__do_clear_bss"); + + // FIXME: We can disable __do_copy_data if there are no static RAM variables. + + OS.emitRawComment(" Declaring this symbol tells the CRT that it should"); + OS.emitRawComment("copy all variables from program memory to RAM on startup"); + OS.EmitSymbolAttribute(DoCopyData, MCSA_Global); + + OS.emitRawComment(" Declaring this symbol tells the CRT that it should"); + OS.emitRawComment("clear the zeroed data section on startup"); + OS.EmitSymbolAttribute(DoClearBss, MCSA_Global); +} + } // end namespace llvm diff --git a/gnu/llvm/lib/Target/AVR/MCTargetDesc/AVRTargetStreamer.h b/gnu/llvm/lib/Target/AVR/MCTargetDesc/AVRTargetStreamer.h index 99a536699ae..815088b0a5d 100644 --- a/gnu/llvm/lib/Target/AVR/MCTargetDesc/AVRTargetStreamer.h +++ b/gnu/llvm/lib/Target/AVR/MCTargetDesc/AVRTargetStreamer.h @@ -19,6 +19,8 @@ class MCStreamer; class AVRTargetStreamer : public MCTargetStreamer { public: explicit AVRTargetStreamer(MCStreamer &S); + + void finish() override; }; /// A target streamer for textual AVR assembly code. diff --git a/gnu/llvm/lib/Target/BPF/BPFISelLowering.cpp b/gnu/llvm/lib/Target/BPF/BPFISelLowering.cpp index 81b0aa7f8b9..5740b49f6a0 100644 --- a/gnu/llvm/lib/Target/BPF/BPFISelLowering.cpp +++ b/gnu/llvm/lib/Target/BPF/BPFISelLowering.cpp @@ -578,11 +578,15 @@ BPFTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI, .addReg(LHS) .addReg(MI.getOperand(2).getReg()) .addMBB(Copy1MBB); - else + else { + int64_t imm32 = MI.getOperand(2).getImm(); + // sanity check before we build J*_ri instruction. + assert (isInt<32>(imm32)); BuildMI(BB, DL, TII.get(NewCC)) .addReg(LHS) - .addImm(MI.getOperand(2).getImm()) + .addImm(imm32) .addMBB(Copy1MBB); + } // Copy0MBB: // %FalseValue = ... diff --git a/gnu/llvm/lib/Target/BPF/BPFInstrInfo.td b/gnu/llvm/lib/Target/BPF/BPFInstrInfo.td index f68357809ad..59e92f8edd0 100644 --- a/gnu/llvm/lib/Target/BPF/BPFInstrInfo.td +++ b/gnu/llvm/lib/Target/BPF/BPFInstrInfo.td @@ -464,7 +464,7 @@ let usesCustomInserter = 1 in { (ins GPR:$lhs, i64imm:$rhs, i64imm:$imm, GPR:$src, GPR:$src2), "# Select PSEUDO $dst = $lhs $imm $rhs ? $src : $src2", [(set i64:$dst, - (BPFselectcc i64:$lhs, (i64 imm:$rhs), (i64 imm:$imm), i64:$src, i64:$src2))]>; + (BPFselectcc i64:$lhs, (i64 i64immSExt32:$rhs), (i64 imm:$imm), i64:$src, i64:$src2))]>; } // load 64-bit global addr into register diff --git a/gnu/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/gnu/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index e12188e7060..a294004b9f6 100644 --- a/gnu/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/gnu/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -304,6 +304,9 @@ class MipsAsmParser : public MCTargetAsmParser { bool expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, const MCSubtargetInfo *STI); + bool expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, + const MCSubtargetInfo *STI); + bool reportParseError(Twine ErrorMsg); bool reportParseError(SMLoc Loc, Twine ErrorMsg); @@ -2511,6 +2514,16 @@ MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, return expandSeq(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success; case Mips::SEQIMacro: return expandSeqI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success; + case Mips::MFTC0: case Mips::MTTC0: + case Mips::MFTGPR: case Mips::MTTGPR: + case Mips::MFTLO: case Mips::MTTLO: + case Mips::MFTHI: case Mips::MTTHI: + case Mips::MFTACX: case Mips::MTTACX: + case Mips::MFTDSP: case Mips::MTTDSP: + case Mips::MFTC1: case Mips::MTTC1: + case Mips::MFTHC1: case Mips::MTTHC1: + case Mips::CFTC1: case Mips::CTTC1: + return expandMXTRAlias(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success; } } @@ -4882,6 +4895,212 @@ bool MipsAsmParser::expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, return false; } +// Map the DSP accumulator and control register to the corresponding gpr +// operand. Unlike the other alias, the m(f|t)t(lo|hi|acx) instructions +// do not map the DSP registers contigously to gpr registers. +static unsigned getRegisterForMxtrDSP(MCInst &Inst, bool IsMFDSP) { + switch (Inst.getOpcode()) { + case Mips::MFTLO: + case Mips::MTTLO: + switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg()) { + case Mips::AC0: + return Mips::ZERO; + case Mips::AC1: + return Mips::A0; + case Mips::AC2: + return Mips::T0; + case Mips::AC3: + return Mips::T4; + default: + llvm_unreachable("Unknown register for 'mttr' alias!"); + } + case Mips::MFTHI: + case Mips::MTTHI: + switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg()) { + case Mips::AC0: + return Mips::AT; + case Mips::AC1: + return Mips::A1; + case Mips::AC2: + return Mips::T1; + case Mips::AC3: + return Mips::T5; + default: + llvm_unreachable("Unknown register for 'mttr' alias!"); + } + case Mips::MFTACX: + case Mips::MTTACX: + switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg()) { + case Mips::AC0: + return Mips::V0; + case Mips::AC1: + return Mips::A2; + case Mips::AC2: + return Mips::T2; + case Mips::AC3: + return Mips::T6; + default: + llvm_unreachable("Unknown register for 'mttr' alias!"); + } + case Mips::MFTDSP: + case Mips::MTTDSP: + return Mips::S0; + default: + llvm_unreachable("Unknown instruction for 'mttr' dsp alias!"); + } +} + +// Map the floating point register operand to the corresponding register +// operand. +static unsigned getRegisterForMxtrFP(MCInst &Inst, bool IsMFTC1) { + switch (Inst.getOperand(IsMFTC1 ? 1 : 0).getReg()) { + case Mips::F0: return Mips::ZERO; + case Mips::F1: return Mips::AT; + case Mips::F2: return Mips::V0; + case Mips::F3: return Mips::V1; + case Mips::F4: return Mips::A0; + case Mips::F5: return Mips::A1; + case Mips::F6: return Mips::A2; + case Mips::F7: return Mips::A3; + case Mips::F8: return Mips::T0; + case Mips::F9: return Mips::T1; + case Mips::F10: return Mips::T2; + case Mips::F11: return Mips::T3; + case Mips::F12: return Mips::T4; + case Mips::F13: return Mips::T5; + case Mips::F14: return Mips::T6; + case Mips::F15: return Mips::T7; + case Mips::F16: return Mips::S0; + case Mips::F17: return Mips::S1; + case Mips::F18: return Mips::S2; + case Mips::F19: return Mips::S3; + case Mips::F20: return Mips::S4; + case Mips::F21: return Mips::S5; + case Mips::F22: return Mips::S6; + case Mips::F23: return Mips::S7; + case Mips::F24: return Mips::T8; + case Mips::F25: return Mips::T9; + case Mips::F26: return Mips::K0; + case Mips::F27: return Mips::K1; + case Mips::F28: return Mips::GP; + case Mips::F29: return Mips::SP; + case Mips::F30: return Mips::FP; + case Mips::F31: return Mips::RA; + default: llvm_unreachable("Unknown register for mttc1 alias!"); + } +} + +// Map the coprocessor operand the corresponding gpr register operand. +static unsigned getRegisterForMxtrC0(MCInst &Inst, bool IsMFTC0) { + switch (Inst.getOperand(IsMFTC0 ? 1 : 0).getReg()) { + case Mips::COP00: return Mips::ZERO; + case Mips::COP01: return Mips::AT; + case Mips::COP02: return Mips::V0; + case Mips::COP03: return Mips::V1; + case Mips::COP04: return Mips::A0; + case Mips::COP05: return Mips::A1; + case Mips::COP06: return Mips::A2; + case Mips::COP07: return Mips::A3; + case Mips::COP08: return Mips::T0; + case Mips::COP09: return Mips::T1; + case Mips::COP010: return Mips::T2; + case Mips::COP011: return Mips::T3; + case Mips::COP012: return Mips::T4; + case Mips::COP013: return Mips::T5; + case Mips::COP014: return Mips::T6; + case Mips::COP015: return Mips::T7; + case Mips::COP016: return Mips::S0; + case Mips::COP017: return Mips::S1; + case Mips::COP018: return Mips::S2; + case Mips::COP019: return Mips::S3; + case Mips::COP020: return Mips::S4; + case Mips::COP021: return Mips::S5; + case Mips::COP022: return Mips::S6; + case Mips::COP023: return Mips::S7; + case Mips::COP024: return Mips::T8; + case Mips::COP025: return Mips::T9; + case Mips::COP026: return Mips::K0; + case Mips::COP027: return Mips::K1; + case Mips::COP028: return Mips::GP; + case Mips::COP029: return Mips::SP; + case Mips::COP030: return Mips::FP; + case Mips::COP031: return Mips::RA; + default: llvm_unreachable("Unknown register for mttc0 alias!"); + } +} + +/// Expand an alias of 'mftr' or 'mttr' into the full instruction, by producing +/// an mftr or mttr with the correctly mapped gpr register, u, sel and h bits. +bool MipsAsmParser::expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, + const MCSubtargetInfo *STI) { + MipsTargetStreamer &TOut = getTargetStreamer(); + unsigned rd = 0; + unsigned u = 1; + unsigned sel = 0; + unsigned h = 0; + bool IsMFTR = false; + switch (Inst.getOpcode()) { + case Mips::MFTC0: + IsMFTR = true; + LLVM_FALLTHROUGH; + case Mips::MTTC0: + u = 0; + rd = getRegisterForMxtrC0(Inst, IsMFTR); + sel = Inst.getOperand(2).getImm(); + break; + case Mips::MFTGPR: + IsMFTR = true; + LLVM_FALLTHROUGH; + case Mips::MTTGPR: + rd = Inst.getOperand(IsMFTR ? 1 : 0).getReg(); + break; + case Mips::MFTLO: + case Mips::MFTHI: + case Mips::MFTACX: + case Mips::MFTDSP: + IsMFTR = true; + LLVM_FALLTHROUGH; + case Mips::MTTLO: + case Mips::MTTHI: + case Mips::MTTACX: + case Mips::MTTDSP: + rd = getRegisterForMxtrDSP(Inst, IsMFTR); + sel = 1; + break; + case Mips::MFTHC1: + h = 1; + LLVM_FALLTHROUGH; + case Mips::MFTC1: + IsMFTR = true; + rd = getRegisterForMxtrFP(Inst, IsMFTR); + sel = 2; + break; + case Mips::MTTHC1: + h = 1; + LLVM_FALLTHROUGH; + case Mips::MTTC1: + rd = getRegisterForMxtrFP(Inst, IsMFTR); + sel = 2; + break; + case Mips::CFTC1: + IsMFTR = true; + LLVM_FALLTHROUGH; + case Mips::CTTC1: + rd = getRegisterForMxtrFP(Inst, IsMFTR); + sel = 3; + break; + } + unsigned Op0 = IsMFTR ? Inst.getOperand(0).getReg() : rd; + unsigned Op1 = + IsMFTR ? rd + : (Inst.getOpcode() != Mips::MTTDSP ? Inst.getOperand(1).getReg() + : Inst.getOperand(0).getReg()); + + TOut.emitRRIII(IsMFTR ? Mips::MFTR : Mips::MTTR, Op0, Op1, u, sel, h, IDLoc, + STI); + return false; +} + unsigned MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst, const OperandVector &Operands) { @@ -5793,14 +6012,21 @@ OperandMatchResultTy MipsAsmParser::parseInvNum(OperandVector &Operands) { MCAsmParser &Parser = getParser(); const MCExpr *IdVal; - // If the first token is '$' we may have register operand. - if (Parser.getTok().is(AsmToken::Dollar)) - return MatchOperand_NoMatch; + // If the first token is '$' we may have register operand. We have to reject + // cases where it is not a register. Complicating the matter is that + // register names are not reserved across all ABIs. + // Peek past the dollar to see if it's a register name for this ABI. SMLoc S = Parser.getTok().getLoc(); + if (Parser.getTok().is(AsmToken::Dollar)) { + return matchCPURegisterName(Parser.getLexer().peekTok().getString()) == -1 + ? MatchOperand_ParseFail + : MatchOperand_NoMatch; + } if (getParser().parseExpression(IdVal)) return MatchOperand_ParseFail; const MCConstantExpr *MCE = dyn_cast(IdVal); - assert(MCE && "Unexpected MCExpr type."); + if (!MCE) + return MatchOperand_NoMatch; int64_t Val = MCE->getValue(); SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); Operands.push_back(MipsOperand::CreateImm( diff --git a/gnu/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp b/gnu/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp index aad6bf378ea..0bddba78145 100644 --- a/gnu/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp +++ b/gnu/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp @@ -246,8 +246,6 @@ void MipsMCExpr::fixELFSymbolsInTLSFixups(MCAssembler &Asm) const { break; case MEK_CALL_HI16: case MEK_CALL_LO16: - case MEK_DTPREL_HI: - case MEK_DTPREL_LO: case MEK_GOT: case MEK_GOT_CALL: case MEK_GOT_DISP: @@ -263,14 +261,16 @@ void MipsMCExpr::fixELFSymbolsInTLSFixups(MCAssembler &Asm) const { case MEK_NEG: case MEK_PCREL_HI16: case MEK_PCREL_LO16: - case MEK_TLSLDM: // If we do have nested target-specific expressions, they will be in // a consecutive chain. if (const MipsMCExpr *E = dyn_cast(getSubExpr())) E->fixELFSymbolsInTLSFixups(Asm); break; - case MEK_GOTTPREL: + case MEK_DTPREL_HI: + case MEK_DTPREL_LO: + case MEK_TLSLDM: case MEK_TLSGD: + case MEK_GOTTPREL: case MEK_TPREL_HI: case MEK_TPREL_LO: fixELFSymbolsInTLSFixupsImpl(getSubExpr(), Asm); diff --git a/gnu/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp b/gnu/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp index 2907b771585..7caeb08589a 100644 --- a/gnu/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp +++ b/gnu/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp @@ -193,6 +193,21 @@ void MipsTargetStreamer::emitRRI(unsigned Opcode, unsigned Reg0, unsigned Reg1, emitRRX(Opcode, Reg0, Reg1, MCOperand::createImm(Imm), IDLoc, STI); } +void MipsTargetStreamer::emitRRIII(unsigned Opcode, unsigned Reg0, + unsigned Reg1, int16_t Imm0, int16_t Imm1, + int16_t Imm2, SMLoc IDLoc, + const MCSubtargetInfo *STI) { + MCInst TmpInst; + TmpInst.setOpcode(Opcode); + TmpInst.addOperand(MCOperand::createReg(Reg0)); + TmpInst.addOperand(MCOperand::createReg(Reg1)); + TmpInst.addOperand(MCOperand::createImm(Imm0)); + TmpInst.addOperand(MCOperand::createImm(Imm1)); + TmpInst.addOperand(MCOperand::createImm(Imm2)); + TmpInst.setLoc(IDLoc); + getStreamer().EmitInstruction(TmpInst, *STI); +} + void MipsTargetStreamer::emitAddu(unsigned DstReg, unsigned SrcReg, unsigned TrgReg, bool Is64Bit, const MCSubtargetInfo *STI) { diff --git a/gnu/llvm/lib/Target/Mips/MicroMipsDSPInstrInfo.td b/gnu/llvm/lib/Target/Mips/MicroMipsDSPInstrInfo.td index f82f82fc7e4..20c1ab5a999 100644 --- a/gnu/llvm/lib/Target/Mips/MicroMipsDSPInstrInfo.td +++ b/gnu/llvm/lib/Target/Mips/MicroMipsDSPInstrInfo.td @@ -415,6 +415,13 @@ class BITREV_MM_DESC : ABSQ_S_PH_MM_R2_DESC_BASE<"bitrev", int_mips_bitrev, class BPOSGE32_MM_DESC : BPOSGE32_DESC_BASE<"bposge32", brtarget_mm, NoItinerary>; +let DecoderNamespace = "MicroMipsDSP", Arch = "mmdsp", + AdditionalPredicates = [HasDSP, InMicroMips] in { + def LWDSP_MM : Load<"lw", DSPROpnd, null_frag, II_LW>, DspMMRel, + LW_FM_MM<0x3f>; + def SWDSP_MM : Store<"sw", DSPROpnd, null_frag, II_SW>, DspMMRel, + LW_FM_MM<0x3e>; +} // Instruction defs. // microMIPS DSP Rev 1 def ADDQ_PH_MM : DspMMRel, ADDQ_PH_MM_ENC, ADDQ_PH_DESC; diff --git a/gnu/llvm/lib/Target/Mips/MipsDSPInstrInfo.td b/gnu/llvm/lib/Target/Mips/MipsDSPInstrInfo.td index c238a65378e..2595333188a 100644 --- a/gnu/llvm/lib/Target/Mips/MipsDSPInstrInfo.td +++ b/gnu/llvm/lib/Target/Mips/MipsDSPInstrInfo.td @@ -1284,6 +1284,12 @@ let isPseudo = 1, isCodeGenOnly = 1, hasNoSchedulingInfo = 1 in { def STORE_CCOND_DSP : Store<"store_ccond_dsp", DSPCC>; } +let DecoderNamespace = "MipsDSP", Arch = "dsp", + AdditionalPredicates = [HasDSP] in { + def LWDSP : Load<"lw", DSPROpnd, null_frag, II_LW>, DspMMRel, LW_FM<0x23>; + def SWDSP : Store<"sw", DSPROpnd, null_frag, II_SW>, DspMMRel, LW_FM<0x2b>; +} + // Pseudo CMP and PICK instructions. class PseudoCMP : PseudoDSP<(outs DSPCC:$cmp), (ins DSPROpnd:$rs, DSPROpnd:$rt), []>, diff --git a/gnu/llvm/lib/Target/Mips/MipsFrameLowering.cpp b/gnu/llvm/lib/Target/Mips/MipsFrameLowering.cpp index ef05166503b..27a85970da6 100644 --- a/gnu/llvm/lib/Target/Mips/MipsFrameLowering.cpp +++ b/gnu/llvm/lib/Target/Mips/MipsFrameLowering.cpp @@ -107,38 +107,31 @@ bool MipsFrameLowering::hasBP(const MachineFunction &MF) const { return MFI.hasVarSizedObjects() && TRI->needsStackRealignment(MF); } +// Estimate the size of the stack, including the incoming arguments. We need to +// account for register spills, local objects, reserved call frame and incoming +// arguments. This is required to determine the largest possible positive offset +// from $sp so that it can be determined if an emergency spill slot for stack +// addresses is required. uint64_t MipsFrameLowering::estimateStackSize(const MachineFunction &MF) const { const MachineFrameInfo &MFI = MF.getFrameInfo(); const TargetRegisterInfo &TRI = *STI.getRegisterInfo(); - int64_t Offset = 0; + int64_t Size = 0; - // Iterate over fixed sized objects. + // Iterate over fixed sized objects which are incoming arguments. for (int I = MFI.getObjectIndexBegin(); I != 0; ++I) - Offset = std::max(Offset, -MFI.getObjectOffset(I)); + if (MFI.getObjectOffset(I) > 0) + Size += MFI.getObjectSize(I); // Conservatively assume all callee-saved registers will be saved. for (const MCPhysReg *R = TRI.getCalleeSavedRegs(&MF); *R; ++R) { - unsigned Size = TRI.getSpillSize(*TRI.getMinimalPhysRegClass(*R)); - Offset = alignTo(Offset + Size, Size); + unsigned RegSize = TRI.getSpillSize(*TRI.getMinimalPhysRegClass(*R)); + Size = alignTo(Size + RegSize, RegSize); } - unsigned MaxAlign = MFI.getMaxAlignment(); - - // Check that MaxAlign is not zero if there is a stack object that is not a - // callee-saved spill. - assert(!MFI.getObjectIndexEnd() || MaxAlign); - - // Iterate over other objects. - for (unsigned I = 0, E = MFI.getObjectIndexEnd(); I != E; ++I) - Offset = alignTo(Offset + MFI.getObjectSize(I), MaxAlign); - - // Call frame. - if (MFI.adjustsStack() && hasReservedCallFrame(MF)) - Offset = alignTo(Offset + MFI.getMaxCallFrameSize(), - std::max(MaxAlign, getStackAlignment())); - - return alignTo(Offset, getStackAlignment()); + // Get the size of the rest of the frame objects and any possible reserved + // call frame, accounting for alignment. + return Size + MFI.estimateStackSize(MF); } // Eliminate ADJCALLSTACKDOWN, ADJCALLSTACKUP pseudo instructions diff --git a/gnu/llvm/lib/Target/Mips/MipsMTInstrFormats.td b/gnu/llvm/lib/Target/Mips/MipsMTInstrFormats.td index 64bee5bfba1..edc0981e627 100644 --- a/gnu/llvm/lib/Target/Mips/MipsMTInstrFormats.td +++ b/gnu/llvm/lib/Target/Mips/MipsMTInstrFormats.td @@ -35,6 +35,8 @@ class FIELD5 Val> { def FIELD5_1_DMT_EMT : FIELD5<0b00001>; def FIELD5_2_DMT_EMT : FIELD5<0b01111>; def FIELD5_1_2_DVPE_EVPE : FIELD5<0b00000>; +def FIELD5_MFTR : FIELD5<0b01000>; +def FIELD5_MTTR : FIELD5<0b01100>; class COP0_MFMC0_MT : MipsMTInst { bits<32> Inst; @@ -50,6 +52,25 @@ class COP0_MFMC0_MT : MipsMTInst { let Inst{2-0} = 0b001; } +class COP0_MFTTR_MT : MipsMTInst { + bits<32> Inst; + + bits<5> rt; + bits<5> rd; + bits<1> u; + bits<1> h; + bits<3> sel; + let Inst{31-26} = 0b010000; // COP0 + let Inst{25-21} = Op.Value; // MFMC0 + let Inst{20-16} = rt; + let Inst{15-11} = rd; + let Inst{10-6} = 0b00000; // rx - currently unsupported. + let Inst{5} = u; + let Inst{4} = h; + let Inst{3} = 0b0; + let Inst{2-0} = sel; +} + class SPECIAL3_MT_FORK : MipsMTInst { bits<32> Inst; diff --git a/gnu/llvm/lib/Target/Mips/MipsMTInstrInfo.td b/gnu/llvm/lib/Target/Mips/MipsMTInstrInfo.td index ab6693f60fd..72e626cbec4 100644 --- a/gnu/llvm/lib/Target/Mips/MipsMTInstrInfo.td +++ b/gnu/llvm/lib/Target/Mips/MipsMTInstrInfo.td @@ -6,6 +6,13 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +// +// This file describes the MIPS MT ASE as defined by MD00378 1.12. +// +// TODO: Add support for the microMIPS encodings for the MT ASE and add the +// instruction mappings. +// +//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===// // MIPS MT Instruction Encodings @@ -27,6 +34,10 @@ class FORK_ENC : SPECIAL3_MT_FORK; class YIELD_ENC : SPECIAL3_MT_YIELD; +class MFTR_ENC : COP0_MFTTR_MT; + +class MTTR_ENC : COP0_MFTTR_MT; + //===----------------------------------------------------------------------===// // MIPS MT Instruction Descriptions //===----------------------------------------------------------------------===// @@ -39,6 +50,22 @@ class MT_1R_DESC_BASE { InstrItinClass Itinerary = Itin; } +class MFTR_DESC { + dag OutOperandList = (outs GPR32Opnd:$rd); + dag InOperandList = (ins GPR32Opnd:$rt, uimm1:$u, uimm3:$sel, uimm1:$h); + string AsmString = "mftr\t$rd, $rt, $u, $sel, $h"; + list Pattern = []; + InstrItinClass Itinerary = II_MFTR; +} + +class MTTR_DESC { + dag OutOperandList = (outs GPR32Opnd:$rd); + dag InOperandList = (ins GPR32Opnd:$rt, uimm1:$u, uimm3:$sel, uimm1:$h); + string AsmString = "mttr\t$rt, $rd, $u, $sel, $h"; + list Pattern = []; + InstrItinClass Itinerary = II_MTTR; +} + class FORK_DESC { dag OutOperandList = (outs GPR32Opnd:$rs, GPR32Opnd:$rd); dag InOperandList = (ins GPR32Opnd:$rt); @@ -79,8 +106,73 @@ let hasSideEffects = 1, isNotDuplicable = 1, def FORK : FORK_ENC, FORK_DESC, ASE_MT; def YIELD : YIELD_ENC, YIELD_DESC, ASE_MT; + + def MFTR : MFTR_ENC, MFTR_DESC, ASE_MT; + + def MTTR : MTTR_ENC, MTTR_DESC, ASE_MT; } +//===----------------------------------------------------------------------===// +// MIPS MT Pseudo Instructions - used to support mtfr & mttr aliases. +//===----------------------------------------------------------------------===// +def MFTC0 : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), (ins COP0Opnd:$rt, + uimm3:$sel), + "mftc0 $rd, $rt, $sel">, ASE_MT; + +def MFTGPR : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), (ins GPR32Opnd:$rt, + uimm3:$sel), + "mftgpr $rd, $rt">, ASE_MT; + +def MFTLO : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins ACC64DSPOpnd:$ac), + "mftlo $rt, $ac">, ASE_MT; + +def MFTHI : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins ACC64DSPOpnd:$ac), + "mfthi $rt, $ac">, ASE_MT; + +def MFTACX : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins ACC64DSPOpnd:$ac), + "mftacx $rt, $ac">, ASE_MT; + +def MFTDSP : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins), + "mftdsp $rt">, ASE_MT; + +def MFTC1 : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins FGR32Opnd:$ft), + "mftc1 $rt, $ft">, ASE_MT; + +def MFTHC1 : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins FGR32Opnd:$ft), + "mfthc1 $rt, $ft">, ASE_MT; + +def CFTC1 : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins FGRCCOpnd:$ft), + "cftc1 $rt, $ft">, ASE_MT; + + +def MTTC0 : MipsAsmPseudoInst<(outs COP0Opnd:$rd), (ins GPR32Opnd:$rt, + uimm3:$sel), + "mttc0 $rt, $rd, $sel">, ASE_MT; + +def MTTGPR : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins GPR32Opnd:$rd), + "mttgpr $rd, $rt">, ASE_MT; + +def MTTLO : MipsAsmPseudoInst<(outs ACC64DSPOpnd:$ac), (ins GPR32Opnd:$rt), + "mttlo $rt, $ac">, ASE_MT; + +def MTTHI : MipsAsmPseudoInst<(outs ACC64DSPOpnd:$ac), (ins GPR32Opnd:$rt), + "mtthi $rt, $ac">, ASE_MT; + +def MTTACX : MipsAsmPseudoInst<(outs ACC64DSPOpnd:$ac), (ins GPR32Opnd:$rt), + "mttacx $rt, $ac">, ASE_MT; + +def MTTDSP : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rt), + "mttdsp $rt">, ASE_MT; + +def MTTC1 : MipsAsmPseudoInst<(outs FGR32Opnd:$ft), (ins GPR32Opnd:$rt), + "mttc1 $rt, $ft">, ASE_MT; + +def MTTHC1 : MipsAsmPseudoInst<(outs FGR32Opnd:$ft), (ins GPR32Opnd:$rt), + "mtthc1 $rt, $ft">, ASE_MT; + +def CTTC1 : MipsAsmPseudoInst<(outs FGRCCOpnd:$ft), (ins GPR32Opnd:$rt), + "cttc1 $rt, $ft">, ASE_MT; + //===----------------------------------------------------------------------===// // MIPS MT Instruction Definitions //===----------------------------------------------------------------------===// @@ -95,4 +187,22 @@ let AdditionalPredicates = [NotInMicroMips] in { def : MipsInstAlias<"evpe", (EVPE ZERO), 1>, ASE_MT; def : MipsInstAlias<"yield $rs", (YIELD ZERO, GPR32Opnd:$rs), 1>, ASE_MT; + + def : MipsInstAlias<"mftc0 $rd, $rt", (MFTC0 GPR32Opnd:$rd, COP0Opnd:$rt, 0), + 1>, ASE_MT; + + def : MipsInstAlias<"mftlo $rt", (MFTLO GPR32Opnd:$rt, AC0), 1>, ASE_MT; + + def : MipsInstAlias<"mfthi $rt", (MFTHI GPR32Opnd:$rt, AC0), 1>, ASE_MT; + + def : MipsInstAlias<"mftacx $rt", (MFTACX GPR32Opnd:$rt, AC0), 1>, ASE_MT; + + def : MipsInstAlias<"mttc0 $rd, $rt", (MTTC0 COP0Opnd:$rt, GPR32Opnd:$rd, 0), + 1>, ASE_MT; + + def : MipsInstAlias<"mttlo $rt", (MTTLO AC0, GPR32Opnd:$rt), 1>, ASE_MT; + + def : MipsInstAlias<"mtthi $rt", (MTTHI AC0, GPR32Opnd:$rt), 1>, ASE_MT; + + def : MipsInstAlias<"mttacx $rt", (MTTACX AC0, GPR32Opnd:$rt), 1>, ASE_MT; } diff --git a/gnu/llvm/lib/Target/Mips/MipsSEFrameLowering.cpp b/gnu/llvm/lib/Target/Mips/MipsSEFrameLowering.cpp index 102ebb21609..735461c2a79 100644 --- a/gnu/llvm/lib/Target/Mips/MipsSEFrameLowering.cpp +++ b/gnu/llvm/lib/Target/Mips/MipsSEFrameLowering.cpp @@ -894,10 +894,12 @@ void MipsSEFrameLowering::determineCalleeSaves(MachineFunction &MF, } // Set scavenging frame index if necessary. - uint64_t MaxSPOffset = MF.getInfo()->getIncomingArgSize() + - estimateStackSize(MF); + uint64_t MaxSPOffset = estimateStackSize(MF); - if (isInt<16>(MaxSPOffset)) + // MSA has a minimum offset of 10 bits signed. If there is a variable + // sized object on the stack, the estimation cannot account for it. + if (isIntN(STI.hasMSA() ? 10 : 16, MaxSPOffset) && + !MF.getFrameInfo().hasVarSizedObjects()) return; const TargetRegisterClass &RC = diff --git a/gnu/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp b/gnu/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp index ee074798563..d2c21691abb 100644 --- a/gnu/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp +++ b/gnu/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp @@ -226,6 +226,8 @@ storeRegToStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, Opc = Mips::SW; else if (Mips::HI64RegClass.hasSubClassEq(RC)) Opc = Mips::SD; + else if (Mips::DSPRRegClass.hasSubClassEq(RC)) + Opc = Mips::SWDSP; // Hi, Lo are normally caller save but they are callee save // for interrupt handling. @@ -302,6 +304,8 @@ loadRegFromStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, Opc = Mips::LW; else if (Mips::LO64RegClass.hasSubClassEq(RC)) Opc = Mips::LD; + else if (Mips::DSPRRegClass.hasSubClassEq(RC)) + Opc = Mips::LWDSP; assert(Opc && "Register class not handled!"); diff --git a/gnu/llvm/lib/Target/Mips/MipsSchedule.td b/gnu/llvm/lib/Target/Mips/MipsSchedule.td index c2947bb44ef..8ec55ab6284 100644 --- a/gnu/llvm/lib/Target/Mips/MipsSchedule.td +++ b/gnu/llvm/lib/Target/Mips/MipsSchedule.td @@ -226,6 +226,7 @@ def II_MFC1 : InstrItinClass; def II_MFHC1 : InstrItinClass; def II_MFC2 : InstrItinClass; def II_MFHI_MFLO : InstrItinClass; // mfhi and mflo +def II_MFTR : InstrItinClass; def II_MOD : InstrItinClass; def II_MODU : InstrItinClass; def II_MOVE : InstrItinClass; @@ -255,6 +256,7 @@ def II_MTC1 : InstrItinClass; def II_MTHC1 : InstrItinClass; def II_MTC2 : InstrItinClass; def II_MTHI_MTLO : InstrItinClass; // mthi and mtlo +def II_MTTR : InstrItinClass; def II_MUL : InstrItinClass; def II_MUH : InstrItinClass; def II_MUHU : InstrItinClass; @@ -664,12 +666,14 @@ def MipsGenericItineraries : ProcessorItineraries<[ALU, IMULDIV], [], [ InstrItinData]>, InstrItinData]>, InstrItinData]>, + InstrItinData]>, InstrItinData]>, InstrItinData]>, InstrItinData]>, InstrItinData]>, InstrItinData]>, InstrItinData]>, + InstrItinData]>, InstrItinData]>, InstrItinData]>, InstrItinData]>, diff --git a/gnu/llvm/lib/Target/Mips/MipsScheduleGeneric.td b/gnu/llvm/lib/Target/Mips/MipsScheduleGeneric.td index 89cda676441..e4c52a4e182 100644 --- a/gnu/llvm/lib/Target/Mips/MipsScheduleGeneric.td +++ b/gnu/llvm/lib/Target/Mips/MipsScheduleGeneric.td @@ -268,9 +268,11 @@ def : ItinRW<[GenericWriteLoad], [II_LWLE, II_LWRE]>; // MIPS MT instructions // ==================== -def : ItinRW<[GenericWriteMove], [II_DMT, II_DVPE, II_EMT, II_EVPE]>; +def : ItinRW<[GenericWriteMove], [II_DMT, II_DVPE, II_EMT, II_EVPE, II_MFTR, + II_MTTR]>; def : ItinRW<[GenericReadWriteCOP0Long], [II_YIELD]>; + def : ItinRW<[GenericWriteCOP0Short], [II_FORK]>; // MIPS32R6 and MIPS16e diff --git a/gnu/llvm/lib/Target/Mips/MipsTargetStreamer.h b/gnu/llvm/lib/Target/Mips/MipsTargetStreamer.h index 7d9f99ce071..af24838665e 100644 --- a/gnu/llvm/lib/Target/Mips/MipsTargetStreamer.h +++ b/gnu/llvm/lib/Target/Mips/MipsTargetStreamer.h @@ -119,6 +119,9 @@ public: SMLoc IDLoc, const MCSubtargetInfo *STI); void emitRRI(unsigned Opcode, unsigned Reg0, unsigned Reg1, int16_t Imm, SMLoc IDLoc, const MCSubtargetInfo *STI); + void emitRRIII(unsigned Opcode, unsigned Reg0, unsigned Reg1, int16_t Imm0, + int16_t Imm1, int16_t Imm2, SMLoc IDLoc, + const MCSubtargetInfo *STI); void emitAddu(unsigned DstReg, unsigned SrcReg, unsigned TrgReg, bool Is64Bit, const MCSubtargetInfo *STI); void emitDSLL(unsigned DstReg, unsigned SrcReg, int16_t ShiftAmount, diff --git a/gnu/llvm/lib/Target/X86/X86ISelLowering.cpp b/gnu/llvm/lib/Target/X86/X86ISelLowering.cpp index 957b46c40a6..607bc4530ab 100644 --- a/gnu/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/gnu/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -7026,6 +7026,18 @@ X86TargetLowering::LowerBUILD_VECTORvXi1(SDValue Op, SelectionDAG &DAG) const { return DAG.getTargetConstant(1, dl, VT); if (ISD::isBuildVectorOfConstantSDNodes(Op.getNode())) { + if (VT == MVT::v64i1 && !Subtarget.is64Bit()) { + // Split the pieces. + SDValue Lower = + DAG.getBuildVector(MVT::v32i1, dl, Op.getNode()->ops().slice(0, 32)); + SDValue Upper = + DAG.getBuildVector(MVT::v32i1, dl, Op.getNode()->ops().slice(32, 32)); + // We have to manually lower both halves so getNode doesn't try to + // reassemble the build_vector. + Lower = LowerBUILD_VECTORvXi1(Lower, DAG); + Upper = LowerBUILD_VECTORvXi1(Upper, DAG); + return DAG.getNode(ISD::CONCAT_VECTORS, dl, MVT::v64i1, Lower, Upper); + } SDValue Imm = ConvertI1VectorToInteger(Op, DAG); if (Imm.getValueSizeInBits() == VT.getSizeInBits()) return DAG.getBitcast(VT, Imm); @@ -34733,6 +34745,11 @@ static SDValue combineVectorSizedSetCCEquality(SDNode *SetCC, SelectionDAG &DAG, if (!OpVT.isScalarInteger() || OpSize < 128 || isNullConstant(Y)) return SDValue(); + // Bail out if we know that this is not really just an oversized integer. + if (peekThroughBitcasts(X).getValueType() == MVT::f128 || + peekThroughBitcasts(Y).getValueType() == MVT::f128) + return SDValue(); + // TODO: Use PXOR + PTEST for SSE4.1 or later? // TODO: Add support for AVX-512. EVT VT = SetCC->getValueType(0); diff --git a/gnu/llvm/lib/Transforms/Scalar/NewGVN.cpp b/gnu/llvm/lib/Transforms/Scalar/NewGVN.cpp index 9d018563618..8ac10348eb7 100644 --- a/gnu/llvm/lib/Transforms/Scalar/NewGVN.cpp +++ b/gnu/llvm/lib/Transforms/Scalar/NewGVN.cpp @@ -586,8 +586,8 @@ public: private: // Expression handling. const Expression *createExpression(Instruction *) const; - const Expression *createBinaryExpression(unsigned, Type *, Value *, - Value *) const; + const Expression *createBinaryExpression(unsigned, Type *, Value *, Value *, + Instruction *) const; PHIExpression *createPHIExpression(Instruction *, bool &HasBackEdge, bool &OriginalOpsConstant) const; const DeadExpression *createDeadExpression() const; @@ -902,8 +902,8 @@ bool NewGVN::setBasicExpressionInfo(Instruction *I, BasicExpression *E) const { } const Expression *NewGVN::createBinaryExpression(unsigned Opcode, Type *T, - Value *Arg1, - Value *Arg2) const { + Value *Arg1, Value *Arg2, + Instruction *I) const { auto *E = new (ExpressionAllocator) BasicExpression(2); E->setType(T); @@ -921,7 +921,7 @@ const Expression *NewGVN::createBinaryExpression(unsigned Opcode, Type *T, E->op_push_back(lookupOperandLeader(Arg2)); Value *V = SimplifyBinOp(Opcode, E->getOperand(0), E->getOperand(1), SQ); - if (const Expression *SimplifiedE = checkSimplificationResults(E, nullptr, V)) + if (const Expression *SimplifiedE = checkSimplificationResults(E, I, V)) return SimplifiedE; return E; } @@ -1699,8 +1699,9 @@ NewGVN::performSymbolicAggrValueEvaluation(Instruction *I) const { // expression. assert(II->getNumArgOperands() == 2 && "Expect two args for recognised intrinsics."); - return createBinaryExpression( - Opcode, EI->getType(), II->getArgOperand(0), II->getArgOperand(1)); + return createBinaryExpression(Opcode, EI->getType(), + II->getArgOperand(0), + II->getArgOperand(1), I); } } } @@ -1933,6 +1934,7 @@ void NewGVN::touchAndErase(Map &M, const KeyType &Key) { } void NewGVN::addAdditionalUsers(Value *To, Value *User) const { + assert(User && To != User); if (isa(To)) AdditionalUsers[To].insert(User); } diff --git a/gnu/llvm/tools/clang/bindings/python/clang/cindex.py b/gnu/llvm/tools/clang/bindings/python/clang/cindex.py index 236803a9ab9..4069ab8650d 100644 --- a/gnu/llvm/tools/clang/bindings/python/clang/cindex.py +++ b/gnu/llvm/tools/clang/bindings/python/clang/cindex.py @@ -207,7 +207,7 @@ class _CXString(Structure): conf.lib.clang_disposeString(self) @staticmethod - def from_result(res, fn, args): + def from_result(res, fn=None, args=None): assert isinstance(res, _CXString) return conf.lib.clang_getCString(res) @@ -459,8 +459,7 @@ class Diagnostic(object): """The command-line option that disables this diagnostic.""" disable = _CXString() conf.lib.clang_getDiagnosticOption(self, byref(disable)) - - return conf.lib.clang_getCString(disable) + return _CXString.from_result(disable) def format(self, options=None): """ @@ -473,8 +472,7 @@ class Diagnostic(object): options = conf.lib.clang_defaultDiagnosticDisplayOptions() if options & ~Diagnostic._FormatOptionsMask: raise ValueError('Invalid format options') - formatted = conf.lib.clang_formatDiagnostic(self, options) - return conf.lib.clang_getCString(formatted) + return conf.lib.clang_formatDiagnostic(self, options) def __repr__(self): return "" % ( diff --git a/gnu/llvm/tools/clang/bindings/python/tests/cindex/test_diagnostics.py b/gnu/llvm/tools/clang/bindings/python/tests/cindex/test_diagnostics.py index ba6e545e8b1..23cbe89f658 100644 --- a/gnu/llvm/tools/clang/bindings/python/tests/cindex/test_diagnostics.py +++ b/gnu/llvm/tools/clang/bindings/python/tests/cindex/test_diagnostics.py @@ -92,3 +92,11 @@ def test_diagnostic_children(): assert children[0].spelling.endswith('declared here') assert children[0].location.line == 1 assert children[0].location.column == 1 + +def test_diagnostic_string_repr(): + tu = get_tu('struct MissingSemicolon{}') + assert len(tu.diagnostics) == 1 + d = tu.diagnostics[0] + + assert repr(d) == ', spelling "expected \';\' after struct">' + diff --git a/gnu/llvm/tools/clang/bindings/python/tests/cindex/test_exception_specification_kind.py b/gnu/llvm/tools/clang/bindings/python/tests/cindex/test_exception_specification_kind.py new file mode 100644 index 00000000000..543d47f7db9 --- /dev/null +++ b/gnu/llvm/tools/clang/bindings/python/tests/cindex/test_exception_specification_kind.py @@ -0,0 +1,27 @@ +import clang.cindex +from clang.cindex import ExceptionSpecificationKind +from .util import get_tu + + +def find_function_declarations(node, declarations=[]): + if node.kind == clang.cindex.CursorKind.FUNCTION_DECL: + declarations.append((node.spelling, node.exception_specification_kind)) + for child in node.get_children(): + declarations = find_function_declarations(child, declarations) + return declarations + + +def test_exception_specification_kind(): + source = """int square1(int x); + int square2(int x) noexcept; + int square3(int x) noexcept(noexcept(x * x));""" + + tu = get_tu(source, lang='cpp', flags=['-std=c++14']) + + declarations = find_function_declarations(tu.cursor) + expected = [ + ('square1', ExceptionSpecificationKind.NONE), + ('square2', ExceptionSpecificationKind.BASIC_NOEXCEPT), + ('square3', ExceptionSpecificationKind.COMPUTED_NOEXCEPT) + ] + assert declarations == expected diff --git a/gnu/llvm/tools/clang/include/clang/Basic/Attr.td b/gnu/llvm/tools/clang/include/clang/Basic/Attr.td index f13e13b0107..5c69635b949 100644 --- a/gnu/llvm/tools/clang/include/clang/Basic/Attr.td +++ b/gnu/llvm/tools/clang/include/clang/Basic/Attr.td @@ -2459,9 +2459,9 @@ def DLLImport : InheritableAttr, TargetSpecificAttr { let Documentation = [DLLImportDocs]; } -def SelectAny : InheritableAttr, TargetSpecificAttr { +def SelectAny : InheritableAttr { let Spellings = [Declspec<"selectany">, GCC<"selectany">]; - let Documentation = [Undocumented]; + let Documentation = [SelectAnyDocs]; } def Thread : Attr { diff --git a/gnu/llvm/tools/clang/include/clang/Basic/AttrDocs.td b/gnu/llvm/tools/clang/include/clang/Basic/AttrDocs.td index 33ef3ea4cad..567c7a3a53b 100644 --- a/gnu/llvm/tools/clang/include/clang/Basic/AttrDocs.td +++ b/gnu/llvm/tools/clang/include/clang/Basic/AttrDocs.td @@ -3106,3 +3106,18 @@ This attribute can be added to an Objective-C ``@interface`` declaration to ensure that this class cannot be subclassed. }]; } + + +def SelectAnyDocs : Documentation { + let Category = DocCatType; + let Content = [{ +This attribute appertains to a global symbol, causing it to have a weak +definition ( +`linkonce `_ +), allowing the linker to select any definition. + +For more information see +`gcc documentation `_ +or `msvc documentation `_. +}]; +} diff --git a/gnu/llvm/tools/clang/include/clang/Basic/BuiltinsX86.def b/gnu/llvm/tools/clang/include/clang/Basic/BuiltinsX86.def index 6d3a478ac36..2f8f8919e5b 100644 --- a/gnu/llvm/tools/clang/include/clang/Basic/BuiltinsX86.def +++ b/gnu/llvm/tools/clang/include/clang/Basic/BuiltinsX86.def @@ -976,7 +976,6 @@ TARGET_BUILTIN(__builtin_ia32_pmuludq512, "V8LLiV16iV16i", "", "avx512f") TARGET_BUILTIN(__builtin_ia32_ptestmd512, "UsV16iV16iUs", "", "avx512f") TARGET_BUILTIN(__builtin_ia32_ptestmq512, "UcV8LLiV8LLiUc", "", "avx512f") TARGET_BUILTIN(__builtin_ia32_pbroadcastd512_gpr_mask, "V16iiV16iUs", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pbroadcastq512_mem_mask, "V8LLiLLiV8LLiUc", "", "avx512f") TARGET_BUILTIN(__builtin_ia32_loaddqusi512_mask, "V16iiC*V16iUs", "", "avx512f") TARGET_BUILTIN(__builtin_ia32_loaddqudi512_mask, "V8LLiLLiC*V8LLiUc", "", "avx512f") TARGET_BUILTIN(__builtin_ia32_loadups512_mask, "V16ffC*V16fUs", "", "avx512f") diff --git a/gnu/llvm/tools/clang/lib/AST/ExprConstant.cpp b/gnu/llvm/tools/clang/lib/AST/ExprConstant.cpp index a26b608082f..792e8cc4a51 100644 --- a/gnu/llvm/tools/clang/lib/AST/ExprConstant.cpp +++ b/gnu/llvm/tools/clang/lib/AST/ExprConstant.cpp @@ -537,7 +537,7 @@ namespace { /// rules. For example, the RHS of (0 && foo()) is not evaluated. We can /// evaluate the expression regardless of what the RHS is, but C only allows /// certain things in certain situations. - struct LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) EvalInfo { + struct EvalInfo { ASTContext &Ctx; /// EvalStatus - Contains information about the evaluation. @@ -977,24 +977,22 @@ namespace { /// RAII object used to optionally suppress diagnostics and side-effects from /// a speculative evaluation. class SpeculativeEvaluationRAII { - /// Pair of EvalInfo, and a bit that stores whether or not we were - /// speculatively evaluating when we created this RAII. - llvm::PointerIntPair InfoAndOldSpecEval; - Expr::EvalStatus Old; + EvalInfo *Info = nullptr; + Expr::EvalStatus OldStatus; + bool OldIsSpeculativelyEvaluating; void moveFromAndCancel(SpeculativeEvaluationRAII &&Other) { - InfoAndOldSpecEval = Other.InfoAndOldSpecEval; - Old = Other.Old; - Other.InfoAndOldSpecEval.setPointer(nullptr); + Info = Other.Info; + OldStatus = Other.OldStatus; + Other.Info = nullptr; } void maybeRestoreState() { - EvalInfo *Info = InfoAndOldSpecEval.getPointer(); if (!Info) return; - Info->EvalStatus = Old; - Info->IsSpeculativelyEvaluating = InfoAndOldSpecEval.getInt(); + Info->EvalStatus = OldStatus; + Info->IsSpeculativelyEvaluating = OldIsSpeculativelyEvaluating; } public: @@ -1002,8 +1000,8 @@ namespace { SpeculativeEvaluationRAII( EvalInfo &Info, SmallVectorImpl *NewDiag = nullptr) - : InfoAndOldSpecEval(&Info, Info.IsSpeculativelyEvaluating), - Old(Info.EvalStatus) { + : Info(&Info), OldStatus(Info.EvalStatus), + OldIsSpeculativelyEvaluating(Info.IsSpeculativelyEvaluating) { Info.EvalStatus.Diag = NewDiag; Info.IsSpeculativelyEvaluating = true; } diff --git a/gnu/llvm/tools/clang/lib/Basic/Version.cpp b/gnu/llvm/tools/clang/lib/Basic/Version.cpp index 509c4a9ea05..2c569ff87d8 100644 --- a/gnu/llvm/tools/clang/lib/Basic/Version.cpp +++ b/gnu/llvm/tools/clang/lib/Basic/Version.cpp @@ -36,7 +36,7 @@ std::string getClangRepositoryPath() { // If the SVN_REPOSITORY is empty, try to use the SVN keyword. This helps us // pick up a tag in an SVN export, for example. - StringRef SVNRepository("$URL: https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_500/final/lib/Basic/Version.cpp $"); + StringRef SVNRepository("$URL: https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_501/final/lib/Basic/Version.cpp $"); if (URL.empty()) { URL = SVNRepository.slice(SVNRepository.find(':'), SVNRepository.find("/lib/Basic")); diff --git a/gnu/llvm/tools/clang/lib/CodeGen/CGExpr.cpp b/gnu/llvm/tools/clang/lib/CodeGen/CGExpr.cpp index 9572bd3543b..63c7b3d10bf 100644 --- a/gnu/llvm/tools/clang/lib/CodeGen/CGExpr.cpp +++ b/gnu/llvm/tools/clang/lib/CodeGen/CGExpr.cpp @@ -3309,12 +3309,7 @@ static Address emitOMPArraySectionBase(CodeGenFunction &CGF, const Expr *Base, LValue CodeGenFunction::EmitOMPArraySectionExpr(const OMPArraySectionExpr *E, bool IsLowerBound) { - QualType BaseTy; - if (auto *ASE = - dyn_cast(E->getBase()->IgnoreParenImpCasts())) - BaseTy = OMPArraySectionExpr::getBaseOriginalType(ASE); - else - BaseTy = E->getBase()->getType(); + QualType BaseTy = OMPArraySectionExpr::getBaseOriginalType(E->getBase()); QualType ResultExprTy; if (auto *AT = getContext().getAsArrayType(BaseTy)) ResultExprTy = AT->getElementType(); @@ -3619,8 +3614,9 @@ LValue CodeGenFunction::EmitLValueForField(LValue base, getFieldAlignmentSource(BaseInfo.getAlignmentSource()); LValueBaseInfo FieldBaseInfo(fieldAlignSource, BaseInfo.getMayAlias()); + QualType type = field->getType(); const RecordDecl *rec = field->getParent(); - if (rec->isUnion() || rec->hasAttr()) + if (rec->isUnion() || rec->hasAttr() || type->isVectorType()) FieldBaseInfo.setMayAlias(true); bool mayAlias = FieldBaseInfo.getMayAlias(); @@ -3645,7 +3641,6 @@ LValue CodeGenFunction::EmitLValueForField(LValue base, return LValue::MakeBitfield(Addr, Info, fieldType, FieldBaseInfo); } - QualType type = field->getType(); Address addr = base.getAddress(); unsigned cvr = base.getVRQualifiers(); bool TBAAPath = CGM.getCodeGenOpts().StructPathTBAA; diff --git a/gnu/llvm/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/gnu/llvm/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp index d488bd4b30b..9f8aa6c8d96 100644 --- a/gnu/llvm/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/gnu/llvm/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -264,6 +264,13 @@ public: return nullptr; } + /// \brief Get an LValue for the current ThreadID variable. + LValue getThreadIDVariableLValue(CodeGenFunction &CGF) override { + if (OuterRegionInfo) + return OuterRegionInfo->getThreadIDVariableLValue(CGF); + llvm_unreachable("No LValue for inlined OpenMP construct"); + } + /// \brief Get the name of the capture helper. StringRef getHelperName() const override { if (auto *OuterRegionInfo = getOldCSI()) @@ -771,7 +778,8 @@ static void emitInitWithReductionInitializer(CodeGenFunction &CGF, /// \param Init Initial expression of array. /// \param SrcAddr Address of the original array. static void EmitOMPAggregateInit(CodeGenFunction &CGF, Address DestAddr, - QualType Type, const Expr *Init, + QualType Type, bool EmitDeclareReductionInit, + const Expr *Init, const OMPDeclareReductionDecl *DRD, Address SrcAddr = Address::invalid()) { // Perform element-by-element initialization. @@ -825,7 +833,7 @@ static void EmitOMPAggregateInit(CodeGenFunction &CGF, Address DestAddr, // Emit copy. { CodeGenFunction::RunCleanupsScope InitScope(CGF); - if (DRD && (DRD->getInitializer() || !Init)) { + if (EmitDeclareReductionInit) { emitInitWithReductionInitializer(CGF, DRD, Init, DestElementCurrent, SrcElementCurrent, ElementTy); } else @@ -883,8 +891,12 @@ void ReductionCodeGen::emitAggregateInitialization( // captured region. auto *PrivateVD = cast(cast(ClausesData[N].Private)->getDecl()); + bool EmitDeclareReductionInit = + DRD && (DRD->getInitializer() || !PrivateVD->hasInit()); EmitOMPAggregateInit(CGF, PrivateAddr, PrivateVD->getType(), - DRD ? ClausesData[N].ReductionOp : PrivateVD->getInit(), + EmitDeclareReductionInit, + EmitDeclareReductionInit ? ClausesData[N].ReductionOp + : PrivateVD->getInit(), DRD, SharedLVal.getAddress()); } @@ -4244,9 +4256,20 @@ CGOpenMPRuntime::emitTaskInit(CodeGenFunction &CGF, SourceLocation Loc, // Build type kmp_routine_entry_t (if not built yet). emitKmpRoutineEntryT(KmpInt32Ty); // Build type kmp_task_t (if not built yet). - if (KmpTaskTQTy.isNull()) { - KmpTaskTQTy = C.getRecordType(createKmpTaskTRecordDecl( - CGM, D.getDirectiveKind(), KmpInt32Ty, KmpRoutineEntryPtrQTy)); + if (isOpenMPTaskLoopDirective(D.getDirectiveKind())) { + if (SavedKmpTaskloopTQTy.isNull()) { + SavedKmpTaskloopTQTy = C.getRecordType(createKmpTaskTRecordDecl( + CGM, D.getDirectiveKind(), KmpInt32Ty, KmpRoutineEntryPtrQTy)); + } + KmpTaskTQTy = SavedKmpTaskloopTQTy; + } else if (D.getDirectiveKind() == OMPD_task) { + assert(D.getDirectiveKind() == OMPD_task && + "Expected taskloop or task directive"); + if (SavedKmpTaskTQTy.isNull()) { + SavedKmpTaskTQTy = C.getRecordType(createKmpTaskTRecordDecl( + CGM, D.getDirectiveKind(), KmpInt32Ty, KmpRoutineEntryPtrQTy)); + } + KmpTaskTQTy = SavedKmpTaskTQTy; } auto *KmpTaskTQTyRD = cast(KmpTaskTQTy->getAsTagDecl()); // Build particular struct kmp_task_t for the given task. diff --git a/gnu/llvm/tools/clang/lib/CodeGen/CGOpenMPRuntime.h b/gnu/llvm/tools/clang/lib/CodeGen/CGOpenMPRuntime.h index 5dcf999bea3..185c01d5e54 100644 --- a/gnu/llvm/tools/clang/lib/CodeGen/CGOpenMPRuntime.h +++ b/gnu/llvm/tools/clang/lib/CodeGen/CGOpenMPRuntime.h @@ -313,6 +313,10 @@ private: /// deconstructors of firstprivate C++ objects */ /// } kmp_task_t; QualType KmpTaskTQTy; + /// Saved kmp_task_t for task directive. + QualType SavedKmpTaskTQTy; + /// Saved kmp_task_t for taskloop-based directive. + QualType SavedKmpTaskloopTQTy; /// \brief Type typedef struct kmp_depend_info { /// kmp_intptr_t base_addr; /// size_t len; diff --git a/gnu/llvm/tools/clang/lib/CodeGen/CGStmtOpenMP.cpp b/gnu/llvm/tools/clang/lib/CodeGen/CGStmtOpenMP.cpp index 6135cf31d17..cf430f860fd 100644 --- a/gnu/llvm/tools/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/gnu/llvm/tools/clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -1210,12 +1210,14 @@ void CodeGenFunction::EmitOMPInnerLoop( EmitBlock(LoopExit.getBlock()); } -void CodeGenFunction::EmitOMPLinearClauseInit(const OMPLoopDirective &D) { +bool CodeGenFunction::EmitOMPLinearClauseInit(const OMPLoopDirective &D) { if (!HaveInsertPoint()) - return; + return false; // Emit inits for the linear variables. + bool HasLinears = false; for (const auto *C : D.getClausesOfKind()) { for (auto *Init : C->inits()) { + HasLinears = true; auto *VD = cast(cast(Init)->getDecl()); if (auto *Ref = dyn_cast(VD->getInit()->IgnoreImpCasts())) { AutoVarEmission Emission = EmitAutoVarAlloca(*VD); @@ -1240,6 +1242,7 @@ void CodeGenFunction::EmitOMPLinearClauseInit(const OMPLoopDirective &D) { EmitIgnoredExpr(CS); } } + return HasLinears; } void CodeGenFunction::EmitOMPLinearClauseFinal( @@ -1529,7 +1532,7 @@ void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) { CGF.EmitOMPSimdInit(S); emitAlignedClause(CGF, S); - CGF.EmitOMPLinearClauseInit(S); + (void)CGF.EmitOMPLinearClauseInit(S); { OMPPrivateScope LoopScope(CGF); CGF.EmitOMPPrivateLoopCounters(S, LoopScope); @@ -2147,7 +2150,7 @@ bool CodeGenFunction::EmitOMPWorksharingLoop( llvm::DenseSet EmittedFinals; emitAlignedClause(*this, S); - EmitOMPLinearClauseInit(S); + bool HasLinears = EmitOMPLinearClauseInit(S); // Emit helper vars inits. std::pair Bounds = CodeGenLoopBounds(*this, S); @@ -2161,7 +2164,7 @@ bool CodeGenFunction::EmitOMPWorksharingLoop( // Emit 'then' code. { OMPPrivateScope LoopScope(*this); - if (EmitOMPFirstprivateClause(S, LoopScope)) { + if (EmitOMPFirstprivateClause(S, LoopScope) || HasLinears) { // Emit implicit barrier to synchronize threads and avoid data races on // initialization of firstprivate variables and post-update of // lastprivate variables. diff --git a/gnu/llvm/tools/clang/lib/CodeGen/CodeGenFunction.h b/gnu/llvm/tools/clang/lib/CodeGen/CodeGenFunction.h index 753dd92f307..6a1fa487ed1 100644 --- a/gnu/llvm/tools/clang/lib/CodeGen/CodeGenFunction.h +++ b/gnu/llvm/tools/clang/lib/CodeGen/CodeGenFunction.h @@ -1116,7 +1116,7 @@ private: auto IP = CGF.Builder.saveAndClearIP(); CGF.EmitBlock(Stack.back().ExitBlock.getBlock()); CodeGen(CGF); - CGF.EmitBranchThroughCleanup(Stack.back().ContBlock); + CGF.EmitBranch(Stack.back().ContBlock.getBlock()); CGF.Builder.restoreIP(IP); Stack.back().HasBeenEmitted = true; } @@ -2761,7 +2761,9 @@ public: /// and initializes them with the values according to OpenMP standard. /// /// \param D Directive (possibly) with the 'linear' clause. - void EmitOMPLinearClauseInit(const OMPLoopDirective &D); + /// \return true if at least one linear variable is found that should be + /// initialized with the value of the original variable, false otherwise. + bool EmitOMPLinearClauseInit(const OMPLoopDirective &D); typedef const llvm::function_refgetValue())) - D.Diag(diag::err_drv_invalid_thread_model_for_target) - << A->getValue() << A->getAsString(Args); - std::string CandidateLibPath = getArchSpecificLibPath(); if (getVFS().exists(CandidateLibPath)) getFilePaths().push_back(CandidateLibPath); diff --git a/gnu/llvm/tools/clang/lib/Driver/ToolChains/BareMetal.cpp b/gnu/llvm/tools/clang/lib/Driver/ToolChains/BareMetal.cpp index 5dc6dfad927..28e4f5b0e58 100644 --- a/gnu/llvm/tools/clang/lib/Driver/ToolChains/BareMetal.cpp +++ b/gnu/llvm/tools/clang/lib/Driver/ToolChains/BareMetal.cpp @@ -65,14 +65,6 @@ Tool *BareMetal::buildLinker() const { return new tools::baremetal::Linker(*this); } -std::string BareMetal::getThreadModel() const { - return "single"; -} - -bool BareMetal::isThreadModelSupported(const StringRef Model) const { - return Model == "single"; -} - std::string BareMetal::getRuntimesDir() const { SmallString<128> Dir(getDriver().ResourceDir); llvm::sys::path::append(Dir, "lib", "baremetal"); diff --git a/gnu/llvm/tools/clang/lib/Driver/ToolChains/BareMetal.h b/gnu/llvm/tools/clang/lib/Driver/ToolChains/BareMetal.h index 4b74899fa53..5e9fd9bffdb 100644 --- a/gnu/llvm/tools/clang/lib/Driver/ToolChains/BareMetal.h +++ b/gnu/llvm/tools/clang/lib/Driver/ToolChains/BareMetal.h @@ -38,8 +38,6 @@ public: bool isPICDefaultForced() const override { return false; } bool SupportsProfiling() const override { return false; } bool SupportsObjCGC() const override { return false; } - std::string getThreadModel() const override; - bool isThreadModelSupported(const StringRef Model) const override; RuntimeLibType GetDefaultRuntimeLibType() const override { return ToolChain::RLT_CompilerRT; diff --git a/gnu/llvm/tools/clang/lib/Format/Format.cpp b/gnu/llvm/tools/clang/lib/Format/Format.cpp index aa4ed8c42a7..6fe5be2c815 100644 --- a/gnu/llvm/tools/clang/lib/Format/Format.cpp +++ b/gnu/llvm/tools/clang/lib/Format/Format.cpp @@ -506,7 +506,7 @@ static FormatStyle expandPresets(const FormatStyle &Style) { Expanded.BraceWrapping.AfterFunction = true; Expanded.BraceWrapping.AfterStruct = true; Expanded.BraceWrapping.AfterUnion = true; - Expanded.BraceWrapping.SplitEmptyFunction = false; + Expanded.BraceWrapping.SplitEmptyFunction = true; Expanded.BraceWrapping.SplitEmptyRecord = false; break; case FormatStyle::BS_Stroustrup: diff --git a/gnu/llvm/tools/clang/lib/Headers/avx512fintrin.h b/gnu/llvm/tools/clang/lib/Headers/avx512fintrin.h index 4ce69453110..4b66acc02fa 100644 --- a/gnu/llvm/tools/clang/lib/Headers/avx512fintrin.h +++ b/gnu/llvm/tools/clang/lib/Headers/avx512fintrin.h @@ -267,21 +267,16 @@ _mm512_maskz_set1_epi32(__mmask16 __M, int __A) __M); } +#ifdef __x86_64__ static __inline __m512i __DEFAULT_FN_ATTRS _mm512_maskz_set1_epi64(__mmask8 __M, long long __A) { -#ifdef __x86_64__ return (__m512i) __builtin_ia32_pbroadcastq512_gpr_mask (__A, (__v8di) _mm512_setzero_si512 (), __M); -#else - return (__m512i) __builtin_ia32_pbroadcastq512_mem_mask (__A, - (__v8di) - _mm512_setzero_si512 (), - __M); -#endif } +#endif static __inline __m512 __DEFAULT_FN_ATTRS _mm512_setzero_ps(void) diff --git a/gnu/llvm/tools/clang/lib/Sema/SemaDecl.cpp b/gnu/llvm/tools/clang/lib/Sema/SemaDecl.cpp index 692a77e2b62..59c10128f90 100644 --- a/gnu/llvm/tools/clang/lib/Sema/SemaDecl.cpp +++ b/gnu/llvm/tools/clang/lib/Sema/SemaDecl.cpp @@ -1603,7 +1603,24 @@ static bool ShouldDiagnoseUnusedDecl(const NamedDecl *D) { if (D->isInvalidDecl()) return false; - if (D->isReferenced() || D->isUsed() || D->hasAttr() || + bool Referenced = false; + if (auto *DD = dyn_cast(D)) { + // For a decomposition declaration, warn if none of the bindings are + // referenced, instead of if the variable itself is referenced (which + // it is, by the bindings' expressions). + for (auto *BD : DD->bindings()) { + if (BD->isReferenced()) { + Referenced = true; + break; + } + } + } else if (!D->getDeclName()) { + return false; + } else if (D->isReferenced() || D->isUsed()) { + Referenced = true; + } + + if (Referenced || D->hasAttr() || D->hasAttr()) return false; @@ -1726,7 +1743,7 @@ void Sema::DiagnoseUnusedDecl(const NamedDecl *D) { else DiagID = diag::warn_unused_variable; - Diag(D->getLocation(), DiagID) << D->getDeclName() << Hint; + Diag(D->getLocation(), DiagID) << D << Hint; } static void CheckPoppedLabel(LabelDecl *L, Sema &S) { @@ -1756,8 +1773,6 @@ void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) { assert(isa(TmpD) && "Decl isn't NamedDecl?"); NamedDecl *D = cast(TmpD); - if (!D->getDeclName()) continue; - // Diagnose unused variables in this scope. if (!S->hasUnrecoverableErrorOccurred()) { DiagnoseUnusedDecl(D); @@ -1765,6 +1780,8 @@ void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) { DiagnoseUnusedNestedTypedefs(RD); } + if (!D->getDeclName()) continue; + // If this was a forward reference to a label, verify it was defined. if (LabelDecl *LD = dyn_cast(D)) CheckPoppedLabel(LD, *this); @@ -6155,7 +6172,6 @@ NamedDecl *Sema::ActOnVariableDeclarator( IdentifierInfo *II = Name.getAsIdentifierInfo(); if (D.isDecompositionDeclarator()) { - AddToScope = false; // Take the name of the first declarator as our name for diagnostic // purposes. auto &Decomp = D.getDecompositionDeclarator(); diff --git a/gnu/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp b/gnu/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp index c05e5f02070..28323f365af 100644 --- a/gnu/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp +++ b/gnu/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp @@ -826,7 +826,10 @@ Sema::ActOnDecompositionDeclarator(Scope *S, Declarator &D, NamedDecl *New = ActOnVariableDeclarator(S, D, DC, TInfo, Previous, MultiTemplateParamsArg(), AddToScope, Bindings); - CurContext->addHiddenDecl(New); + if (AddToScope) { + S->AddDecl(New); + CurContext->addHiddenDecl(New); + } if (isInOpenMPDeclareTargetContext()) checkDeclIsAllowedInOpenMPTarget(nullptr, New); diff --git a/gnu/llvm/tools/clang/lib/Sema/SemaOpenMP.cpp b/gnu/llvm/tools/clang/lib/Sema/SemaOpenMP.cpp index 01f574b6aee..1ae6f9d6c19 100644 --- a/gnu/llvm/tools/clang/lib/Sema/SemaOpenMP.cpp +++ b/gnu/llvm/tools/clang/lib/Sema/SemaOpenMP.cpp @@ -3111,8 +3111,8 @@ bool OpenMPIterationSpaceChecker::SetStep(Expr *NewStep, bool Subtract) { if (!NewStep->isValueDependent()) { // Check that the step is integer expression. SourceLocation StepLoc = NewStep->getLocStart(); - ExprResult Val = - SemaRef.PerformOpenMPImplicitIntegerConversion(StepLoc, NewStep); + ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( + StepLoc, getExprAsWritten(NewStep)); if (Val.isInvalid()) return true; NewStep = Val.get(); @@ -8858,7 +8858,8 @@ buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, PrevD = D; } } - if (Ty->isDependentType() || Ty->isInstantiationDependentType() || + if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || + Ty->isInstantiationDependentType() || Ty->containsUnexpandedParameterPack() || filterLookupForUDR(Lookups, [](ValueDecl *D) -> bool { return !D->isInvalidDecl() && @@ -10226,9 +10227,14 @@ Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, if (!CurContext->isDependentContext() && DSAStack->getParentOrderedRegionParam() && DepCounter != DSAStack->isParentLoopControlVariable(D).first) { - Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) - << DSAStack->getParentLoopControlVariable( - DepCounter.getZExtValue()); + ValueDecl* VD = DSAStack->getParentLoopControlVariable( + DepCounter.getZExtValue()); + if (VD) { + Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) + << 1 << VD; + } else { + Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; + } continue; } OpsOffs.push_back({RHS, OOK}); @@ -10258,8 +10264,9 @@ Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && TotalDepCount > VarList.size() && - DSAStack->getParentOrderedRegionParam()) { - Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) + DSAStack->getParentOrderedRegionParam() && + DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { + Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); } if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && diff --git a/gnu/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/gnu/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 6fee23aa8bc..4a26efcc943 100644 --- a/gnu/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/gnu/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -677,6 +677,7 @@ TemplateDeclInstantiator::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) { Decl *TemplateDeclInstantiator::VisitBindingDecl(BindingDecl *D) { auto *NewBD = BindingDecl::Create(SemaRef.Context, Owner, D->getLocation(), D->getIdentifier()); + NewBD->setReferenced(D->isReferenced()); SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, NewBD); return NewBD; } diff --git a/gnu/llvm/tools/clang/tools/clang-format/clang-format.py b/gnu/llvm/tools/clang/tools/clang-format/clang-format.py index 2412566346f..187125ed09a 100644 --- a/gnu/llvm/tools/clang/tools/clang-format/clang-format.py +++ b/gnu/llvm/tools/clang/tools/clang-format/clang-format.py @@ -62,7 +62,7 @@ def main(): # Determine range to format. if vim.eval('exists("l:lines")') == '1': - lines = vim.eval('l:lines') + lines = ['-lines', vim.eval('l:lines')] elif vim.eval('exists("l:formatdiff")') == '1': with open(vim.current.buffer.name, 'r') as f: ondisk = f.read().splitlines(); diff --git a/gnu/llvm/tools/clang/www/cxx_dr_status.html b/gnu/llvm/tools/clang/www/cxx_dr_status.html index c2e03033a77..79a774c252c 100644 --- a/gnu/llvm/tools/clang/www/cxx_dr_status.html +++ b/gnu/llvm/tools/clang/www/cxx_dr_status.html @@ -28,7 +28,7 @@

C++ Defect Report Support in Clang

-

Last updated: $Date: 2017/10/04 20:27:42 $

+

Last updated: $Date: 2017/12/24 23:15:40 $

C++ defect report implementation status

diff --git a/gnu/llvm/tools/clang/www/cxx_status.html b/gnu/llvm/tools/clang/www/cxx_status.html index 5f84e4c162f..8bc93648fbd 100644 --- a/gnu/llvm/tools/clang/www/cxx_status.html +++ b/gnu/llvm/tools/clang/www/cxx_status.html @@ -26,7 +26,7 @@

C++ Support in Clang

-

Last updated: $Date: 2017/10/04 20:27:42 $

+

Last updated: $Date: 2017/12/24 23:15:40 $

Clang fully implements all published ISO C++ standards (C++98 / C++03, Cies; // CIE records are uniquified by their contents and personality functions. - llvm::DenseMap, SymbolBody *>, CieRecord> CieMap; + llvm::DenseMap, SymbolBody *>, CieRecord *> + CieMap; }; class GotSection : public SyntheticSection { diff --git a/gnu/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler.h b/gnu/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler.h index 70a63bd1004..6028006ca9d 100644 --- a/gnu/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler.h +++ b/gnu/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler.h @@ -112,6 +112,10 @@ public: /// info in final executables. virtual bool isLazyPointer(const Reference &); + /// Reference from an __stub_helper entry to the required offset of the + /// lazy bind commands. + virtual Reference::KindValue lazyImmediateLocationKind() = 0; + /// Returns true if the specified relocation is paired to the next relocation. virtual bool isPairedReloc(const normalized::Relocation &) = 0; diff --git a/gnu/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler_arm.cpp b/gnu/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler_arm.cpp index 7d1544854cf..2f663c660f5 100644 --- a/gnu/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler_arm.cpp +++ b/gnu/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler_arm.cpp @@ -67,6 +67,10 @@ public: return invalid; } + Reference::KindValue lazyImmediateLocationKind() override { + return lazyImmediateLocation; + } + Reference::KindValue pointerKind() override { return invalid; } diff --git a/gnu/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp b/gnu/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp index 10360b5c6dd..b9c815c5a32 100644 --- a/gnu/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp +++ b/gnu/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp @@ -127,6 +127,10 @@ public: return pointer64; } + Reference::KindValue lazyImmediateLocationKind() override { + return lazyImmediateLocation; + } + uint32_t dwarfCompactUnwindType() override { return 0x03000000; } diff --git a/gnu/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler_x86.cpp b/gnu/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler_x86.cpp index 2272bff65cc..a2c68092724 100644 --- a/gnu/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler_x86.cpp +++ b/gnu/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler_x86.cpp @@ -70,6 +70,10 @@ public: return delta32; } + Reference::KindValue lazyImmediateLocationKind() override { + return lazyImmediateLocation; + } + Reference::KindValue unwindRefToEhFrameKind() override { return invalid; } diff --git a/gnu/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp b/gnu/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp index d687ca5de5b..aee9959ca6b 100644 --- a/gnu/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp +++ b/gnu/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp @@ -116,6 +116,10 @@ public: return unwindFDEToFunction; } + Reference::KindValue lazyImmediateLocationKind() override { + return lazyImmediateLocation; + } + Reference::KindValue unwindRefToEhFrameKind() override { return unwindInfoToEhFrame; } diff --git a/gnu/llvm/tools/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp b/gnu/llvm/tools/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp index e58e3d2e7a4..f2e5ed78167 100644 --- a/gnu/llvm/tools/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp +++ b/gnu/llvm/tools/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp @@ -172,6 +172,8 @@ private: SymbolScope &symbolScope); void appendSection(SectionInfo *si, NormalizedFile &file); uint32_t sectionIndexForAtom(const Atom *atom); + void fixLazyReferenceImm(const DefinedAtom *atom, uint32_t offset, + NormalizedFile &file); typedef llvm::DenseMap AtomToIndex; struct AtomAndIndex { const Atom *atom; uint32_t index; SymbolScope scope; }; @@ -1423,6 +1425,8 @@ void Util::addRebaseAndBindingInfo(const lld::File &atomFile, uint8_t segmentIndex; uint64_t segmentStartAddr; + uint32_t offsetInBindInfo = 0; + for (SectionInfo *sect : _sectionInfos) { segIndexForSection(sect, segmentIndex, segmentStartAddr); for (const AtomInfo &info : sect->atomsAndOffsets) { @@ -1467,6 +1471,59 @@ void Util::addRebaseAndBindingInfo(const lld::File &atomFile, bind.symbolName = targ->name(); bind.addend = ref->addend(); nFile.lazyBindingInfo.push_back(bind); + + // Now that we know the segmentOffset and the ordinal attribute, + // we can fix the helper's code + + fixLazyReferenceImm(atom, offsetInBindInfo, nFile); + + // 5 bytes for opcodes + variable sizes (target name + \0 and offset + // encode's size) + offsetInBindInfo += + 6 + targ->name().size() + llvm::getULEB128Size(bind.segOffset); + if (bind.ordinal > BIND_IMMEDIATE_MASK) + offsetInBindInfo += llvm::getULEB128Size(bind.ordinal); + } + } + } + } +} + +void Util::fixLazyReferenceImm(const DefinedAtom *atom, uint32_t offset, + NormalizedFile &file) { + for (const auto &ref : *atom) { + const DefinedAtom *da = dyn_cast(ref->target()); + if (da == nullptr) + return; + + const Reference *helperRef = nullptr; + for (const Reference *hr : *da) { + if (hr->kindValue() == _archHandler.lazyImmediateLocationKind()) { + helperRef = hr; + break; + } + } + if (helperRef == nullptr) + continue; + + // TODO: maybe get the fixed atom content from _archHandler ? + for (SectionInfo *sectInfo : _sectionInfos) { + for (const AtomInfo &atomInfo : sectInfo->atomsAndOffsets) { + if (atomInfo.atom == helperRef->target()) { + auto sectionContent = + file.sections[sectInfo->normalizedSectionIndex].content; + uint8_t *rawb = + file.ownedAllocations.Allocate(sectionContent.size()); + llvm::MutableArrayRef newContent{rawb, + sectionContent.size()}; + std::copy(sectionContent.begin(), sectionContent.end(), + newContent.begin()); + llvm::support::ulittle32_t *loc = + reinterpret_cast( + &newContent[atomInfo.offsetInSection + + helperRef->offsetInAtom()]); + *loc = offset; + file.sections[sectInfo->normalizedSectionIndex].content = newContent; } } } diff --git a/gnu/llvm/tools/lldb/source/Expression/IRExecutionUnit.cpp b/gnu/llvm/tools/lldb/source/Expression/IRExecutionUnit.cpp index e31483f1728..363e6fe8678 100644 --- a/gnu/llvm/tools/lldb/source/Expression/IRExecutionUnit.cpp +++ b/gnu/llvm/tools/lldb/source/Expression/IRExecutionUnit.cpp @@ -282,8 +282,7 @@ void IRExecutionUnit::GetRunnableInfo(Status &error, lldb::addr_t &func_addr, .setMCJITMemoryManager( std::unique_ptr(new MemoryManager(*this))) .setCodeModel(codeModel) - .setOptLevel(llvm::CodeGenOpt::Less) - .setUseOrcMCJITReplacement(true); + .setOptLevel(llvm::CodeGenOpt::Less); llvm::StringRef mArch; llvm::StringRef mCPU; diff --git a/gnu/llvm/tools/lldb/unittests/tools/lldb-server/tests/MessageObjects.cpp b/gnu/llvm/tools/lldb/unittests/tools/lldb-server/tests/MessageObjects.cpp index 9fcb4207675..6ac067bce06 100644 --- a/gnu/llvm/tools/lldb/unittests/tools/lldb-server/tests/MessageObjects.cpp +++ b/gnu/llvm/tools/lldb/unittests/tools/lldb-server/tests/MessageObjects.cpp @@ -67,8 +67,8 @@ StringRef ThreadInfo::ReadRegister(unsigned int register_id) const { bool ThreadInfo::ReadRegisterAsUint64(unsigned int register_id, uint64_t &value) const { - StringRef value_str(m_registers.lookup(register_id)); - if (value_str.getAsInteger(16, value)) { + std::string value_str(m_registers.lookup(register_id)); + if (!llvm::to_integer(value_str, value, 16)) { GTEST_LOG_(ERROR) << formatv("ThreadInfo: Unable to parse register value at {0}.", register_id) diff --git a/gnu/llvm/unittests/Support/FormatVariadicTest.cpp b/gnu/llvm/unittests/Support/FormatVariadicTest.cpp index 5387a8ae499..bfbe556b31a 100644 --- a/gnu/llvm/unittests/Support/FormatVariadicTest.cpp +++ b/gnu/llvm/unittests/Support/FormatVariadicTest.cpp @@ -553,6 +553,12 @@ TEST(FormatVariadicTest, Adapter) { formatv("{0,=34:X-}", fmt_repeat(fmt_pad(N, 1, 3), 5)).str()); } +TEST(FormatVariadicTest, MoveConstructor) { + auto fmt = formatv("{0} {1}", 1, 2); + auto fmt2 = std::move(fmt); + std::string S = fmt2; + EXPECT_EQ("1 2", S); +} TEST(FormatVariadicTest, ImplicitConversions) { std::string S = formatv("{0} {1}", 1, 2); EXPECT_EQ("1 2", S); diff --git a/gnu/llvm/unittests/Support/Host.cpp b/gnu/llvm/unittests/Support/Host.cpp index 4f895e7163c..7c018ac5042 100644 --- a/gnu/llvm/unittests/Support/Host.cpp +++ b/gnu/llvm/unittests/Support/Host.cpp @@ -105,6 +105,9 @@ TEST(getLinuxHostCPUName, AArch64) { EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x51\n" "CPU part : 0x201"), "kryo"); + EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x51\n" + "CPU part : 0xc00"), + "falkor"); // MSM8992/4 weirdness StringRef MSM8992ProcCpuInfo = R"( diff --git a/gnu/llvm/utils/release/merge-request.sh b/gnu/llvm/utils/release/merge-request.sh index 703023aaa79..6691b3733bb 100755 --- a/gnu/llvm/utils/release/merge-request.sh +++ b/gnu/llvm/utils/release/merge-request.sh @@ -14,7 +14,7 @@ dryrun="" stable_version="" -revision="" +revisions="" BUGZILLA_BIN="" BUGZILLA_CMD="" release_metabug="" @@ -31,6 +31,7 @@ function usage() { echo " -user EMAIL Your email address for logging into bugzilla." echo " -stable-version X.Y The stable release version (e.g. 4.0, 5.0)." echo " -r NUM Revision number to merge (e.g. 1234567)." + echo " This option can be specified multiple times." echo " -bugzilla-bin PATH Path to bugzilla binary (optional)." echo " -assign-to EMAIL Assign bug to user with EMAIL (optional)." echo " -dry-run Print commands instead of executing them." @@ -48,7 +49,7 @@ while [ $# -gt 0 ]; do ;; -r) shift - revision="$1" + revisions="$revisions $1" ;; -project) shift @@ -91,14 +92,17 @@ case $stable_version in 4.0) release_metabug="32061" ;; + 5.0) + release_metabug="34492" + ;; *) echo "error: invalid stable version" exit 1 esac bugzilla_version=$stable_version -if [ -z "$revision" ]; then - echo "error: revision not specified" +if [ -z "$revisions" ]; then + echo "error: no revisions specified" exit 1 fi @@ -124,25 +128,23 @@ BUGZILLA_MAJOR_VERSION=`$BUGZILLA_BIN --version 2>&1 | cut -d . -f 1` if [ $BUGZILLA_MAJOR_VERSION -eq 1 ]; then - echo "***************************** Warning *******************************" - echo "You are using an older version of the bugzilla cli tool. You will be " - echo "able to create bugs, but this script will crash with the following " - echo "error when trying to read back information about the bug you created:" - echo "" - echo "KeyError: 'internals'" - echo "" - echo "To avoid this error, use version 2.0.0 or higher" - echo "https://pypi.python.org/pypi/python-bugzilla" - echo "*********************************************************************" + echo "***************************** Error ** ********************************" + echo "You are using an older version of the bugzilla cli tool, which is not " + echo "supported. You need to use bugzilla cli version 2.0.0 or higher:" + echo "***********************************************************************" + exit 1 fi BUGZILLA_CMD="$BUGZILLA_BIN --bugzilla=$bugzilla_url" -bug_url="https://reviews.llvm.org/rL$revision" +rev_string="" +for r in $revisions; do + rev_string="$rev_string r$r" +done echo "Checking for duplicate bugs..." -check_duplicates=`$BUGZILLA_CMD query --url $bug_url` +check_duplicates=`$BUGZILLA_CMD query --blocked=$release_metabug --field="cf_fixed_by_commits=$rev_string"` if [ -n "$check_duplicates" ]; then echo "Duplicate bug found:" @@ -152,47 +154,55 @@ fi echo "Done" -# Get short commit summary +# Get short commit summary. To avoid having a huge summary, we just +# use the commit message for the first commit. commit_summary='' -commit_msg=`svn log -r $revision https://llvm.org/svn/llvm-project/` -if [ $? -ne 0 ]; then - echo "warning: failed to get commit message." - commit_msg="" -fi +for r in $revisions; do + commit_msg=`svn log -r $r https://llvm.org/svn/llvm-project/` + if [ $? -ne 0 ]; then + echo "warning: failed to get commit message." + commit_msg="" + fi + break +done if [ -n "$commit_msg" ]; then commit_summary=`echo "$commit_msg" | sed '4q;d' | cut -c1-80` commit_summary=" : ${commit_summary}" fi -bug_summary="Merge r$revision into the $stable_version branch${commit_summary}" +bug_summary="Merge${rev_string} into the $stable_version branch${commit_summary}" -if [ -z "$dryrun" ]; then - set -x -fi +set -x + +# Login to bugzilla +$BUGZILLA_CMD login $bugzilla_user -${dryrun} $BUGZILLA_CMD --login --user=$bugzilla_user new \ +bug_id=`${dryrun} $BUGZILLA_CMD --ensure-logged-in new \ -p "$bugzilla_product" \ - -c "$bugzilla_component" -u $bug_url --blocked=$release_metabug \ + -c "$bugzilla_component" --blocked=$release_metabug \ -o All --priority=P --arch All -v $bugzilla_version \ + --field="cf_fixed_by_commits=$rev_string" \ --summary "${bug_summary}" \ - -l "Is this patch OK to merge to the $stable_version branch?" \ + -l "Is it OK to merge the following revision(s) to the $stable_version branch?" \ $bugzilla_assigned_to \ - --oneline - -set +x + -i` if [ -n "$dryrun" ]; then exit 0 fi -if [ $BUGZILLA_MAJOR_VERSION -eq 1 ]; then - success=`$BUGZILLA_CMD query --url $bug_url` - if [ -z "$success" ]; then - echo "Failed to create bug." - exit 1 - fi +set +x - echo " Created new bug:" - echo $success +if [ -z "$bug_id" ]; then + echo "Failed to create bug." + exit 1 fi + +echo " Created new bug:" +echo https://llvm.org/PR$bug_id + +# Add links to revisions +for r in $revisions; do + $BUGZILLA_CMD --ensure-logged-in modify -l "https://reviews.llvm.org/rL$r" $bug_id +done