diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2023-04-08 10:22:46 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2023-04-08 10:22:46 +0000 |
| commit | 8a37c71e9d8855c91b9ef296ed389248f960bb52 (patch) | |
| tree | ba53c9477fd985f645c0cfbacb5e9466f36dde9c /llvm/lib | |
| parent | 5bcd187b307a70f29854eb0c5ccdf30ff3770fe1 (diff) | |
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 7 | ||||
| -rw-r--r-- | llvm/lib/DWARFLinker/DWARFLinker.cpp | 36 | ||||
| -rw-r--r-- | llvm/lib/DWARFLinker/DWARFStreamer.cpp | 5 | ||||
| -rw-r--r-- | llvm/lib/Object/ELFObjectFile.cpp | 7 | ||||
| -rw-r--r-- | llvm/lib/Support/AddressRanges.cpp | 70 | ||||
| -rw-r--r-- | llvm/lib/Support/RISCVISAInfo.cpp | 2 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/ARMFrameLowering.cpp | 28 | ||||
| -rw-r--r-- | llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 3 | ||||
| -rw-r--r-- | llvm/lib/Target/Sparc/MCTargetDesc/SparcInstPrinter.cpp | 2 | ||||
| -rw-r--r-- | llvm/lib/Target/Sparc/SparcInstrInfo.cpp | 121 | ||||
| -rw-r--r-- | llvm/lib/Target/Sparc/SparcInstrInfo.h | 9 | ||||
| -rw-r--r-- | llvm/lib/Target/Sparc/SparcInstrInfo.td | 9 | ||||
| -rw-r--r-- | llvm/lib/Target/Sparc/SparcTargetMachine.cpp | 7 | ||||
| -rw-r--r-- | llvm/lib/Transforms/Utils/Local.cpp | 3 |
14 files changed, 250 insertions, 59 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index eed3d820c120..d9cde609e599 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -21361,10 +21361,9 @@ static SDValue reduceBuildVecToShuffleWithZero(SDNode *BV, SelectionDAG &DAG) { // the source vector. The high bits map to zero. We will use a zero vector // as the 2nd source operand of the shuffle, so use the 1st element of // that vector (mask value is number-of-elements) for the high bits. - if (i % ZextRatio == 0) - ShufMask[i] = Extract.getConstantOperandVal(1); - else - ShufMask[i] = NumMaskElts; + int Low = DAG.getDataLayout().isBigEndian() ? (ZextRatio - 1) : 0; + ShufMask[i] = (i % ZextRatio == Low) ? Extract.getConstantOperandVal(1) + : NumMaskElts; } // Undef elements of the build vector remain undef because we initialize diff --git a/llvm/lib/DWARFLinker/DWARFLinker.cpp b/llvm/lib/DWARFLinker/DWARFLinker.cpp index d302d61894fa..9f6e54377ede 100644 --- a/llvm/lib/DWARFLinker/DWARFLinker.cpp +++ b/llvm/lib/DWARFLinker/DWARFLinker.cpp @@ -1659,7 +1659,7 @@ void DWARFLinker::patchRangesForUnit(const CompileUnit &Unit, DWARFDataExtractor RangeExtractor(OrigDwarf.getDWARFObj(), OrigDwarf.getDWARFObj().getRangesSection(), OrigDwarf.isLittleEndian(), AddressSize); - std::optional<AddressRangeValuePair> CachedRange; + std::optional<std::pair<AddressRange, int64_t>> CachedRange; DWARFUnit &OrigUnit = Unit.getOrigUnit(); auto OrigUnitDie = OrigUnit.getUnitDIE(false); uint64_t UnitBaseAddress = @@ -1687,9 +1687,9 @@ void DWARFLinker::patchRangesForUnit(const CompileUnit &Unit, } if (!CachedRange || - !CachedRange->Range.contains(Range.StartAddress + BaseAddress)) - CachedRange = FunctionRanges.getRangeThatContains(Range.StartAddress + - BaseAddress); + !CachedRange->first.contains(Range.StartAddress + BaseAddress)) + CachedRange = FunctionRanges.getRangeValueThatContains( + Range.StartAddress + BaseAddress); // All range entries should lie in the function range. if (!CachedRange) { @@ -1698,8 +1698,8 @@ void DWARFLinker::patchRangesForUnit(const CompileUnit &Unit, } LinkedRanges.insert( - {Range.StartAddress + BaseAddress + CachedRange->Value, - Range.EndAddress + BaseAddress + CachedRange->Value}); + {Range.StartAddress + BaseAddress + CachedRange->second, + Range.EndAddress + BaseAddress + CachedRange->second}); } } @@ -1802,7 +1802,7 @@ void DWARFLinker::patchLineTableForUnit(CompileUnit &Unit, // in NewRows. std::vector<DWARFDebugLine::Row> Seq; const auto &FunctionRanges = Unit.getFunctionRanges(); - std::optional<AddressRangeValuePair> CurrRange; + std::optional<std::pair<AddressRange, int64_t>> CurrRange; // FIXME: This logic is meant to generate exactly the same output as // Darwin's classic dsymutil. There is a nicer way to implement this @@ -1821,13 +1821,13 @@ void DWARFLinker::patchLineTableForUnit(CompileUnit &Unit, // it is marked as end_sequence in the input (because in that // case, the relocation offset is accurate and that entry won't // serve as the start of another function). - if (!CurrRange || !CurrRange->Range.contains(Row.Address.Address) || - (Row.Address.Address == CurrRange->Range.end() && !Row.EndSequence)) { + if (!CurrRange || !CurrRange->first.contains(Row.Address.Address) || + (Row.Address.Address == CurrRange->first.end() && !Row.EndSequence)) { // We just stepped out of a known range. Insert a end_sequence // corresponding to the end of the range. uint64_t StopAddress = - CurrRange ? CurrRange->Range.end() + CurrRange->Value : -1ULL; - CurrRange = FunctionRanges.getRangeThatContains(Row.Address.Address); + CurrRange ? CurrRange->first.end() + CurrRange->second : -1ULL; + CurrRange = FunctionRanges.getRangeValueThatContains(Row.Address.Address); if (!CurrRange) { if (StopAddress != -1ULL) { // Try harder by looking in the Address ranges map. @@ -1836,9 +1836,9 @@ void DWARFLinker::patchLineTableForUnit(CompileUnit &Unit, // for now do as dsymutil. // FIXME: Understand exactly what cases this addresses and // potentially remove it along with the Ranges map. - if (std::optional<AddressRangeValuePair> Range = - Ranges.getRangeThatContains(Row.Address.Address)) - StopAddress = Row.Address.Address + (*Range).Value; + if (std::optional<std::pair<AddressRange, int64_t>> Range = + Ranges.getRangeValueThatContains(Row.Address.Address)) + StopAddress = Row.Address.Address + (*Range).second; } } if (StopAddress != -1ULL && !Seq.empty()) { @@ -1863,7 +1863,7 @@ void DWARFLinker::patchLineTableForUnit(CompileUnit &Unit, continue; // Relocate row address and add it to the current sequence. - Row.Address.Address += CurrRange->Value; + Row.Address.Address += CurrRange->second; Seq.emplace_back(Row); if (Row.EndSequence) @@ -2002,8 +2002,8 @@ void DWARFLinker::patchFrameInfoForObject(const DWARFFile &File, // the function entry point, thus we can't just lookup the address // in the debug map. Use the AddressInfo's range map to see if the FDE // describes something that we can relocate. - std::optional<AddressRangeValuePair> Range = - Ranges.getRangeThatContains(Loc); + std::optional<std::pair<AddressRange, int64_t>> Range = + Ranges.getRangeValueThatContains(Loc); if (!Range) { // The +4 is to account for the size of the InitialLength field itself. InputOffset = EntryOffset + InitialLength + 4; @@ -2032,7 +2032,7 @@ void DWARFLinker::patchFrameInfoForObject(const DWARFFile &File, // fields that will get reconstructed by emitFDE(). unsigned FDERemainingBytes = InitialLength - (4 + AddrSize); TheDwarfEmitter->emitFDE(IteratorInserted.first->getValue(), AddrSize, - Loc + Range->Value, + Loc + Range->second, FrameData.substr(InputOffset, FDERemainingBytes)); InputOffset += FDERemainingBytes; } diff --git a/llvm/lib/DWARFLinker/DWARFStreamer.cpp b/llvm/lib/DWARFLinker/DWARFStreamer.cpp index ae79e8cb9066..5cad267fd845 100644 --- a/llvm/lib/DWARFLinker/DWARFStreamer.cpp +++ b/llvm/lib/DWARFLinker/DWARFStreamer.cpp @@ -402,9 +402,10 @@ void DwarfStreamer::emitUnitRangesEntries(CompileUnit &Unit, // Linked addresses might end up in a different order. // Build linked address ranges. AddressRanges LinkedRanges; - for (const AddressRangeValuePair &Range : FunctionRanges) + for (size_t Idx = 0; Idx < FunctionRanges.size(); Idx++) LinkedRanges.insert( - {Range.Range.start() + Range.Value, Range.Range.end() + Range.Value}); + {FunctionRanges[Idx].first.start() + FunctionRanges[Idx].second, + FunctionRanges[Idx].first.end() + FunctionRanges[Idx].second}); if (!FunctionRanges.empty()) emitDwarfDebugArangesTable(Unit, LinkedRanges); diff --git a/llvm/lib/Object/ELFObjectFile.cpp b/llvm/lib/Object/ELFObjectFile.cpp index ebc57bd04be7..c6d536188391 100644 --- a/llvm/lib/Object/ELFObjectFile.cpp +++ b/llvm/lib/Object/ELFObjectFile.cpp @@ -303,12 +303,7 @@ Expected<SubtargetFeatures> ELFObjectFileBase::getRISCVFeatures() const { std::optional<StringRef> Attr = Attributes.getAttributeString(RISCVAttrs::ARCH); if (Attr) { - // Suppress version checking for experimental extensions to prevent erroring - // when getting any unknown version of experimental extension. - auto ParseResult = RISCVISAInfo::parseArchString( - *Attr, /*EnableExperimentalExtension=*/true, - /*ExperimentalExtensionVersionCheck=*/false, - /*IgnoreUnknown=*/true); + auto ParseResult = RISCVISAInfo::parseNormalizedArchString(*Attr); if (!ParseResult) return ParseResult.takeError(); auto &ISAInfo = *ParseResult; diff --git a/llvm/lib/Support/AddressRanges.cpp b/llvm/lib/Support/AddressRanges.cpp new file mode 100644 index 000000000000..187d5be00dae --- /dev/null +++ b/llvm/lib/Support/AddressRanges.cpp @@ -0,0 +1,70 @@ +//===- AddressRanges.cpp ----------------------------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "llvm/ADT/AddressRanges.h" +#include "llvm/ADT/STLExtras.h" +#include <inttypes.h> + +using namespace llvm; + +AddressRanges::Collection::const_iterator +AddressRanges::insert(AddressRange Range) { + if (Range.size() == 0) + return Ranges.end(); + + auto It = llvm::upper_bound(Ranges, Range); + auto It2 = It; + while (It2 != Ranges.end() && It2->start() <= Range.end()) + ++It2; + if (It != It2) { + Range = {Range.start(), std::max(Range.end(), std::prev(It2)->end())}; + It = Ranges.erase(It, It2); + } + if (It != Ranges.begin() && Range.start() <= std::prev(It)->end()) { + --It; + *It = {It->start(), std::max(It->end(), Range.end())}; + return It; + } + + return Ranges.insert(It, Range); +} + +AddressRanges::Collection::const_iterator +AddressRanges::find(uint64_t Addr) const { + auto It = std::partition_point( + Ranges.begin(), Ranges.end(), + [=](const AddressRange &R) { return R.start() <= Addr; }); + + if (It == Ranges.begin()) + return Ranges.end(); + + --It; + if (Addr >= It->end()) + return Ranges.end(); + + return It; +} + +AddressRanges::Collection::const_iterator +AddressRanges::find(AddressRange Range) const { + if (Range.size() == 0) + return Ranges.end(); + + auto It = std::partition_point( + Ranges.begin(), Ranges.end(), + [=](const AddressRange &R) { return R.start() <= Range.start(); }); + + if (It == Ranges.begin()) + return Ranges.end(); + + --It; + if (Range.end() > It->end()) + return Ranges.end(); + + return It; +} diff --git a/llvm/lib/Support/RISCVISAInfo.cpp b/llvm/lib/Support/RISCVISAInfo.cpp index b14fe1358d1f..7cb1147d4265 100644 --- a/llvm/lib/Support/RISCVISAInfo.cpp +++ b/llvm/lib/Support/RISCVISAInfo.cpp @@ -1060,6 +1060,8 @@ std::vector<std::string> RISCVISAInfo::toFeatureVector() const { std::string ExtName = Ext.first; if (ExtName == "i") // i is not recognized in clang -cc1 continue; + if (!isSupportedExtension(ExtName)) + continue; std::string Feature = isExperimentalExtension(ExtName) ? "+experimental-" + ExtName : "+" + ExtName; diff --git a/llvm/lib/Target/ARM/ARMFrameLowering.cpp b/llvm/lib/Target/ARM/ARMFrameLowering.cpp index 5fa7068c89eb..724705c25e3a 100644 --- a/llvm/lib/Target/ARM/ARMFrameLowering.cpp +++ b/llvm/lib/Target/ARM/ARMFrameLowering.cpp @@ -357,6 +357,34 @@ static MachineBasicBlock::iterator insertSEH(MachineBasicBlock::iterator MBBI, .setMIFlags(Flags); break; + case ARM::t2STR_PRE: + if (MBBI->getOperand(0).getReg() == ARM::SP && + MBBI->getOperand(2).getReg() == ARM::SP && + MBBI->getOperand(3).getImm() == -4) { + unsigned Reg = RegInfo->getSEHRegNum(MBBI->getOperand(1).getReg()); + MIB = BuildMI(MF, DL, TII.get(ARM::SEH_SaveRegs)) + .addImm(1ULL << Reg) + .addImm(/*Wide=*/1) + .setMIFlags(Flags); + } else { + report_fatal_error("No matching SEH Opcode for t2STR_PRE"); + } + break; + + case ARM::t2LDR_POST: + if (MBBI->getOperand(1).getReg() == ARM::SP && + MBBI->getOperand(2).getReg() == ARM::SP && + MBBI->getOperand(3).getImm() == 4) { + unsigned Reg = RegInfo->getSEHRegNum(MBBI->getOperand(0).getReg()); + MIB = BuildMI(MF, DL, TII.get(ARM::SEH_SaveRegs)) + .addImm(1ULL << Reg) + .addImm(/*Wide=*/1) + .setMIFlags(Flags); + } else { + report_fatal_error("No matching SEH Opcode for t2LDR_POST"); + } + break; + case ARM::t2LDMIA_RET: case ARM::t2LDMIA_UPD: case ARM::t2STMDB_UPD: { diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index 6eea169f8919..a1dc6a0cd2c1 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -4540,6 +4540,9 @@ SDValue RISCVTargetLowering::lowerGlobalTLSAddress(SDValue Op, GlobalAddressSDNode *N = cast<GlobalAddressSDNode>(Op); assert(N->getOffset() == 0 && "unexpected offset in global node"); + if (DAG.getTarget().useEmulatedTLS()) + return LowerToTLSEmulatedModel(N, DAG); + TLSModel::Model Model = getTargetMachine().getTLSModel(N->getGlobal()); if (DAG.getMachineFunction().getFunction().getCallingConv() == diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcInstPrinter.cpp b/llvm/lib/Target/Sparc/MCTargetDesc/SparcInstPrinter.cpp index fb22ddd91ba0..14c0e276a11b 100644 --- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcInstPrinter.cpp +++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcInstPrinter.cpp @@ -178,6 +178,8 @@ void SparcInstPrinter::printCCOperand(const MCInst *MI, int opNum, default: break; case SP::FBCOND: case SP::FBCONDA: + case SP::FBCOND_V9: + case SP::FBCONDA_V9: case SP::BPFCC: case SP::BPFCCA: case SP::BPFCCNT: diff --git a/llvm/lib/Target/Sparc/SparcInstrInfo.cpp b/llvm/lib/Target/Sparc/SparcInstrInfo.cpp index 63f662c41f93..a3a09a36f1dd 100644 --- a/llvm/lib/Target/Sparc/SparcInstrInfo.cpp +++ b/llvm/lib/Target/Sparc/SparcInstrInfo.cpp @@ -28,6 +28,10 @@ using namespace llvm; #define GET_INSTRINFO_CTOR_DTOR #include "SparcGenInstrInfo.inc" +static cl::opt<unsigned> BPccDisplacementBits( + "sparc-bpcc-offset-bits", cl::Hidden, cl::init(19), + cl::desc("Restrict range of BPcc/FBPfcc instructions (DEBUG)")); + // Pin the vtable to this file. void SparcInstrInfo::anchor() {} @@ -73,11 +77,6 @@ unsigned SparcInstrInfo::isStoreToStackSlot(const MachineInstr &MI, return 0; } -static bool IsIntegerCC(unsigned CC) -{ - return (CC <= SPCC::ICC_VC); -} - static SPCC::CondCodes GetOppositeBranchCondition(SPCC::CondCodes CC) { switch(CC) { @@ -155,9 +154,7 @@ static SPCC::CondCodes GetOppositeBranchCondition(SPCC::CondCodes CC) llvm_unreachable("Invalid cond code"); } -static bool isUncondBranchOpcode(int Opc) { - return Opc == SP::BA || Opc == SP::BPA; -} +static bool isUncondBranchOpcode(int Opc) { return Opc == SP::BA; } static bool isI32CondBranchOpcode(int Opc) { return Opc == SP::BCOND || Opc == SP::BPICC || Opc == SP::BPICCA || @@ -169,7 +166,10 @@ static bool isI64CondBranchOpcode(int Opc) { Opc == SP::BPXCCANT; } -static bool isFCondBranchOpcode(int Opc) { return Opc == SP::FBCOND; } +static bool isFCondBranchOpcode(int Opc) { + return Opc == SP::FBCOND || Opc == SP::FBCONDA || Opc == SP::FBCOND_V9 || + Opc == SP::FBCONDA_V9; +} static bool isCondBranchOpcode(int Opc) { return isI32CondBranchOpcode(Opc) || isI64CondBranchOpcode(Opc) || @@ -193,6 +193,34 @@ static void parseCondBranch(MachineInstr *LastInst, MachineBasicBlock *&Target, Target = LastInst->getOperand(0).getMBB(); } +MachineBasicBlock * +SparcInstrInfo::getBranchDestBlock(const MachineInstr &MI) const { + switch (MI.getOpcode()) { + default: + llvm_unreachable("unexpected opcode!"); + case SP::BA: + case SP::BCOND: + case SP::BCONDA: + case SP::FBCOND: + case SP::FBCONDA: + case SP::BPICC: + case SP::BPICCA: + case SP::BPICCNT: + case SP::BPICCANT: + case SP::BPXCC: + case SP::BPXCCA: + case SP::BPXCCNT: + case SP::BPXCCANT: + case SP::BPFCC: + case SP::BPFCCA: + case SP::BPFCCNT: + case SP::BPFCCANT: + case SP::FBCOND_V9: + case SP::FBCONDA_V9: + return MI.getOperand(0).getMBB(); + } +} + bool SparcInstrInfo::analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, @@ -285,36 +313,37 @@ unsigned SparcInstrInfo::insertBranch(MachineBasicBlock &MBB, assert(TBB && "insertBranch must not be told to insert a fallthrough"); assert((Cond.size() <= 2) && "Sparc branch conditions should have at most two components!"); - assert(!BytesAdded && "code size not handled"); if (Cond.empty()) { assert(!FBB && "Unconditional branch with multiple successors!"); - BuildMI(&MBB, DL, get(Subtarget.isV9() ? SP::BPA : SP::BA)).addMBB(TBB); + BuildMI(&MBB, DL, get(SP::BA)).addMBB(TBB); + if (BytesAdded) + *BytesAdded = 8; return 1; } // Conditional branch unsigned Opc = Cond[0].getImm(); unsigned CC = Cond[1].getImm(); + BuildMI(&MBB, DL, get(Opc)).addMBB(TBB).addImm(CC); - if (IsIntegerCC(CC)) { - BuildMI(&MBB, DL, get(Opc)).addMBB(TBB).addImm(CC); - } else { - BuildMI(&MBB, DL, get(SP::FBCOND)).addMBB(TBB).addImm(CC); - } - if (!FBB) + if (!FBB) { + if (BytesAdded) + *BytesAdded = 8; return 1; + } - BuildMI(&MBB, DL, get(Subtarget.isV9() ? SP::BPA : SP::BA)).addMBB(FBB); + BuildMI(&MBB, DL, get(SP::BA)).addMBB(FBB); + if (BytesAdded) + *BytesAdded = 16; return 2; } unsigned SparcInstrInfo::removeBranch(MachineBasicBlock &MBB, int *BytesRemoved) const { - assert(!BytesRemoved && "code size not handled"); - MachineBasicBlock::iterator I = MBB.end(); unsigned Count = 0; + int Removed = 0; while (I != MBB.begin()) { --I; @@ -325,10 +354,14 @@ unsigned SparcInstrInfo::removeBranch(MachineBasicBlock &MBB, !isUncondBranchOpcode(I->getOpcode())) break; // Not a branch + Removed += getInstSizeInBytes(*I); I->eraseFromParent(); I = MBB.end(); ++Count; } + + if (BytesRemoved) + *BytesRemoved = Removed; return Count; } @@ -340,6 +373,37 @@ bool SparcInstrInfo::reverseBranchCondition( return false; } +bool SparcInstrInfo::isBranchOffsetInRange(unsigned BranchOpc, + int64_t Offset) const { + assert((Offset & 0b11) == 0 && "Malformed branch offset"); + switch (BranchOpc) { + case SP::BA: + case SP::BCOND: + case SP::BCONDA: + case SP::FBCOND: + case SP::FBCONDA: + return isIntN(22, Offset >> 2); + + case SP::BPICC: + case SP::BPICCA: + case SP::BPICCNT: + case SP::BPICCANT: + case SP::BPXCC: + case SP::BPXCCA: + case SP::BPXCCNT: + case SP::BPXCCANT: + case SP::BPFCC: + case SP::BPFCCA: + case SP::BPFCCNT: + case SP::BPFCCANT: + case SP::FBCOND_V9: + case SP::FBCONDA_V9: + return isIntN(BPccDisplacementBits, Offset >> 2); + } + + llvm_unreachable("Unknown branch instruction!"); +} + void SparcInstrInfo::copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const DebugLoc &DL, MCRegister DestReg, @@ -530,6 +594,23 @@ Register SparcInstrInfo::getGlobalBaseReg(MachineFunction *MF) const { return GlobalBaseReg; } +unsigned SparcInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const { + unsigned Opcode = MI.getOpcode(); + + if (MI.isInlineAsm()) { + const MachineFunction *MF = MI.getParent()->getParent(); + const char *AsmStr = MI.getOperand(0).getSymbolName(); + return getInlineAsmLength(AsmStr, *MF->getTarget().getMCAsmInfo()); + } + + // If the instruction has a delay slot, be conservative and also include + // it for sizing purposes. This is done so that the BranchRelaxation pass + // will not mistakenly mark out-of-range branches as in-range. + if (MI.hasDelaySlot()) + return get(Opcode).getSize() * 2; + return get(Opcode).getSize(); +} + bool SparcInstrInfo::expandPostRAPseudo(MachineInstr &MI) const { switch (MI.getOpcode()) { case TargetOpcode::LOAD_STACK_GUARD: { diff --git a/llvm/lib/Target/Sparc/SparcInstrInfo.h b/llvm/lib/Target/Sparc/SparcInstrInfo.h index 39cf791c2173..7056d6babe17 100644 --- a/llvm/lib/Target/Sparc/SparcInstrInfo.h +++ b/llvm/lib/Target/Sparc/SparcInstrInfo.h @@ -64,6 +64,8 @@ public: unsigned isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const override; + MachineBasicBlock *getBranchDestBlock(const MachineInstr &MI) const override; + bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl<MachineOperand> &Cond, @@ -80,6 +82,9 @@ public: bool reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const override; + /// Determine if the branch target is in range. + bool isBranchOffsetInRange(unsigned BranchOpc, int64_t Offset) const override; + void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const DebugLoc &DL, MCRegister DestReg, MCRegister SrcReg, bool KillSrc) const override; @@ -99,6 +104,10 @@ public: Register getGlobalBaseReg(MachineFunction *MF) const; + /// GetInstSize - Return the number of bytes of code the specified + /// instruction may be. This returns the maximum number of bytes. + unsigned getInstSizeInBytes(const MachineInstr &MI) const override; + // Lower pseudo instructions after register allocation. bool expandPostRAPseudo(MachineInstr &MI) const override; }; diff --git a/llvm/lib/Target/Sparc/SparcInstrInfo.td b/llvm/lib/Target/Sparc/SparcInstrInfo.td index 2c45a7218d04..2e95bc10337a 100644 --- a/llvm/lib/Target/Sparc/SparcInstrInfo.td +++ b/llvm/lib/Target/Sparc/SparcInstrInfo.td @@ -850,15 +850,8 @@ class BranchPredictAlways<dag ins, string asmstr, list<dag> pattern> : F2_3<0b001, 0, 1, (outs), ins, asmstr, pattern>; } -let cond = 8 in { - // If we're compiling for v9, prefer BPA rather than BA - // TODO: Disallow BA emission when FeatureV8Deprecated isn't enabled - let Predicates = [HasV9], cc = 0b00 in - def BPA : BranchPredictAlways<(ins bprtarget:$imm19), - "ba %icc, $imm19", [(br bb:$imm19)]>; - +let cond = 8 in def BA : BranchAlways<(ins brtarget:$imm22), "ba $imm22", [(br bb:$imm22)]>; -} let isBranch = 1, isTerminator = 1, hasDelaySlot = 1 in { diff --git a/llvm/lib/Target/Sparc/SparcTargetMachine.cpp b/llvm/lib/Target/Sparc/SparcTargetMachine.cpp index 58faaafc29d6..1dbe5c563359 100644 --- a/llvm/lib/Target/Sparc/SparcTargetMachine.cpp +++ b/llvm/lib/Target/Sparc/SparcTargetMachine.cpp @@ -32,6 +32,10 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSparcTarget() { initializeSparcDAGToDAGISelPass(PR); } +static cl::opt<bool> + BranchRelaxation("sparc-enable-branch-relax", cl::Hidden, cl::init(true), + cl::desc("Relax out of range conditional branches")); + static std::string computeDataLayout(const Triple &T, bool is64Bit) { // Sparc is typically big endian, but some are little. std::string Ret = T.getArch() == Triple::sparcel ? "e" : "E"; @@ -182,6 +186,9 @@ bool SparcPassConfig::addInstSelector() { } void SparcPassConfig::addPreEmitPass(){ + if (BranchRelaxation) + addPass(&BranchRelaxationPassID); + addPass(createSparcDelaySlotFillerPass()); if (this->getSparcTargetMachine().getSubtargetImpl()->insertNOPLoad()) diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp index 31cdd2ee56b9..b2ed95b05e04 100644 --- a/llvm/lib/Transforms/Utils/Local.cpp +++ b/llvm/lib/Transforms/Utils/Local.cpp @@ -2930,7 +2930,8 @@ void llvm::copyRangeMetadata(const DataLayout &DL, const LoadInst &OldLI, return; unsigned BitWidth = DL.getPointerTypeSizeInBits(NewTy); - if (!getConstantRangeFromMetadata(*N).contains(APInt(BitWidth, 0))) { + if (BitWidth == OldLI.getType()->getScalarSizeInBits() && + !getConstantRangeFromMetadata(*N).contains(APInt(BitWidth, 0))) { MDNode *NN = MDNode::get(OldLI.getContext(), std::nullopt); NewLI.setMetadata(LLVMContext::MD_nonnull, NN); } |
