Author: dim Date: Sat Jun 27 18:34:17 2020 New Revision: 362703 URL: https://svnweb.freebsd.org/changeset/base/362703
Log: Vendor import of llvm-project branch release/10.x llvmorg-10.0.1-rc2-0-g77d76b71d7d. Added: vendor/llvm-project/release-10.x/compiler-rt/lib/builtins/riscv/int_mul_impl.inc (contents, props changed) vendor/llvm-project/release-10.x/compiler-rt/lib/builtins/riscv/muldi3.S (contents, props changed) vendor/llvm-project/release-10.x/llvm/tools/llvm-dwp/ vendor/llvm-project/release-10.x/llvm/tools/llvm-dwp/DWPError.cpp (contents, props changed) vendor/llvm-project/release-10.x/llvm/tools/llvm-dwp/DWPError.h (contents, props changed) vendor/llvm-project/release-10.x/llvm/tools/llvm-dwp/DWPStringPool.h (contents, props changed) vendor/llvm-project/release-10.x/llvm/tools/llvm-dwp/llvm-dwp.cpp (contents, props changed) vendor/llvm-project/release-10.x/llvm/tools/llvm-size/ vendor/llvm-project/release-10.x/llvm/tools/llvm-size/llvm-size.cpp (contents, props changed) vendor/llvm-project/release-10.x/llvm/tools/llvm-strings/ vendor/llvm-project/release-10.x/llvm/tools/llvm-strings/llvm-strings.cpp (contents, props changed) Modified: vendor/llvm-project/release-10.x/clang/lib/CodeGen/TargetInfo.cpp vendor/llvm-project/release-10.x/compiler-rt/lib/builtins/riscv/mulsi3.S vendor/llvm-project/release-10.x/libcxx/include/array vendor/llvm-project/release-10.x/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp vendor/llvm-project/release-10.x/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp vendor/llvm-project/release-10.x/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp vendor/llvm-project/release-10.x/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp vendor/llvm-project/release-10.x/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp vendor/llvm-project/release-10.x/llvm/lib/Target/RISCV/RISCVISelLowering.cpp Modified: vendor/llvm-project/release-10.x/clang/lib/CodeGen/TargetInfo.cpp ============================================================================== --- vendor/llvm-project/release-10.x/clang/lib/CodeGen/TargetInfo.cpp Sat Jun 27 17:39:13 2020 (r362702) +++ vendor/llvm-project/release-10.x/clang/lib/CodeGen/TargetInfo.cpp Sat Jun 27 18:34:17 2020 (r362703) @@ -9613,7 +9613,8 @@ ABIArgInfo RISCVABIInfo::classifyArgumentType(QualType uint64_t Size = getContext().getTypeSize(Ty); // Pass floating point values via FPRs if possible. - if (IsFixed && Ty->isFloatingType() && FLen >= Size && ArgFPRsLeft) { + if (IsFixed && Ty->isFloatingType() && !Ty->isComplexType() && + FLen >= Size && ArgFPRsLeft) { ArgFPRsLeft--; return ABIArgInfo::getDirect(); } Added: vendor/llvm-project/release-10.x/compiler-rt/lib/builtins/riscv/int_mul_impl.inc ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ vendor/llvm-project/release-10.x/compiler-rt/lib/builtins/riscv/int_mul_impl.inc Sat Jun 27 18:34:17 2020 (r362703) @@ -0,0 +1,31 @@ +//===-- int_mul_impl.inc - Integer multiplication -------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Helpers used by __mulsi3, __muldi3. +// +//===----------------------------------------------------------------------===// + +#if !defined(__riscv_mul) + .text + .align 2 + + .globl __mulxi3 + .type __mulxi3, @function +__mulxi3: + mv a2, a0 + mv a0, zero +.L1: + andi a3, a1, 1 + beqz a3, .L2 + add a0, a0, a2 +.L2: + srli a1, a1, 1 + slli a2, a2, 1 + bnez a1, .L1 + ret +#endif Added: vendor/llvm-project/release-10.x/compiler-rt/lib/builtins/riscv/muldi3.S ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ vendor/llvm-project/release-10.x/compiler-rt/lib/builtins/riscv/muldi3.S Sat Jun 27 18:34:17 2020 (r362703) @@ -0,0 +1,11 @@ +//===--- muldi3.S - Integer multiplication routines -----------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#if __riscv_xlen == 64 +#define __mulxi3 __muldi3 +#include "int_mul_impl.inc" +#endif Modified: vendor/llvm-project/release-10.x/compiler-rt/lib/builtins/riscv/mulsi3.S ============================================================================== --- vendor/llvm-project/release-10.x/compiler-rt/lib/builtins/riscv/mulsi3.S Sat Jun 27 17:39:13 2020 (r362702) +++ vendor/llvm-project/release-10.x/compiler-rt/lib/builtins/riscv/mulsi3.S Sat Jun 27 18:34:17 2020 (r362703) @@ -1,4 +1,4 @@ -//===--- mulsi3.S - Integer multiplication routines routines ---===// +//===--- mulsi3.S - Integer multiplication routines -----------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,22 +6,7 @@ // //===----------------------------------------------------------------------===// -#if !defined(__riscv_mul) && __riscv_xlen == 32 - .text - .align 2 - - .globl __mulsi3 - .type __mulsi3, @function -__mulsi3: - mv a2, a0 - mv a0, zero -.L1: - andi a3, a1, 1 - beqz a3, .L2 - add a0, a0, a2 -.L2: - srli a1, a1, 1 - slli a2, a2, 1 - bnez a1, .L1 - ret +#if __riscv_xlen == 32 +#define __mulxi3 __mulsi3 +#include "int_mul_impl.inc" #endif Modified: vendor/llvm-project/release-10.x/libcxx/include/array ============================================================================== --- vendor/llvm-project/release-10.x/libcxx/include/array Sat Jun 27 17:39:13 2020 (r362702) +++ vendor/llvm-project/release-10.x/libcxx/include/array Sat Jun 27 18:34:17 2020 (r362703) @@ -359,7 +359,7 @@ struct _LIBCPP_TEMPLATE_VIS array<_Tp, 0> #ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES template<class _Tp, class... _Args, - class = typename enable_if<(is_same_v<_Tp, _Args> && ...), void>::type + class = _EnableIf<__all<_IsSame<_Tp, _Args>::value...>::value> > array(_Tp, _Args...) -> array<_Tp, 1 + sizeof...(_Args)>; Modified: vendor/llvm-project/release-10.x/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp ============================================================================== --- vendor/llvm-project/release-10.x/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp Sat Jun 27 17:39:13 2020 (r362702) +++ vendor/llvm-project/release-10.x/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp Sat Jun 27 18:34:17 2020 (r362703) @@ -271,8 +271,20 @@ SDValue DAGTypeLegalizer::PromoteIntRes_AtomicCmpSwap( return Res.getValue(1); } - SDValue Op2 = GetPromotedInteger(N->getOperand(2)); + // Op2 is used for the comparison and thus must be extended according to the + // target's atomic operations. Op3 is merely stored and so can be left alone. + SDValue Op2 = N->getOperand(2); SDValue Op3 = GetPromotedInteger(N->getOperand(3)); + if (TLI.getTargetMachine().getTargetTriple().isRISCV()) { + // The comparison argument must be sign-extended for RISC-V. This is + // abstracted using a new TargetLowering hook in the main LLVM development + // branch, but handled here directly in order to fix the codegen bug for + // 10.x without breaking the libLLVM.so ABI. + Op2 = SExtPromotedInteger(Op2); + } else { + Op2 = GetPromotedInteger(Op2); + } + SDVTList VTs = DAG.getVTList(Op2.getValueType(), N->getValueType(1), MVT::Other); SDValue Res = DAG.getAtomicCmpSwap( Modified: vendor/llvm-project/release-10.x/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp ============================================================================== --- vendor/llvm-project/release-10.x/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp Sat Jun 27 17:39:13 2020 (r362702) +++ vendor/llvm-project/release-10.x/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp Sat Jun 27 18:34:17 2020 (r362703) @@ -5490,10 +5490,21 @@ char TargetLowering::isNegatibleForFree(SDValue Op, Se EVT VT = Op.getValueType(); const SDNodeFlags Flags = Op->getFlags(); const TargetOptions &Options = DAG.getTarget().Options; - if (!Op.hasOneUse() && !(Op.getOpcode() == ISD::FP_EXTEND && - isFPExtFree(VT, Op.getOperand(0).getValueType()))) - return 0; + if (!Op.hasOneUse()) { + bool IsFreeExtend = Op.getOpcode() == ISD::FP_EXTEND && + isFPExtFree(VT, Op.getOperand(0).getValueType()); + // If we already have the use of the negated floating constant, it is free + // to negate it even it has multiple uses. + bool IsFreeConstant = + Op.getOpcode() == ISD::ConstantFP && + !getNegatedExpression(Op, DAG, LegalOperations, ForCodeSize) + .use_empty(); + + if (!IsFreeExtend && !IsFreeConstant) + return 0; + } + // Don't recurse exponentially. if (Depth > SelectionDAG::MaxRecursionDepth) return 0; @@ -5687,14 +5698,7 @@ SDValue TargetLowering::getNegatedExpression(SDValue O ForCodeSize, Depth + 1); char V1 = isNegatibleForFree(Op.getOperand(1), DAG, LegalOperations, ForCodeSize, Depth + 1); - // TODO: This is a hack. It is possible that costs have changed between now - // and the initial calls to isNegatibleForFree(). That is because we - // are rewriting the expression, and that may change the number of - // uses (and therefore the cost) of values. If the negation costs are - // equal, only negate this value if it is a constant. Otherwise, try - // operand 1. A better fix would eliminate uses as a cost factor or - // track the change in uses as we rewrite the expression. - if (V0 > V1 || (V0 == V1 && isa<ConstantFPSDNode>(Op.getOperand(0)))) { + if (V0 > V1) { // fold (fneg (fma X, Y, Z)) -> (fma (fneg X), Y, (fneg Z)) SDValue Neg0 = getNegatedExpression( Op.getOperand(0), DAG, LegalOperations, ForCodeSize, Depth + 1); Modified: vendor/llvm-project/release-10.x/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp ============================================================================== --- vendor/llvm-project/release-10.x/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp Sat Jun 27 17:39:13 2020 (r362702) +++ vendor/llvm-project/release-10.x/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp Sat Jun 27 18:34:17 2020 (r362703) @@ -211,6 +211,24 @@ AArch64FrameLowering::getStackIDForScalableVectors() c return TargetStackID::SVEVector; } +/// Returns the size of the fixed object area (allocated next to sp on entry) +/// On Win64 this may include a var args area and an UnwindHelp object for EH. +static unsigned getFixedObjectSize(const MachineFunction &MF, + const AArch64FunctionInfo *AFI, bool IsWin64, + bool IsFunclet) { + if (!IsWin64 || IsFunclet) { + // Only Win64 uses fixed objects, and then only for the function (not + // funclets) + return 0; + } else { + // Var args are stored here in the primary function. + const unsigned VarArgsArea = AFI->getVarArgsGPRSize(); + // To support EH funclets we allocate an UnwindHelp object + const unsigned UnwindHelpObject = (MF.hasEHFunclets() ? 8 : 0); + return alignTo(VarArgsArea + UnwindHelpObject, 16); + } +} + /// Returns the size of the entire SVE stackframe (calleesaves + spills). static StackOffset getSVEStackSize(const MachineFunction &MF) { const AArch64FunctionInfo *AFI = MF.getInfo<AArch64FunctionInfo>(); @@ -959,10 +977,7 @@ void AArch64FrameLowering::emitPrologue(MachineFunctio bool IsWin64 = Subtarget.isCallingConvWin64(MF.getFunction().getCallingConv()); - // Var args are accounted for in the containing function, so don't - // include them for funclets. - unsigned FixedObject = (IsWin64 && !IsFunclet) ? - alignTo(AFI->getVarArgsGPRSize(), 16) : 0; + unsigned FixedObject = getFixedObjectSize(MF, AFI, IsWin64, IsFunclet); auto PrologueSaveSize = AFI->getCalleeSavedStackSize() + FixedObject; // All of the remaining stack allocations are for locals. @@ -993,32 +1008,8 @@ void AArch64FrameLowering::emitPrologue(MachineFunctio ++MBBI; } - // The code below is not applicable to funclets. We have emitted all the SEH - // opcodes that we needed to emit. The FP and BP belong to the containing - // function. - if (IsFunclet) { - if (NeedsWinCFI) { - HasWinCFI = true; - BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_PrologEnd)) - .setMIFlag(MachineInstr::FrameSetup); - } - - // SEH funclets are passed the frame pointer in X1. If the parent - // function uses the base register, then the base register is used - // directly, and is not retrieved from X1. - if (F.hasPersonalityFn()) { - EHPersonality Per = classifyEHPersonality(F.getPersonalityFn()); - if (isAsynchronousEHPersonality(Per)) { - BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::COPY), AArch64::FP) - .addReg(AArch64::X1).setMIFlag(MachineInstr::FrameSetup); - MBB.addLiveIn(AArch64::X1); - } - } - - return; - } - - if (HasFP) { + // For funclets the FP belongs to the containing function. + if (!IsFunclet && HasFP) { // Only set up FP if we actually need to. int64_t FPOffset = isTargetDarwin(MF) ? (AFI->getCalleeSavedStackSize() - 16) : 0; @@ -1161,7 +1152,9 @@ void AArch64FrameLowering::emitPrologue(MachineFunctio // Allocate space for the rest of the frame. if (NumBytes) { - const bool NeedsRealignment = RegInfo->needsStackRealignment(MF); + // Alignment is required for the parent frame, not the funclet + const bool NeedsRealignment = + !IsFunclet && RegInfo->needsStackRealignment(MF); unsigned scratchSPReg = AArch64::SP; if (NeedsRealignment) { @@ -1215,7 +1208,8 @@ void AArch64FrameLowering::emitPrologue(MachineFunctio // FIXME: Clarify FrameSetup flags here. // Note: Use emitFrameOffset() like above for FP if the FrameSetup flag is // needed. - if (RegInfo->hasBasePointer(MF)) { + // For funclets the BP belongs to the containing function. + if (!IsFunclet && RegInfo->hasBasePointer(MF)) { TII->copyPhysReg(MBB, MBBI, DL, RegInfo->getBaseRegister(), AArch64::SP, false); if (NeedsWinCFI) { @@ -1232,6 +1226,19 @@ void AArch64FrameLowering::emitPrologue(MachineFunctio .setMIFlag(MachineInstr::FrameSetup); } + // SEH funclets are passed the frame pointer in X1. If the parent + // function uses the base register, then the base register is used + // directly, and is not retrieved from X1. + if (IsFunclet && F.hasPersonalityFn()) { + EHPersonality Per = classifyEHPersonality(F.getPersonalityFn()); + if (isAsynchronousEHPersonality(Per)) { + BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::COPY), AArch64::FP) + .addReg(AArch64::X1) + .setMIFlag(MachineInstr::FrameSetup); + MBB.addLiveIn(AArch64::X1); + } + } + if (needsFrameMoves) { const DataLayout &TD = MF.getDataLayout(); const int StackGrowth = isTargetDarwin(MF) @@ -1450,10 +1457,7 @@ void AArch64FrameLowering::emitEpilogue(MachineFunctio bool IsWin64 = Subtarget.isCallingConvWin64(MF.getFunction().getCallingConv()); - // Var args are accounted for in the containing function, so don't - // include them for funclets. - unsigned FixedObject = - (IsWin64 && !IsFunclet) ? alignTo(AFI->getVarArgsGPRSize(), 16) : 0; + unsigned FixedObject = getFixedObjectSize(MF, AFI, IsWin64, IsFunclet); uint64_t AfterCSRPopSize = ArgumentPopSize; auto PrologueSaveSize = AFI->getCalleeSavedStackSize() + FixedObject; @@ -1679,7 +1683,9 @@ static StackOffset getFPOffset(const MachineFunction & const auto &Subtarget = MF.getSubtarget<AArch64Subtarget>(); bool IsWin64 = Subtarget.isCallingConvWin64(MF.getFunction().getCallingConv()); - unsigned FixedObject = IsWin64 ? alignTo(AFI->getVarArgsGPRSize(), 16) : 0; + + unsigned FixedObject = + getFixedObjectSize(MF, AFI, IsWin64, /*IsFunclet=*/false); unsigned FPAdjust = isTargetDarwin(MF) ? 16 : AFI->getCalleeSavedStackSize(MF.getFrameInfo()); return {ObjectOffset + FixedObject + FPAdjust, MVT::i8}; @@ -2632,9 +2638,14 @@ void AArch64FrameLowering::processFunctionBeforeFrameF ++MBBI; // Create an UnwindHelp object. - int UnwindHelpFI = - MFI.CreateStackObject(/*size*/8, /*alignment*/16, false); + // The UnwindHelp object is allocated at the start of the fixed object area + int64_t FixedObject = + getFixedObjectSize(MF, AFI, /*IsWin64*/ true, /*IsFunclet*/ false); + int UnwindHelpFI = MFI.CreateFixedObject(/*Size*/ 8, + /*SPOffset*/ -FixedObject, + /*IsImmutable=*/false); EHInfo.UnwindHelpFrameIdx = UnwindHelpFI; + // We need to store -2 into the UnwindHelp object at the start of the // function. DebugLoc DL; @@ -2656,10 +2667,14 @@ int AArch64FrameLowering::getFrameIndexReferencePrefer const MachineFunction &MF, int FI, unsigned &FrameReg, bool IgnoreSPUpdates) const { const MachineFrameInfo &MFI = MF.getFrameInfo(); - LLVM_DEBUG(dbgs() << "Offset from the SP for " << FI << " is " - << MFI.getObjectOffset(FI) << "\n"); - FrameReg = AArch64::SP; - return MFI.getObjectOffset(FI); + if (IgnoreSPUpdates) { + LLVM_DEBUG(dbgs() << "Offset from the SP for " << FI << " is " + << MFI.getObjectOffset(FI) << "\n"); + FrameReg = AArch64::SP; + return MFI.getObjectOffset(FI); + } + + return getFrameIndexReference(MF, FI, FrameReg); } /// The parent frame offset (aka dispFrame) is only used on X86_64 to retrieve Modified: vendor/llvm-project/release-10.x/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp ============================================================================== --- vendor/llvm-project/release-10.x/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp Sat Jun 27 17:39:13 2020 (r362702) +++ vendor/llvm-project/release-10.x/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp Sat Jun 27 18:34:17 2020 (r362703) @@ -298,6 +298,11 @@ bool PPCAsmPrinter::PrintAsmMemoryOperand(const Machin switch (ExtraCode[0]) { default: return true; // Unknown modifier. + case 'L': // A memory reference to the upper word of a double word op. + O << getDataLayout().getPointerSize() << "("; + printOperand(MI, OpNo, O); + O << ")"; + return false; case 'y': // A memory reference for an X-form instruction { const char *RegName = "r0"; @@ -309,7 +314,6 @@ bool PPCAsmPrinter::PrintAsmMemoryOperand(const Machin } case 'U': // Print 'u' for update form. case 'X': // Print 'x' for indexed form. - { // FIXME: Currently for PowerPC memory operands are always loaded // into a register, so we never get an update or indexed form. // This is bad even for offset forms, since even if we know we @@ -318,7 +322,6 @@ bool PPCAsmPrinter::PrintAsmMemoryOperand(const Machin // tolerate 'U' and 'X' but don't output anything. assert(MI->getOperand(OpNo).isReg()); return false; - } } } Modified: vendor/llvm-project/release-10.x/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp ============================================================================== --- vendor/llvm-project/release-10.x/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp Sat Jun 27 17:39:13 2020 (r362702) +++ vendor/llvm-project/release-10.x/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp Sat Jun 27 18:34:17 2020 (r362703) @@ -181,9 +181,9 @@ void RISCVFrameLowering::emitPrologue(MachineFunction adjustReg(MBB, MBBI, DL, FPReg, SPReg, StackSize - RVFI->getVarArgsSaveSize(), MachineInstr::FrameSetup); - // Emit ".cfi_def_cfa $fp, 0" + // Emit ".cfi_def_cfa $fp, -RVFI->getVarArgsSaveSize()" unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createDefCfa( - nullptr, RI->getDwarfRegNum(FPReg, true), 0)); + nullptr, RI->getDwarfRegNum(FPReg, true), -RVFI->getVarArgsSaveSize())); BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION)) .addCFIIndex(CFIIndex); } Modified: vendor/llvm-project/release-10.x/llvm/lib/Target/RISCV/RISCVISelLowering.cpp ============================================================================== --- vendor/llvm-project/release-10.x/llvm/lib/Target/RISCV/RISCVISelLowering.cpp Sat Jun 27 17:39:13 2020 (r362702) +++ vendor/llvm-project/release-10.x/llvm/lib/Target/RISCV/RISCVISelLowering.cpp Sat Jun 27 18:34:17 2020 (r362703) @@ -197,6 +197,14 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetM setTruncStoreAction(MVT::f64, MVT::f16, Expand); } + if (Subtarget.is64Bit() && + !(Subtarget.hasStdExtD() || Subtarget.hasStdExtF())) { + setOperationAction(ISD::FP_TO_UINT, MVT::i32, Custom); + setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom); + setOperationAction(ISD::STRICT_FP_TO_UINT, MVT::i32, Custom); + setOperationAction(ISD::STRICT_FP_TO_SINT, MVT::i32, Custom); + } + setOperationAction(ISD::GlobalAddress, XLenVT, Custom); setOperationAction(ISD::BlockAddress, XLenVT, Custom); setOperationAction(ISD::ConstantPool, XLenVT, Custom); @@ -876,6 +884,32 @@ void RISCVTargetLowering::ReplaceNodeResults(SDNode *N switch (N->getOpcode()) { default: llvm_unreachable("Don't know how to custom type legalize this operation!"); + case ISD::STRICT_FP_TO_SINT: + case ISD::STRICT_FP_TO_UINT: + case ISD::FP_TO_SINT: + case ISD::FP_TO_UINT: { + bool IsStrict = N->isStrictFPOpcode(); + assert(N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() && + "Unexpected custom legalisation"); + SDValue Op0 = IsStrict ? N->getOperand(1) : N->getOperand(0); + RTLIB::Libcall LC; + if (N->getOpcode() == ISD::FP_TO_SINT || + N->getOpcode() == ISD::STRICT_FP_TO_SINT) + LC = RTLIB::getFPTOSINT(Op0.getValueType(), N->getValueType(0)); + else + LC = RTLIB::getFPTOUINT(Op0.getValueType(), N->getValueType(0)); + MakeLibCallOptions CallOptions; + EVT OpVT = Op0.getValueType(); + CallOptions.setTypeListBeforeSoften(OpVT, N->getValueType(0), true); + SDValue Chain = IsStrict ? N->getOperand(0) : SDValue(); + SDValue Result; + std::tie(Result, Chain) = + makeLibCall(DAG, LC, N->getValueType(0), Op0, CallOptions, DL, Chain); + Results.push_back(Result); + if (IsStrict) + Results.push_back(Chain); + break; + } case ISD::READCYCLECOUNTER: { assert(!Subtarget.is64Bit() && "READCYCLECOUNTER only has custom type legalization on riscv32"); Added: vendor/llvm-project/release-10.x/llvm/tools/llvm-dwp/DWPError.cpp ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ vendor/llvm-project/release-10.x/llvm/tools/llvm-dwp/DWPError.cpp Sat Jun 27 18:34:17 2020 (r362703) @@ -0,0 +1,3 @@ +#include "DWPError.h" +using namespace llvm; +char DWPError::ID; Added: vendor/llvm-project/release-10.x/llvm/tools/llvm-dwp/DWPError.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ vendor/llvm-project/release-10.x/llvm/tools/llvm-dwp/DWPError.h Sat Jun 27 18:34:17 2020 (r362703) @@ -0,0 +1,23 @@ +#ifndef TOOLS_LLVM_DWP_DWPERROR +#define TOOLS_LLVM_DWP_DWPERROR + +#include "llvm/Support/Error.h" +#include "llvm/Support/ErrorHandling.h" +#include <string> + +namespace llvm { +class DWPError : public ErrorInfo<DWPError> { +public: + DWPError(std::string Info) : Info(std::move(Info)) {} + void log(raw_ostream &OS) const override { OS << Info; } + std::error_code convertToErrorCode() const override { + llvm_unreachable("Not implemented"); + } + static char ID; + +private: + std::string Info; +}; +} + +#endif Added: vendor/llvm-project/release-10.x/llvm/tools/llvm-dwp/DWPStringPool.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ vendor/llvm-project/release-10.x/llvm/tools/llvm-dwp/DWPStringPool.h Sat Jun 27 18:34:17 2020 (r362703) @@ -0,0 +1,56 @@ +#ifndef TOOLS_LLVM_DWP_DWPSTRINGPOOL +#define TOOLS_LLVM_DWP_DWPSTRINGPOOL + +#include "llvm/ADT/DenseMap.h" +#include "llvm/MC/MCSection.h" +#include "llvm/MC/MCStreamer.h" +#include <cassert> + +namespace llvm { +class DWPStringPool { + + struct CStrDenseMapInfo { + static inline const char *getEmptyKey() { + return reinterpret_cast<const char *>(~static_cast<uintptr_t>(0)); + } + static inline const char *getTombstoneKey() { + return reinterpret_cast<const char *>(~static_cast<uintptr_t>(1)); + } + static unsigned getHashValue(const char *Val) { + assert(Val != getEmptyKey() && "Cannot hash the empty key!"); + assert(Val != getTombstoneKey() && "Cannot hash the tombstone key!"); + return (unsigned)hash_value(StringRef(Val)); + } + static bool isEqual(const char *LHS, const char *RHS) { + if (RHS == getEmptyKey()) + return LHS == getEmptyKey(); + if (RHS == getTombstoneKey()) + return LHS == getTombstoneKey(); + return strcmp(LHS, RHS) == 0; + } + }; + + MCStreamer &Out; + MCSection *Sec; + DenseMap<const char *, uint32_t, CStrDenseMapInfo> Pool; + uint32_t Offset = 0; + +public: + DWPStringPool(MCStreamer &Out, MCSection *Sec) : Out(Out), Sec(Sec) {} + + uint32_t getOffset(const char *Str, unsigned Length) { + assert(strlen(Str) + 1 == Length && "Ensure length hint is correct"); + + auto Pair = Pool.insert(std::make_pair(Str, Offset)); + if (Pair.second) { + Out.SwitchSection(Sec); + Out.EmitBytes(StringRef(Str, Length)); + Offset += Length; + } + + return Pair.first->second; + } +}; +} + +#endif Added: vendor/llvm-project/release-10.x/llvm/tools/llvm-dwp/llvm-dwp.cpp ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ vendor/llvm-project/release-10.x/llvm/tools/llvm-dwp/llvm-dwp.cpp Sat Jun 27 18:34:17 2020 (r362703) @@ -0,0 +1,749 @@ +//===-- llvm-dwp.cpp - Split DWARF merging tool for llvm ------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// A utility for merging DWARF 5 Split DWARF .dwo files into .dwp (DWARF +// package files). +// +//===----------------------------------------------------------------------===// +#include "DWPError.h" +#include "DWPStringPool.h" +#include "llvm/ADT/MapVector.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/DebugInfo/DWARF/DWARFContext.h" +#include "llvm/DebugInfo/DWARF/DWARFFormValue.h" +#include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h" +#include "llvm/MC/MCAsmBackend.h" +#include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCCodeEmitter.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCInstrInfo.h" +#include "llvm/MC/MCObjectFileInfo.h" +#include "llvm/MC/MCObjectWriter.h" +#include "llvm/MC/MCRegisterInfo.h" +#include "llvm/MC/MCStreamer.h" +#include "llvm/MC/MCTargetOptionsCommandFlags.inc" +#include "llvm/Object/Decompressor.h" +#include "llvm/Object/ObjectFile.h" +#include "llvm/Support/DataExtractor.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/InitLLVM.h" +#include "llvm/Support/MathExtras.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/Path.h" +#include "llvm/Support/TargetRegistry.h" +#include "llvm/Support/TargetSelect.h" +#include "llvm/Support/ToolOutputFile.h" +#include "llvm/Support/WithColor.h" +#include "llvm/Support/raw_ostream.h" + +using namespace llvm; +using namespace llvm::object; + +cl::OptionCategory DwpCategory("Specific Options"); +static cl::list<std::string> InputFiles(cl::Positional, cl::ZeroOrMore, + cl::desc("<input files>"), + cl::cat(DwpCategory)); + +static cl::list<std::string> ExecFilenames( + "e", cl::ZeroOrMore, + cl::desc("Specify the executable/library files to get the list of *.dwo from"), + cl::value_desc("filename"), cl::cat(DwpCategory)); + +static cl::opt<std::string> OutputFilename(cl::Required, "o", + cl::desc("Specify the output file."), + cl::value_desc("filename"), + cl::cat(DwpCategory)); + +static void writeStringsAndOffsets(MCStreamer &Out, DWPStringPool &Strings, + MCSection *StrOffsetSection, + StringRef CurStrSection, + StringRef CurStrOffsetSection) { + // Could possibly produce an error or warning if one of these was non-null but + // the other was null. + if (CurStrSection.empty() || CurStrOffsetSection.empty()) + return; + + DenseMap<uint64_t, uint32_t> OffsetRemapping; + + DataExtractor Data(CurStrSection, true, 0); + uint64_t LocalOffset = 0; + uint64_t PrevOffset = 0; + while (const char *s = Data.getCStr(&LocalOffset)) { + OffsetRemapping[PrevOffset] = + Strings.getOffset(s, LocalOffset - PrevOffset); + PrevOffset = LocalOffset; + } + + Data = DataExtractor(CurStrOffsetSection, true, 0); + + Out.SwitchSection(StrOffsetSection); + + uint64_t Offset = 0; + uint64_t Size = CurStrOffsetSection.size(); + while (Offset < Size) { + auto OldOffset = Data.getU32(&Offset); + auto NewOffset = OffsetRemapping[OldOffset]; + Out.EmitIntValue(NewOffset, 4); + } +} + +static uint64_t getCUAbbrev(StringRef Abbrev, uint64_t AbbrCode) { + uint64_t CurCode; + uint64_t Offset = 0; + DataExtractor AbbrevData(Abbrev, true, 0); + while ((CurCode = AbbrevData.getULEB128(&Offset)) != AbbrCode) { + // Tag + AbbrevData.getULEB128(&Offset); + // DW_CHILDREN + AbbrevData.getU8(&Offset); + // Attributes + while (AbbrevData.getULEB128(&Offset) | AbbrevData.getULEB128(&Offset)) + ; + } + return Offset; +} + +struct CompileUnitIdentifiers { + uint64_t Signature = 0; + const char *Name = ""; + const char *DWOName = ""; +}; + +static Expected<const char *> +getIndexedString(dwarf::Form Form, DataExtractor InfoData, + uint64_t &InfoOffset, StringRef StrOffsets, StringRef Str) { + if (Form == dwarf::DW_FORM_string) + return InfoData.getCStr(&InfoOffset); + if (Form != dwarf::DW_FORM_GNU_str_index) + return make_error<DWPError>( + "string field encoded without DW_FORM_string or DW_FORM_GNU_str_index"); + auto StrIndex = InfoData.getULEB128(&InfoOffset); + DataExtractor StrOffsetsData(StrOffsets, true, 0); + uint64_t StrOffsetsOffset = 4 * StrIndex; + uint64_t StrOffset = StrOffsetsData.getU32(&StrOffsetsOffset); + DataExtractor StrData(Str, true, 0); + return StrData.getCStr(&StrOffset); +} + +static Expected<CompileUnitIdentifiers> getCUIdentifiers(StringRef Abbrev, + StringRef Info, + StringRef StrOffsets, + StringRef Str) { + uint64_t Offset = 0; + DataExtractor InfoData(Info, true, 0); + dwarf::DwarfFormat Format = dwarf::DwarfFormat::DWARF32; + uint64_t Length = InfoData.getU32(&Offset); + // If the length is 0xffffffff, then this indictes that this is a DWARF 64 + // stream and the length is actually encoded into a 64 bit value that follows. + if (Length == 0xffffffffU) { + Format = dwarf::DwarfFormat::DWARF64; + Length = InfoData.getU64(&Offset); + } + uint16_t Version = InfoData.getU16(&Offset); + InfoData.getU32(&Offset); // Abbrev offset (should be zero) + uint8_t AddrSize = InfoData.getU8(&Offset); + + uint32_t AbbrCode = InfoData.getULEB128(&Offset); + + DataExtractor AbbrevData(Abbrev, true, 0); + uint64_t AbbrevOffset = getCUAbbrev(Abbrev, AbbrCode); + auto Tag = static_cast<dwarf::Tag>(AbbrevData.getULEB128(&AbbrevOffset)); + if (Tag != dwarf::DW_TAG_compile_unit) + return make_error<DWPError>("top level DIE is not a compile unit"); + // DW_CHILDREN + AbbrevData.getU8(&AbbrevOffset); + uint32_t Name; + dwarf::Form Form; + CompileUnitIdentifiers ID; + Optional<uint64_t> Signature = None; + while ((Name = AbbrevData.getULEB128(&AbbrevOffset)) | + (Form = static_cast<dwarf::Form>(AbbrevData.getULEB128(&AbbrevOffset))) && + (Name != 0 || Form != 0)) { + switch (Name) { + case dwarf::DW_AT_name: { + Expected<const char *> EName = + getIndexedString(Form, InfoData, Offset, StrOffsets, Str); + if (!EName) + return EName.takeError(); + ID.Name = *EName; + break; + } + case dwarf::DW_AT_GNU_dwo_name: { + Expected<const char *> EName = + getIndexedString(Form, InfoData, Offset, StrOffsets, Str); + if (!EName) + return EName.takeError(); + ID.DWOName = *EName; + break; + } + case dwarf::DW_AT_GNU_dwo_id: + Signature = InfoData.getU64(&Offset); + break; + default: + DWARFFormValue::skipValue(Form, InfoData, &Offset, + dwarf::FormParams({Version, AddrSize, Format})); + } + } + if (!Signature) + return make_error<DWPError>("compile unit missing dwo_id"); + ID.Signature = *Signature; + return ID; +} + +struct UnitIndexEntry { + DWARFUnitIndex::Entry::SectionContribution Contributions[8]; + std::string Name; + std::string DWOName; + StringRef DWPName; +}; + +static StringRef getSubsection(StringRef Section, + const DWARFUnitIndex::Entry &Entry, + DWARFSectionKind Kind) { + const auto *Off = Entry.getOffset(Kind); + if (!Off) + return StringRef(); + return Section.substr(Off->Offset, Off->Length); +} + +static void addAllTypesFromDWP( + MCStreamer &Out, MapVector<uint64_t, UnitIndexEntry> &TypeIndexEntries, + const DWARFUnitIndex &TUIndex, MCSection *OutputTypes, StringRef Types, + const UnitIndexEntry &TUEntry, uint32_t &TypesOffset) { + Out.SwitchSection(OutputTypes); + for (const DWARFUnitIndex::Entry &E : TUIndex.getRows()) { + auto *I = E.getOffsets(); + if (!I) + continue; + auto P = TypeIndexEntries.insert(std::make_pair(E.getSignature(), TUEntry)); + if (!P.second) + continue; + auto &Entry = P.first->second; + // Zero out the debug_info contribution + Entry.Contributions[0] = {}; + for (auto Kind : TUIndex.getColumnKinds()) { + auto &C = Entry.Contributions[Kind - DW_SECT_INFO]; + C.Offset += I->Offset; + C.Length = I->Length; + ++I; + } + auto &C = Entry.Contributions[DW_SECT_TYPES - DW_SECT_INFO]; + Out.EmitBytes(Types.substr( + C.Offset - TUEntry.Contributions[DW_SECT_TYPES - DW_SECT_INFO].Offset, + C.Length)); + C.Offset = TypesOffset; + TypesOffset += C.Length; + } +} + +static void addAllTypes(MCStreamer &Out, + MapVector<uint64_t, UnitIndexEntry> &TypeIndexEntries, + MCSection *OutputTypes, + const std::vector<StringRef> &TypesSections, + const UnitIndexEntry &CUEntry, uint32_t &TypesOffset) { + for (StringRef Types : TypesSections) { + Out.SwitchSection(OutputTypes); + uint64_t Offset = 0; + DataExtractor Data(Types, true, 0); + while (Data.isValidOffset(Offset)) { + UnitIndexEntry Entry = CUEntry; + // Zero out the debug_info contribution + Entry.Contributions[0] = {}; + auto &C = Entry.Contributions[DW_SECT_TYPES - DW_SECT_INFO]; + C.Offset = TypesOffset; + auto PrevOffset = Offset; + // Length of the unit, including the 4 byte length field. + C.Length = Data.getU32(&Offset) + 4; + + Data.getU16(&Offset); // Version + Data.getU32(&Offset); // Abbrev offset + Data.getU8(&Offset); // Address size + auto Signature = Data.getU64(&Offset); + Offset = PrevOffset + C.Length; + + auto P = TypeIndexEntries.insert(std::make_pair(Signature, Entry)); + if (!P.second) + continue; + + Out.EmitBytes(Types.substr(PrevOffset, C.Length)); + TypesOffset += C.Length; + } + } +} + +static void +writeIndexTable(MCStreamer &Out, ArrayRef<unsigned> ContributionOffsets, + const MapVector<uint64_t, UnitIndexEntry> &IndexEntries, + uint32_t DWARFUnitIndex::Entry::SectionContribution::*Field) { + for (const auto &E : IndexEntries) + for (size_t i = 0; i != array_lengthof(E.second.Contributions); ++i) + if (ContributionOffsets[i]) + Out.EmitIntValue(E.second.Contributions[i].*Field, 4); +} + +static void +writeIndex(MCStreamer &Out, MCSection *Section, + ArrayRef<unsigned> ContributionOffsets, + const MapVector<uint64_t, UnitIndexEntry> &IndexEntries) { + if (IndexEntries.empty()) + return; + + unsigned Columns = 0; + for (auto &C : ContributionOffsets) + if (C) + ++Columns; + + std::vector<unsigned> Buckets(NextPowerOf2(3 * IndexEntries.size() / 2)); + uint64_t Mask = Buckets.size() - 1; + size_t i = 0; + for (const auto &P : IndexEntries) { + auto S = P.first; + auto H = S & Mask; + auto HP = ((S >> 32) & Mask) | 1; + while (Buckets[H]) { + assert(S != IndexEntries.begin()[Buckets[H] - 1].first && + "Duplicate unit"); + H = (H + HP) & Mask; + } + Buckets[H] = i + 1; + ++i; + } + + Out.SwitchSection(Section); + Out.EmitIntValue(2, 4); // Version + Out.EmitIntValue(Columns, 4); // Columns + Out.EmitIntValue(IndexEntries.size(), 4); // Num Units + Out.EmitIntValue(Buckets.size(), 4); // Num Buckets + + // Write the signatures. + for (const auto &I : Buckets) + Out.EmitIntValue(I ? IndexEntries.begin()[I - 1].first : 0, 8); + + // Write the indexes. + for (const auto &I : Buckets) + Out.EmitIntValue(I, 4); + + // Write the column headers (which sections will appear in the table) + for (size_t i = 0; i != ContributionOffsets.size(); ++i) + if (ContributionOffsets[i]) + Out.EmitIntValue(i + DW_SECT_INFO, 4); + + // Write the offsets. + writeIndexTable(Out, ContributionOffsets, IndexEntries, + &DWARFUnitIndex::Entry::SectionContribution::Offset); + + // Write the lengths. + writeIndexTable(Out, ContributionOffsets, IndexEntries, + &DWARFUnitIndex::Entry::SectionContribution::Length); +} + +std::string buildDWODescription(StringRef Name, StringRef DWPName, StringRef DWOName) { + std::string Text = "\'"; + Text += Name; + Text += '\''; + if (!DWPName.empty()) { + Text += " (from "; + if (!DWOName.empty()) { + Text += '\''; + Text += DWOName; + Text += "' in "; + } + Text += '\''; + Text += DWPName; + Text += "')"; + } + return Text; +} + +static Error createError(StringRef Name, Error E) { + return make_error<DWPError>( + ("failure while decompressing compressed section: '" + Name + "', " + + llvm::toString(std::move(E))) + .str()); +} + +static Error +handleCompressedSection(std::deque<SmallString<32>> &UncompressedSections, + StringRef &Name, StringRef &Contents) { + if (!Decompressor::isGnuStyle(Name)) + return Error::success(); + + Expected<Decompressor> Dec = + Decompressor::create(Name, Contents, false /*IsLE*/, false /*Is64Bit*/); + if (!Dec) + return createError(Name, Dec.takeError()); + + UncompressedSections.emplace_back(); + if (Error E = Dec->resizeAndDecompress(UncompressedSections.back())) + return createError(Name, std::move(E)); + + Name = Name.substr(2); // Drop ".z" + Contents = UncompressedSections.back(); + return Error::success(); +} + +static Error handleSection( + const StringMap<std::pair<MCSection *, DWARFSectionKind>> &KnownSections, + const MCSection *StrSection, const MCSection *StrOffsetSection, + const MCSection *TypesSection, const MCSection *CUIndexSection, + const MCSection *TUIndexSection, const SectionRef &Section, MCStreamer &Out, + std::deque<SmallString<32>> &UncompressedSections, + uint32_t (&ContributionOffsets)[8], UnitIndexEntry &CurEntry, + StringRef &CurStrSection, StringRef &CurStrOffsetSection, + std::vector<StringRef> &CurTypesSection, StringRef &InfoSection, + StringRef &AbbrevSection, StringRef &CurCUIndexSection, + StringRef &CurTUIndexSection) { + if (Section.isBSS()) + return Error::success(); + + if (Section.isVirtual()) + return Error::success(); + + Expected<StringRef> NameOrErr = Section.getName(); + if (!NameOrErr) + return NameOrErr.takeError(); + StringRef Name = *NameOrErr; + + Expected<StringRef> ContentsOrErr = Section.getContents(); + if (!ContentsOrErr) + return ContentsOrErr.takeError(); + StringRef Contents = *ContentsOrErr; + + if (auto Err = handleCompressedSection(UncompressedSections, Name, Contents)) + return Err; + + Name = Name.substr(Name.find_first_not_of("._")); + + auto SectionPair = KnownSections.find(Name); + if (SectionPair == KnownSections.end()) + return Error::success(); + + if (DWARFSectionKind Kind = SectionPair->second.second) { + auto Index = Kind - DW_SECT_INFO; + if (Kind != DW_SECT_TYPES) { + CurEntry.Contributions[Index].Offset = ContributionOffsets[Index]; + ContributionOffsets[Index] += + (CurEntry.Contributions[Index].Length = Contents.size()); + } + + switch (Kind) { + case DW_SECT_INFO: + InfoSection = Contents; + break; + case DW_SECT_ABBREV: + AbbrevSection = Contents; + break; + default: + break; + } + } + + MCSection *OutSection = SectionPair->second.first; + if (OutSection == StrOffsetSection) + CurStrOffsetSection = Contents; + else if (OutSection == StrSection) + CurStrSection = Contents; + else if (OutSection == TypesSection) + CurTypesSection.push_back(Contents); + else if (OutSection == CUIndexSection) + CurCUIndexSection = Contents; + else if (OutSection == TUIndexSection) + CurTUIndexSection = Contents; + else { + Out.SwitchSection(OutSection); + Out.EmitBytes(Contents); + } + return Error::success(); +} + +static Error *** DIFF OUTPUT TRUNCATED AT 1000 LINES *** _______________________________________________ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"