diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2023-12-25 17:35:41 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2024-04-19 21:23:58 +0000 |
| commit | a2055961001193c277cffdfffba259ca8fad3835 (patch) | |
| tree | aceda26284a7ba56ded691457493d4ef7364f4e8 /contrib/llvm-project/llvm/lib/CodeGen | |
| parent | b168c9a3e534d5d65fd7070687b85e27217e2bcd (diff) | |
Diffstat (limited to 'contrib/llvm-project/llvm/lib/CodeGen')
27 files changed, 493 insertions, 251 deletions
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp index d6f487c18b03..30ea7eef3a12 100644 --- a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp +++ b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp @@ -412,7 +412,7 @@ static uint32_t constructAbbreviationTag( const std::optional<DWARF5AccelTable::UnitIndexAndEncoding> &EntryRet) { uint32_t AbbrvTag = 0; if (EntryRet) - AbbrvTag |= 1 << EntryRet->Endoding.Index; + AbbrvTag |= 1 << EntryRet->Encoding.Index; AbbrvTag |= 1 << dwarf::DW_IDX_die_offset; AbbrvTag |= Tag << LowerBitSize; return AbbrvTag; @@ -429,7 +429,7 @@ void Dwarf5AccelTableWriter<DataT>::populateAbbrevsMap() { if (Abbreviations.count(AbbrvTag) == 0) { SmallVector<DWARF5AccelTableData::AttributeEncoding, 2> UA; if (EntryRet) - UA.push_back(EntryRet->Endoding); + UA.push_back(EntryRet->Encoding); UA.push_back({dwarf::DW_IDX_die_offset, dwarf::DW_FORM_ref4}); Abbreviations.try_emplace(AbbrvTag, UA); } diff --git a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 61309c51336e..4dd27702786e 100644 --- a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -583,6 +583,7 @@ bool AsmPrinter::doInitialization(Module &M) { [[fallthrough]]; case ExceptionHandling::SjLj: case ExceptionHandling::DwarfCFI: + case ExceptionHandling::ZOS: ES = new DwarfCFIException(this); break; case ExceptionHandling::ARM: diff --git a/contrib/llvm-project/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp b/contrib/llvm-project/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp index 87a0ba58b14c..9037f752dc4f 100644 --- a/contrib/llvm-project/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp +++ b/contrib/llvm-project/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp @@ -1375,16 +1375,9 @@ bool InstrRefBasedLDV::transferDebugValue(const MachineInstr &MI) { if (!MI.isDebugValue()) return false; - const DILocalVariable *Var = MI.getDebugVariable(); - const DIExpression *Expr = MI.getDebugExpression(); - const DILocation *DebugLoc = MI.getDebugLoc(); - const DILocation *InlinedAt = DebugLoc->getInlinedAt(); - assert(Var->isValidLocationForIntrinsic(DebugLoc) && + assert(MI.getDebugVariable()->isValidLocationForIntrinsic(MI.getDebugLoc()) && "Expected inlined-at fields to agree"); - DebugVariable V(Var, Expr, InlinedAt); - DbgValueProperties Properties(MI); - // If there are no instructions in this lexical scope, do no location tracking // at all, this variable shouldn't get a legitimate location range. auto *Scope = LS.findLexicalScope(MI.getDebugLoc().get()); @@ -1417,7 +1410,7 @@ bool InstrRefBasedLDV::transferDebugValue(const MachineInstr &MI) { } } } - VTracker->defVar(MI, Properties, DebugOps); + VTracker->defVar(MI, DbgValueProperties(MI), DebugOps); } // If performing final tracking of transfers, report this variable definition @@ -2420,7 +2413,7 @@ bool InstrRefBasedLDV::mlocJoin( // Pick out the first predecessors live-out value for this location. It's // guaranteed to not be a backedge, as we order by RPO. - ValueIDNum FirstVal = OutLocs[BlockOrders[0]->getNumber()][Idx.asU64()]; + ValueIDNum FirstVal = OutLocs[*BlockOrders[0]][Idx.asU64()]; // If we've already eliminated a PHI here, do no further checking, just // propagate the first live-in value into this block. @@ -2437,8 +2430,7 @@ bool InstrRefBasedLDV::mlocJoin( bool Disagree = false; for (unsigned int I = 1; I < BlockOrders.size(); ++I) { const MachineBasicBlock *PredMBB = BlockOrders[I]; - const ValueIDNum &PredLiveOut = - OutLocs[PredMBB->getNumber()][Idx.asU64()]; + const ValueIDNum &PredLiveOut = OutLocs[*PredMBB][Idx.asU64()]; // Incoming values agree, continue trying to eliminate this PHI. if (FirstVal == PredLiveOut) @@ -2563,7 +2555,7 @@ void InstrRefBasedLDV::placeMLocPHIs( auto InstallPHIsAtLoc = [&PHIBlocks, &MInLocs](LocIdx L) { for (const MachineBasicBlock *MBB : PHIBlocks) - MInLocs[MBB->getNumber()][L.asU64()] = ValueIDNum(MBB->getNumber(), 0, L); + MInLocs[*MBB][L.asU64()] = ValueIDNum(MBB->getNumber(), 0, L); }; // For locations with no reg units, just place PHIs. @@ -2642,7 +2634,8 @@ void InstrRefBasedLDV::buildMLocValueMap( // Initialize entry block to PHIs. These represent arguments. for (auto Location : MTracker->locations()) - MInLocs[0][Location.Idx.asU64()] = ValueIDNum(0, 0, Location.Idx); + MInLocs.tableForEntryMBB()[Location.Idx.asU64()] = + ValueIDNum(0, 0, Location.Idx); MTracker->reset(); @@ -2671,7 +2664,7 @@ void InstrRefBasedLDV::buildMLocValueMap( // Join the values in all predecessor blocks. bool InLocsChanged; - InLocsChanged = mlocJoin(*MBB, Visited, MOutLocs, MInLocs[CurBB]); + InLocsChanged = mlocJoin(*MBB, Visited, MOutLocs, MInLocs[*MBB]); InLocsChanged |= Visited.insert(MBB).second; // Don't examine transfer function if we've visited this loc at least @@ -2680,7 +2673,7 @@ void InstrRefBasedLDV::buildMLocValueMap( continue; // Load the current set of live-ins into MLocTracker. - MTracker->loadFromArray(MInLocs[CurBB], CurBB); + MTracker->loadFromArray(MInLocs[*MBB], CurBB); // Each element of the transfer function can be a new def, or a read of // a live-in value. Evaluate each element, and store to "ToRemap". @@ -2707,8 +2700,8 @@ void InstrRefBasedLDV::buildMLocValueMap( // the transfer function, and mlocJoin. bool OLChanged = false; for (auto Location : MTracker->locations()) { - OLChanged |= MOutLocs[CurBB][Location.Idx.asU64()] != Location.Value; - MOutLocs[CurBB][Location.Idx.asU64()] = Location.Value; + OLChanged |= MOutLocs[*MBB][Location.Idx.asU64()] != Location.Value; + MOutLocs[*MBB][Location.Idx.asU64()] = Location.Value; } MTracker->reset(); @@ -2851,7 +2844,6 @@ std::optional<ValueIDNum> InstrRefBasedLDV::pickOperandPHILoc( unsigned NumLocs = MTracker->getNumLocs(); for (const auto p : BlockOrders) { - unsigned ThisBBNum = p->getNumber(); auto OutValIt = LiveOuts.find(p); assert(OutValIt != LiveOuts.end()); const DbgValue &OutVal = *OutValIt->second; @@ -2870,7 +2862,7 @@ std::optional<ValueIDNum> InstrRefBasedLDV::pickOperandPHILoc( ValueIDNum ValToLookFor = OutValOp.ID; // Search the live-outs of the predecessor for the specified value. for (unsigned int I = 0; I < NumLocs; ++I) { - if (MOutLocs[ThisBBNum][I] == ValToLookFor) + if (MOutLocs[*p][I] == ValToLookFor) Locs.back().push_back(LocIdx(I)); } } else { @@ -2883,7 +2875,7 @@ std::optional<ValueIDNum> InstrRefBasedLDV::pickOperandPHILoc( // machine-value PHI locations. for (unsigned int I = 0; I < NumLocs; ++I) { ValueIDNum MPHI(MBB.getNumber(), 0, LocIdx(I)); - if (MOutLocs[ThisBBNum][I] == MPHI) + if (MOutLocs[*p][I] == MPHI) Locs.back().push_back(LocIdx(I)); } } @@ -3505,19 +3497,15 @@ bool InstrRefBasedLDV::depthFirstVLocAndEmit( // Helper lambda for ejecting a block -- if nothing is going to use the block, // we can translate the variable location information into DBG_VALUEs and then // free all of InstrRefBasedLDV's data structures. - SmallPtrSet<const MachineBasicBlock *, 8> EjectedBBs; auto EjectBlock = [&](MachineBasicBlock &MBB) -> void { - if (EjectedBBs.insert(&MBB).second == false) - return; unsigned BBNum = MBB.getNumber(); AllTheVLocs[BBNum].clear(); // Prime the transfer-tracker, and then step through all the block // instructions, installing transfers. MTracker->reset(); - MTracker->loadFromArray(MInLocs[BBNum], BBNum); - TTracker->loadInlocs(MBB, MInLocs[BBNum], DbgOpStore, Output[BBNum], - NumLocs); + MTracker->loadFromArray(MInLocs[MBB], BBNum); + TTracker->loadInlocs(MBB, MInLocs[MBB], DbgOpStore, Output[BBNum], NumLocs); CurBB = BBNum; CurInst = 1; @@ -3528,8 +3516,8 @@ bool InstrRefBasedLDV::depthFirstVLocAndEmit( } // Free machine-location tables for this block. - MInLocs[BBNum] = ValueTable(); - MOutLocs[BBNum] = ValueTable(); + MInLocs.ejectTableForBlock(MBB); + MOutLocs.ejectTableForBlock(MBB); // We don't need live-in variable values for this block either. Output[BBNum].clear(); AllTheVLocs[BBNum].clear(); @@ -3594,7 +3582,8 @@ bool InstrRefBasedLDV::depthFirstVLocAndEmit( // anything for such out-of-scope blocks, but for the sake of being similar // to VarLocBasedLDV, eject these too. for (auto *MBB : ArtificialBlocks) - EjectBlock(*MBB); + if (MInLocs.hasTableFor(*MBB)) + EjectBlock(*MBB); return emitTransfers(AllVarsNumbering); } @@ -3693,8 +3682,8 @@ bool InstrRefBasedLDV::ExtendRanges(MachineFunction &MF, // machine values. The outer dimension is the block number; while the inner // dimension is a LocIdx from MLocTracker. unsigned NumLocs = MTracker->getNumLocs(); - FuncValueTable MOutLocs(MaxNumBlocks, ValueTable(NumLocs)); - FuncValueTable MInLocs(MaxNumBlocks, ValueTable(NumLocs)); + FuncValueTable MOutLocs(MaxNumBlocks, NumLocs); + FuncValueTable MInLocs(MaxNumBlocks, NumLocs); // Solve the machine value dataflow problem using the MLocTransfer function, // storing the computed live-ins / live-outs into the array-of-arrays. We use @@ -3732,7 +3721,7 @@ bool InstrRefBasedLDV::ExtendRanges(MachineFunction &MF, CurBB = MBB.getNumber(); VTracker = &vlocs[CurBB]; VTracker->MBB = &MBB; - MTracker->loadFromArray(MInLocs[CurBB], CurBB); + MTracker->loadFromArray(MInLocs[MBB], CurBB); CurInst = 1; for (auto &MI : MBB) { process(MI, &MOutLocs, &MInLocs); @@ -3946,7 +3935,7 @@ public: /// Find the live-in value number for the given block. Looks up the value at /// the PHI location on entry. BlockValueNum getValue(LDVSSABlock *LDVBB) { - return MLiveIns[LDVBB->BB.getNumber()][Loc.asU64()].asU64(); + return MLiveIns[LDVBB->BB][Loc.asU64()].asU64(); } }; @@ -4186,8 +4175,7 @@ std::optional<ValueIDNum> InstrRefBasedLDV::resolveDbgPHIsImpl( }); for (auto &PHI : SortedPHIs) { - ValueIDNum ThisBlockValueNum = - MLiveIns[PHI->ParentBlock->BB.getNumber()][Loc.asU64()]; + ValueIDNum ThisBlockValueNum = MLiveIns[PHI->ParentBlock->BB][Loc.asU64()]; // Are all these things actually defined? for (auto &PHIIt : PHI->IncomingValues) { @@ -4196,7 +4184,7 @@ std::optional<ValueIDNum> InstrRefBasedLDV::resolveDbgPHIsImpl( return std::nullopt; ValueIDNum ValueToCheck; - const ValueTable &BlockLiveOuts = MLiveOuts[PHIIt.first->BB.getNumber()]; + const ValueTable &BlockLiveOuts = MLiveOuts[PHIIt.first->BB]; auto VVal = ValidatedValues.find(PHIIt.first); if (VVal == ValidatedValues.end()) { diff --git a/contrib/llvm-project/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.h b/contrib/llvm-project/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.h index d6dbb1feda3e..ccc284b62331 100644 --- a/contrib/llvm-project/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.h +++ b/contrib/llvm-project/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.h @@ -207,9 +207,48 @@ using namespace llvm; /// Type for a table of values in a block. using ValueTable = SmallVector<ValueIDNum, 0>; -/// Type for a table-of-table-of-values, i.e., the collection of either -/// live-in or live-out values for each block in the function. -using FuncValueTable = SmallVector<ValueTable, 0>; +/// A collection of ValueTables, one per BB in a function, with convenient +/// accessor methods. +struct FuncValueTable { + FuncValueTable(int NumBBs, int NumLocs) { + Storage.reserve(NumBBs); + for (int i = 0; i != NumBBs; ++i) + Storage.push_back( + std::make_unique<ValueTable>(NumLocs, ValueIDNum::EmptyValue)); + } + + /// Returns the ValueTable associated with MBB. + ValueTable &operator[](const MachineBasicBlock &MBB) const { + return (*this)[MBB.getNumber()]; + } + + /// Returns the ValueTable associated with the MachineBasicBlock whose number + /// is MBBNum. + ValueTable &operator[](int MBBNum) const { + auto &TablePtr = Storage[MBBNum]; + assert(TablePtr && "Trying to access a deleted table"); + return *TablePtr; + } + + /// Returns the ValueTable associated with the entry MachineBasicBlock. + ValueTable &tableForEntryMBB() const { return (*this)[0]; } + + /// Returns true if the ValueTable associated with MBB has not been freed. + bool hasTableFor(MachineBasicBlock &MBB) const { + return Storage[MBB.getNumber()] != nullptr; + } + + /// Frees the memory of the ValueTable associated with MBB. + void ejectTableForBlock(const MachineBasicBlock &MBB) { + Storage[MBB.getNumber()].reset(); + } + +private: + /// ValueTables are stored as unique_ptrs to allow for deallocation during + /// LDV; this was measured to have a significant impact on compiler memory + /// usage. + SmallVector<std::unique_ptr<ValueTable>, 0> Storage; +}; /// Thin wrapper around an integer -- designed to give more type safety to /// spill location numbers. diff --git a/contrib/llvm-project/llvm/lib/CodeGen/LiveRangeEdit.cpp b/contrib/llvm-project/llvm/lib/CodeGen/LiveRangeEdit.cpp index 0203034b5a01..643370f0573d 100644 --- a/contrib/llvm-project/llvm/lib/CodeGen/LiveRangeEdit.cpp +++ b/contrib/llvm-project/llvm/lib/CodeGen/LiveRangeEdit.cpp @@ -426,8 +426,7 @@ void LiveRangeEdit::eliminateDeadDef(MachineInstr *MI, ToShrinkSet &ToShrink) { // Erase any virtregs that are now empty and unused. There may be <undef> // uses around. Keep the empty live range in that case. - for (unsigned i = 0, e = RegsToErase.size(); i != e; ++i) { - Register Reg = RegsToErase[i]; + for (Register Reg : RegsToErase) { if (LIS.hasInterval(Reg) && MRI.reg_nodbg_empty(Reg)) { ToShrink.remove(&LIS.getInterval(Reg)); eraseVirtReg(Reg); diff --git a/contrib/llvm-project/llvm/lib/CodeGen/LowerEmuTLS.cpp b/contrib/llvm-project/llvm/lib/CodeGen/LowerEmuTLS.cpp index f3b5069d351b..af0b0a20c856 100644 --- a/contrib/llvm-project/llvm/lib/CodeGen/LowerEmuTLS.cpp +++ b/contrib/llvm-project/llvm/lib/CodeGen/LowerEmuTLS.cpp @@ -13,7 +13,11 @@ // //===----------------------------------------------------------------------===// +#include "llvm/CodeGen/LowerEmuTLS.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/Analysis/GlobalsModRef.h" +#include "llvm/Analysis/ModuleSummaryAnalysis.h" +#include "llvm/Analysis/StackSafetyAnalysis.h" #include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/TargetPassConfig.h" #include "llvm/IR/Constants.h" @@ -24,7 +28,7 @@ using namespace llvm; -#define DEBUG_TYPE "loweremutls" +#define DEBUG_TYPE "lower-emutls" namespace { @@ -36,22 +40,41 @@ public: } bool runOnModule(Module &M) override; -private: - bool addEmuTlsVar(Module &M, const GlobalVariable *GV); - static void copyLinkageVisibility(Module &M, - const GlobalVariable *from, - GlobalVariable *to) { - to->setLinkage(from->getLinkage()); - to->setVisibility(from->getVisibility()); - to->setDSOLocal(from->isDSOLocal()); - if (from->hasComdat()) { - to->setComdat(M.getOrInsertComdat(to->getName())); - to->getComdat()->setSelectionKind(from->getComdat()->getSelectionKind()); - } - } }; } +static bool addEmuTlsVar(Module &M, const GlobalVariable *GV); + +static void copyLinkageVisibility(Module &M, const GlobalVariable *from, + GlobalVariable *to) { + to->setLinkage(from->getLinkage()); + to->setVisibility(from->getVisibility()); + to->setDSOLocal(from->isDSOLocal()); + if (from->hasComdat()) { + to->setComdat(M.getOrInsertComdat(to->getName())); + to->getComdat()->setSelectionKind(from->getComdat()->getSelectionKind()); + } +} + +PreservedAnalyses LowerEmuTLSPass::run(Module &M, ModuleAnalysisManager &MAM) { + bool Changed = false; + SmallVector<const GlobalVariable *, 8> TlsVars; + for (const auto &G : M.globals()) { + if (G.isThreadLocal()) + TlsVars.push_back(&G); + } + for (const auto *G : TlsVars) + Changed |= addEmuTlsVar(M, G); + + if (!Changed) + return PreservedAnalyses::all(); + PreservedAnalyses PA = PreservedAnalyses::all(); + PA.abandon<GlobalsAA>(); + PA.abandon<ModuleSummaryIndexAnalysis>(); + PA.abandon<StackSafetyGlobalAnalysis>(); + return PA; +} + char LowerEmuTLS::ID = 0; INITIALIZE_PASS(LowerEmuTLS, DEBUG_TYPE, @@ -83,7 +106,7 @@ bool LowerEmuTLS::runOnModule(Module &M) { return Changed; } -bool LowerEmuTLS::addEmuTlsVar(Module &M, const GlobalVariable *GV) { +bool addEmuTlsVar(Module &M, const GlobalVariable *GV) { LLVMContext &C = M.getContext(); PointerType *VoidPtrType = PointerType::getUnqual(C); diff --git a/contrib/llvm-project/llvm/lib/CodeGen/MachineInstrBundle.cpp b/contrib/llvm-project/llvm/lib/CodeGen/MachineInstrBundle.cpp index b9db34f7be95..6eeed8b5c3f7 100644 --- a/contrib/llvm-project/llvm/lib/CodeGen/MachineInstrBundle.cpp +++ b/contrib/llvm-project/llvm/lib/CodeGen/MachineInstrBundle.cpp @@ -208,8 +208,7 @@ void llvm::finalizeBundle(MachineBasicBlock &MBB, } SmallSet<Register, 32> Added; - for (unsigned i = 0, e = LocalDefs.size(); i != e; ++i) { - Register Reg = LocalDefs[i]; + for (Register Reg : LocalDefs) { if (Added.insert(Reg).second) { // If it's not live beyond end of the bundle, mark it dead. bool isDead = DeadDefSet.count(Reg) || KilledDefSet.count(Reg); @@ -218,8 +217,7 @@ void llvm::finalizeBundle(MachineBasicBlock &MBB, } } - for (unsigned i = 0, e = ExternUses.size(); i != e; ++i) { - Register Reg = ExternUses[i]; + for (Register Reg : ExternUses) { bool isKill = KilledUseSet.count(Reg); bool isUndef = UndefUseSet.count(Reg); MIB.addReg(Reg, getKillRegState(isKill) | getUndefRegState(isUndef) | diff --git a/contrib/llvm-project/llvm/lib/CodeGen/MacroFusion.cpp b/contrib/llvm-project/llvm/lib/CodeGen/MacroFusion.cpp index aff4d95781f4..5bd6ca0978a4 100644 --- a/contrib/llvm-project/llvm/lib/CodeGen/MacroFusion.cpp +++ b/contrib/llvm-project/llvm/lib/CodeGen/MacroFusion.cpp @@ -212,15 +212,9 @@ bool MacroFusion::scheduleAdjacentImpl(ScheduleDAGInstrs &DAG, SUnit &AnchorSU) } std::unique_ptr<ScheduleDAGMutation> -llvm::createMacroFusionDAGMutation(ArrayRef<MacroFusionPredTy> Predicates) { +llvm::createMacroFusionDAGMutation(ArrayRef<MacroFusionPredTy> Predicates, + bool BranchOnly) { if (EnableMacroFusion) - return std::make_unique<MacroFusion>(Predicates, true); - return nullptr; -} - -std::unique_ptr<ScheduleDAGMutation> llvm::createBranchMacroFusionDAGMutation( - ArrayRef<MacroFusionPredTy> Predicates) { - if (EnableMacroFusion) - return std::make_unique<MacroFusion>(Predicates, false); + return std::make_unique<MacroFusion>(Predicates, !BranchOnly); return nullptr; } diff --git a/contrib/llvm-project/llvm/lib/CodeGen/RegAllocFast.cpp b/contrib/llvm-project/llvm/lib/CodeGen/RegAllocFast.cpp index 40c42cabf776..e81d47930136 100644 --- a/contrib/llvm-project/llvm/lib/CodeGen/RegAllocFast.cpp +++ b/contrib/llvm-project/llvm/lib/CodeGen/RegAllocFast.cpp @@ -62,6 +62,118 @@ static RegisterRegAlloc fastRegAlloc("fast", "fast register allocator", namespace { +/// Assign ascending index for instructions in machine basic block. The index +/// can be used to determine dominance between instructions in same MBB. +class InstrPosIndexes { +public: + void unsetInitialized() { IsInitialized = false; } + + void init(const MachineBasicBlock &MBB) { + CurMBB = &MBB; + Instr2PosIndex.clear(); + uint64_t LastIndex = 0; + for (const MachineInstr &MI : MBB) { + LastIndex += InstrDist; + Instr2PosIndex[&MI] = LastIndex; + } + } + + /// Set \p Index to index of \p MI. If \p MI is new inserted, it try to assign + /// index without affecting existing instruction's index. Return true if all + /// instructions index has been reassigned. + bool getIndex(const MachineInstr &MI, uint64_t &Index) { + if (!IsInitialized) { + init(*MI.getParent()); + IsInitialized = true; + Index = Instr2PosIndex.at(&MI); + return true; + } + + assert(MI.getParent() == CurMBB && "MI is not in CurMBB"); + auto It = Instr2PosIndex.find(&MI); + if (It != Instr2PosIndex.end()) { + Index = It->second; + return false; + } + + // Distance is the number of consecutive unassigned instructions including + // MI. Start is the first instruction of them. End is the next of last + // instruction of them. + // e.g. + // |Instruction| A | B | C | MI | D | E | + // | Index | 1024 | | | | | 2048 | + // + // In this case, B, C, MI, D are unassigned. Distance is 4, Start is B, End + // is E. + unsigned Distance = 1; + MachineBasicBlock::const_iterator Start = MI.getIterator(), + End = std::next(Start); + while (Start != CurMBB->begin() && + !Instr2PosIndex.count(&*std::prev(Start))) { + --Start; + ++Distance; + } + while (End != CurMBB->end() && !Instr2PosIndex.count(&*(End))) { + ++End; + ++Distance; + } + + // LastIndex is initialized to last used index prior to MI or zero. + // In previous example, LastIndex is 1024, EndIndex is 2048; + uint64_t LastIndex = + Start == CurMBB->begin() ? 0 : Instr2PosIndex.at(&*std::prev(Start)); + uint64_t Step; + if (End == CurMBB->end()) + Step = static_cast<uint64_t>(InstrDist); + else { + // No instruction uses index zero. + uint64_t EndIndex = Instr2PosIndex.at(&*End); + assert(EndIndex > LastIndex && "Index must be ascending order"); + unsigned NumAvailableIndexes = EndIndex - LastIndex - 1; + // We want index gap between two adjacent MI is as same as possible. Given + // total A available indexes, D is number of consecutive unassigned + // instructions, S is the step. + // |<- S-1 -> MI <- S-1 -> MI <- A-S*D ->| + // There're S-1 available indexes between unassigned instruction and its + // predecessor. There're A-S*D available indexes between the last + // unassigned instruction and its successor. + // Ideally, we want + // S-1 = A-S*D + // then + // S = (A+1)/(D+1) + // An valid S must be integer greater than zero, so + // S <= (A+1)/(D+1) + // => + // A-S*D >= 0 + // That means we can safely use (A+1)/(D+1) as step. + // In previous example, Step is 204, Index of B, C, MI, D is 1228, 1432, + // 1636, 1840. + Step = (NumAvailableIndexes + 1) / (Distance + 1); + } + + // Reassign index for all instructions if number of new inserted + // instructions exceed slot or all instructions are new. + if (LLVM_UNLIKELY(!Step || (!LastIndex && Step == InstrDist))) { + init(*CurMBB); + Index = Instr2PosIndex.at(&MI); + return true; + } + + for (auto I = Start; I != End; ++I) { + LastIndex += Step; + Instr2PosIndex[&*I] = LastIndex; + } + Index = Instr2PosIndex.at(&MI); + return false; + } + +private: + bool IsInitialized = false; + enum { InstrDist = 1024 }; + const MachineBasicBlock *CurMBB = nullptr; + DenseMap<const MachineInstr *, uint64_t> Instr2PosIndex; +}; + class RegAllocFast : public MachineFunctionPass { public: static char ID; @@ -153,6 +265,9 @@ private: // Register masks attached to the current instruction. SmallVector<const uint32_t *> RegMasks; + // Assign index for each instruction to quickly determine dominance. + InstrPosIndexes PosIndexes; + void setPhysRegState(MCPhysReg PhysReg, unsigned NewState); bool isPhysRegFree(MCPhysReg PhysReg) const; @@ -339,18 +454,13 @@ int RegAllocFast::getStackSpaceFor(Register VirtReg) { return FrameIdx; } -static bool dominates(MachineBasicBlock &MBB, - MachineBasicBlock::const_iterator A, - MachineBasicBlock::const_iterator B) { - auto MBBEnd = MBB.end(); - if (B == MBBEnd) - return true; - - MachineBasicBlock::const_iterator I = MBB.begin(); - for (; &*I != A && &*I != B; ++I) - ; - - return &*I == A; +static bool dominates(InstrPosIndexes &PosIndexes, const MachineInstr &A, + const MachineInstr &B) { + uint64_t IndexA, IndexB; + PosIndexes.getIndex(A, IndexA); + if (LLVM_UNLIKELY(PosIndexes.getIndex(B, IndexB))) + PosIndexes.getIndex(A, IndexA); + return IndexA < IndexB; } /// Returns false if \p VirtReg is known to not live out of the current block. @@ -371,7 +481,7 @@ bool RegAllocFast::mayLiveOut(Register VirtReg) { MayLiveAcrossBlocks.set(Register::virtReg2Index(VirtReg)); return true; } else { - if (!SelfLoopDef || dominates(*MBB, DefInst.getIterator(), SelfLoopDef)) + if (!SelfLoopDef || dominates(PosIndexes, DefInst, *SelfLoopDef)) SelfLoopDef = &DefInst; } } @@ -396,7 +506,7 @@ bool RegAllocFast::mayLiveOut(Register VirtReg) { // Try to handle some simple cases to avoid spilling and reloading every // value inside a self looping block. if (SelfLoopDef == &UseInst || - !dominates(*MBB, SelfLoopDef->getIterator(), UseInst.getIterator())) { + !dominates(PosIndexes, *SelfLoopDef, UseInst)) { MayLiveAcrossBlocks.set(Register::virtReg2Index(VirtReg)); return true; } @@ -1565,6 +1675,7 @@ void RegAllocFast::allocateBasicBlock(MachineBasicBlock &MBB) { this->MBB = &MBB; LLVM_DEBUG(dbgs() << "\nAllocating " << MBB); + PosIndexes.unsetInitialized(); RegUnitStates.assign(TRI->getNumRegUnits(), regFree); assert(LiveVirtRegs.empty() && "Mapping not cleared from last block?"); diff --git a/contrib/llvm-project/llvm/lib/CodeGen/RegisterClassInfo.cpp b/contrib/llvm-project/llvm/lib/CodeGen/RegisterClassInfo.cpp index fba8c35ecec2..17a9f55cccc0 100644 --- a/contrib/llvm-project/llvm/lib/CodeGen/RegisterClassInfo.cpp +++ b/contrib/llvm-project/llvm/lib/CodeGen/RegisterClassInfo.cpp @@ -165,8 +165,7 @@ void RegisterClassInfo::compute(const TargetRegisterClass *RC) const { assert(RCI.NumRegs <= NumRegs && "Allocation order larger than regclass"); // CSR aliases go after the volatile registers, preserve the target's order. - for (unsigned i = 0, e = CSRAlias.size(); i != e; ++i) { - unsigned PhysReg = CSRAlias[i]; + for (unsigned PhysReg : CSRAlias) { uint8_t Cost = RegCosts[PhysReg]; if (Cost != LastCost) LastCostChange = N; diff --git a/contrib/llvm-project/llvm/lib/CodeGen/RegisterCoalescer.cpp b/contrib/llvm-project/llvm/lib/CodeGen/RegisterCoalescer.cpp index c1af37c8510f..3fbb93795075 100644 --- a/contrib/llvm-project/llvm/lib/CodeGen/RegisterCoalescer.cpp +++ b/contrib/llvm-project/llvm/lib/CodeGen/RegisterCoalescer.cpp @@ -305,7 +305,11 @@ namespace { /// number if it is not zero. If DstReg is a physical register and the /// existing subregister number of the def / use being updated is not zero, /// make sure to set it to the correct physical subregister. - void updateRegDefsUses(Register SrcReg, Register DstReg, unsigned SubIdx); + /// + /// If \p IsSubregToReg, we are coalescing a DstReg = SUBREG_TO_REG + /// SrcReg. This introduces an implicit-def of DstReg on coalesced users. + void updateRegDefsUses(Register SrcReg, Register DstReg, unsigned SubIdx, + bool IsSubregToReg); /// If the given machine operand reads only undefined lanes add an undef /// flag. @@ -1343,8 +1347,7 @@ bool RegisterCoalescer::reMaterializeTrivialDef(const CoalescerPair &CP, if (DstReg.isPhysical()) { Register NewDstReg = DstReg; - unsigned NewDstIdx = TRI->composeSubRegIndices(CP.getSrcIdx(), - DefMI->getOperand(0).getSubReg()); + unsigned NewDstIdx = TRI->composeSubRegIndices(CP.getSrcIdx(), DefSubIdx); if (NewDstIdx) NewDstReg = TRI->getSubReg(DstReg, NewDstIdx); @@ -1493,7 +1496,7 @@ bool RegisterCoalescer::reMaterializeTrivialDef(const CoalescerPair &CP, MRI->setRegClass(DstReg, NewRC); // Update machine operands and add flags. - updateRegDefsUses(DstReg, DstReg, DstIdx); + updateRegDefsUses(DstReg, DstReg, DstIdx, false); NewMI.getOperand(0).setSubReg(NewIdx); // updateRegDefUses can add an "undef" flag to the definition, since // it will replace DstReg with DstReg.DstIdx. If NewIdx is 0, make @@ -1618,8 +1621,7 @@ bool RegisterCoalescer::reMaterializeTrivialDef(const CoalescerPair &CP, NewMI.addOperand(MO); SlotIndex NewMIIdx = LIS->getInstructionIndex(NewMI); - for (unsigned i = 0, e = NewMIImplDefs.size(); i != e; ++i) { - MCRegister Reg = NewMIImplDefs[i]; + for (MCRegister Reg : NewMIImplDefs) { for (MCRegUnit Unit : TRI->regunits(Reg)) if (LiveRange *LR = LIS->getCachedRegUnit(Unit)) LR->createDeadDef(NewMIIdx.getRegSlot(), LIS->getVNInfoAllocator()); @@ -1814,7 +1816,7 @@ void RegisterCoalescer::addUndefFlag(const LiveInterval &Int, SlotIndex UseIdx, } void RegisterCoalescer::updateRegDefsUses(Register SrcReg, Register DstReg, - unsigned SubIdx) { + unsigned SubIdx, bool IsSubregToReg) { bool DstIsPhys = DstReg.isPhysical(); LiveInterval *DstInt = DstIsPhys ? nullptr : &LIS->getInterval(DstReg); @@ -1854,6 +1856,8 @@ void RegisterCoalescer::updateRegDefsUses(Register SrcReg, Register DstReg, if (DstInt && !Reads && SubIdx && !UseMI->isDebugInstr()) Reads = DstInt->liveAt(LIS->getInstructionIndex(*UseMI)); + bool FullDef = true; + // Replace SrcReg with DstReg in all UseMI operands. for (unsigned i = 0, e = Ops.size(); i != e; ++i) { MachineOperand &MO = UseMI->getOperand(Ops[i]); @@ -1861,9 +1865,13 @@ void RegisterCoalescer::updateRegDefsUses(Register SrcReg, Register DstReg, // Adjust <undef> flags in case of sub-register joins. We don't want to // turn a full def into a read-modify-write sub-register def and vice // versa. - if (SubIdx && MO.isDef()) + if (SubIdx && MO.isDef()) { MO.setIsUndef(!Reads); + if (!Reads) + FullDef = false; + } + // A subreg use of a partially undef (super) register may be a complete // undef use now and then has to be marked that way. if (MO.isUse() && !DstIsPhys) { @@ -1895,6 +1903,25 @@ void RegisterCoalescer::updateRegDefsUses(Register SrcReg, Register DstReg, MO.substVirtReg(DstReg, SubIdx, *TRI); } + if (IsSubregToReg && !FullDef) { + // If the coalesed instruction doesn't fully define the register, we need + // to preserve the original super register liveness for SUBREG_TO_REG. + // + // We pretended SUBREG_TO_REG was a regular copy for coalescing purposes, + // but it introduces liveness for other subregisters. Downstream users may + // have been relying on those bits, so we need to ensure their liveness is + // captured with a def of other lanes. + + // FIXME: Need to add new subrange if tracking subranges. We could also + // skip adding this if we knew the other lanes are dead, and only for + // other lanes. + + assert(!MRI->shouldTrackSubRegLiveness(DstReg) && + "this should update subranges"); + MachineInstrBuilder MIB(*MF, UseMI); + MIB.addReg(DstReg, RegState::ImplicitDefine); + } + LLVM_DEBUG({ dbgs() << "\t\tupdated: "; if (!UseMI->isDebugInstr()) @@ -2094,6 +2121,8 @@ bool RegisterCoalescer::joinCopy(MachineInstr *CopyMI, bool &Again) { }); } + const bool IsSubregToReg = CopyMI->isSubregToReg(); + ShrinkMask = LaneBitmask::getNone(); ShrinkMainRange = false; @@ -2161,9 +2190,12 @@ bool RegisterCoalescer::joinCopy(MachineInstr *CopyMI, bool &Again) { // Rewrite all SrcReg operands to DstReg. // Also update DstReg operands to include DstIdx if it is set. - if (CP.getDstIdx()) - updateRegDefsUses(CP.getDstReg(), CP.getDstReg(), CP.getDstIdx()); - updateRegDefsUses(CP.getSrcReg(), CP.getDstReg(), CP.getSrcIdx()); + if (CP.getDstIdx()) { + assert(!IsSubregToReg && "can this happen?"); + updateRegDefsUses(CP.getDstReg(), CP.getDstReg(), CP.getDstIdx(), false); + } + updateRegDefsUses(CP.getSrcReg(), CP.getDstReg(), CP.getSrcIdx(), + IsSubregToReg); // Shrink subregister ranges if necessary. if (ShrinkMask.any()) { @@ -4236,8 +4268,7 @@ bool RegisterCoalescer::runOnMachineFunction(MachineFunction &fn) { InflateRegs.end()); LLVM_DEBUG(dbgs() << "Trying to inflate " << InflateRegs.size() << " regs.\n"); - for (unsigned i = 0, e = InflateRegs.size(); i != e; ++i) { - Register Reg = InflateRegs[i]; + for (Register Reg : InflateRegs) { if (MRI->reg_nodbg_empty(Reg)) continue; if (MRI->recomputeRegClass(Reg)) { diff --git a/contrib/llvm-project/llvm/lib/CodeGen/ReplaceWithVeclib.cpp b/contrib/llvm-project/llvm/lib/CodeGen/ReplaceWithVeclib.cpp index 36c91b7fa97e..893aa4a91828 100644 --- a/contrib/llvm-project/llvm/lib/CodeGen/ReplaceWithVeclib.cpp +++ b/contrib/llvm-project/llvm/lib/CodeGen/ReplaceWithVeclib.cpp @@ -15,14 +15,17 @@ #include "llvm/CodeGen/ReplaceWithVeclib.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/Statistic.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Analysis/DemandedBits.h" #include "llvm/Analysis/GlobalsModRef.h" #include "llvm/Analysis/OptimizationRemarkEmitter.h" #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Analysis/VectorUtils.h" #include "llvm/CodeGen/Passes.h" +#include "llvm/IR/DerivedTypes.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/InstIterator.h" +#include "llvm/Support/TypeSize.h" #include "llvm/Transforms/Utils/ModuleUtils.h" using namespace llvm; @@ -38,138 +41,137 @@ STATISTIC(NumTLIFuncDeclAdded, STATISTIC(NumFuncUsedAdded, "Number of functions added to `llvm.compiler.used`"); -static bool replaceWithTLIFunction(CallInst &CI, const StringRef TLIName) { - Module *M = CI.getModule(); - - Function *OldFunc = CI.getCalledFunction(); - - // Check if the vector library function is already declared in this module, - // otherwise insert it. +/// Returns a vector Function that it adds to the Module \p M. When an \p +/// ScalarFunc is not null, it copies its attributes to the newly created +/// Function. +Function *getTLIFunction(Module *M, FunctionType *VectorFTy, + const StringRef TLIName, + Function *ScalarFunc = nullptr) { Function *TLIFunc = M->getFunction(TLIName); if (!TLIFunc) { - TLIFunc = Function::Create(OldFunc->getFunctionType(), - Function::ExternalLinkage, TLIName, *M); - TLIFunc->copyAttributesFrom(OldFunc); + TLIFunc = + Function::Create(VectorFTy, Function::ExternalLinkage, TLIName, *M); + if (ScalarFunc) + TLIFunc->copyAttributesFrom(ScalarFunc); LLVM_DEBUG(dbgs() << DEBUG_TYPE << ": Added vector library function `" << TLIName << "` of type `" << *(TLIFunc->getType()) << "` to module.\n"); ++NumTLIFuncDeclAdded; - - // Add the freshly created function to llvm.compiler.used, - // similar to as it is done in InjectTLIMappings + // Add the freshly created function to llvm.compiler.used, similar to as it + // is done in InjectTLIMappings. appendToCompilerUsed(*M, {TLIFunc}); - LLVM_DEBUG(dbgs() << DEBUG_TYPE << ": Adding `" << TLIName << "` to `@llvm.compiler.used`.\n"); ++NumFuncUsedAdded; } + return TLIFunc; +} - // Replace the call to the vector intrinsic with a call - // to the corresponding function from the vector library. - IRBuilder<> IRBuilder(&CI); - SmallVector<Value *> Args(CI.args()); - // Preserve the operand bundles. - SmallVector<OperandBundleDef, 1> OpBundles; - CI.getOperandBundlesAsDefs(OpBundles); - CallInst *Replacement = IRBuilder.CreateCall(TLIFunc, Args, OpBundles); - assert(OldFunc->getFunctionType() == TLIFunc->getFunctionType() && - "Expecting function types to be identical"); - CI.replaceAllUsesWith(Replacement); - if (isa<FPMathOperator>(Replacement)) { - // Preserve fast math flags for FP math. - Replacement->copyFastMathFlags(&CI); +/// Replace the call to the vector intrinsic ( \p CalltoReplace ) with a call to +/// the corresponding function from the vector library ( \p TLIVecFunc ). +static void replaceWithTLIFunction(CallInst &CalltoReplace, VFInfo &Info, + Function *TLIVecFunc) { + IRBuilder<> IRBuilder(&CalltoReplace); + SmallVector<Value *> Args(CalltoReplace.args()); + if (auto OptMaskpos = Info.getParamIndexForOptionalMask()) { + auto *MaskTy = VectorType::get(Type::getInt1Ty(CalltoReplace.getContext()), + Info.Shape.VF); + Args.insert(Args.begin() + OptMaskpos.value(), + Constant::getAllOnesValue(MaskTy)); } - LLVM_DEBUG(dbgs() << DEBUG_TYPE << ": Replaced call to `" - << OldFunc->getName() << "` with call to `" << TLIName - << "`.\n"); - ++NumCallsReplaced; - return true; + // Preserve the operand bundles. + SmallVector<OperandBundleDef, 1> OpBundles; + CalltoReplace.getOperandBundlesAsDefs(OpBundles); + CallInst *Replacement = IRBuilder.CreateCall(TLIVecFunc, Args, OpBundles); + CalltoReplace.replaceAllUsesWith(Replacement); + // Preserve fast math flags for FP math. + if (isa<FPMathOperator>(Replacement)) + Replacement->copyFastMathFlags(&CalltoReplace); } +/// Returns true when successfully replaced \p CallToReplace with a suitable +/// function taking vector arguments, based on available mappings in the \p TLI. +/// Currently only works when \p CallToReplace is a call to vectorized +/// intrinsic. static bool replaceWithCallToVeclib(const TargetLibraryInfo &TLI, - CallInst &CI) { - if (!CI.getCalledFunction()) { + CallInst &CallToReplace) { + if (!CallToReplace.getCalledFunction()) return false; - } - auto IntrinsicID = CI.getCalledFunction()->getIntrinsicID(); - if (IntrinsicID == Intrinsic::not_intrinsic) { - // Replacement is only performed for intrinsic functions + auto IntrinsicID = CallToReplace.getCalledFunction()->getIntrinsicID(); + // Replacement is only performed for intrinsic functions. + if (IntrinsicID == Intrinsic::not_intrinsic) return false; - } - // Convert vector arguments to scalar type and check that - // all vector operands have identical vector width. + // Compute arguments types of the corresponding scalar call. Additionally + // checks if in the vector call, all vector operands have the same EC. ElementCount VF = ElementCount::getFixed(0); - SmallVector<Type *> ScalarTypes; - for (auto Arg : enumerate(CI.args())) { - auto *ArgType = Arg.value()->getType(); - // Vector calls to intrinsics can still have - // scalar operands for specific arguments. + SmallVector<Type *> ScalarArgTypes; + for (auto Arg : enumerate(CallToReplace.args())) { + auto *ArgTy = Arg.value()->getType(); if (isVectorIntrinsicWithScalarOpAtArg(IntrinsicID, Arg.index())) { - ScalarTypes.push_back(ArgType); - } else { - // The argument in this place should be a vector if - // this is a call to a vector intrinsic. - auto *VectorArgTy = dyn_cast<VectorType>(ArgType); - if (!VectorArgTy) { - // The argument is not a vector, do not perform - // the replacement. - return false; - } - ElementCount NumElements = VectorArgTy->getElementCount(); - if (NumElements.isScalable()) { - // The current implementation does not support - // scalable vectors. + ScalarArgTypes.push_back(ArgTy); + } else if (auto *VectorArgTy = dyn_cast<VectorType>(ArgTy)) { + ScalarArgTypes.push_back(ArgTy->getScalarType()); + // Disallow vector arguments with different VFs. When processing the first + // vector argument, store it's VF, and for the rest ensure that they match + // it. + if (VF.isZero()) + VF = VectorArgTy->getElementCount(); + else if (VF != VectorArgTy->getElementCount()) return false; - } - if (VF.isNonZero() && VF != NumElements) { - // The different arguments differ in vector size. - return false; - } else { - VF = NumElements; - } - ScalarTypes.push_back(VectorArgTy->getElementType()); - } + } else + // Exit when it is supposed to be a vector argument but it isn't. + return false; } - // Try to reconstruct the name for the scalar version of this - // intrinsic using the intrinsic ID and the argument types - // converted to scalar above. - std::string ScalarName; - if (Intrinsic::isOverloaded(IntrinsicID)) { - ScalarName = Intrinsic::getName(IntrinsicID, ScalarTypes, CI.getModule()); - } else { - ScalarName = Intrinsic::getName(IntrinsicID).str(); - } + // Try to reconstruct the name for the scalar version of this intrinsic using + // the intrinsic ID and the argument types converted to scalar above. + std::string ScalarName = + (Intrinsic::isOverloaded(IntrinsicID) + ? Intrinsic::getName(IntrinsicID, ScalarArgTypes, + CallToReplace.getModule()) + : Intrinsic::getName(IntrinsicID).str()); + + // Try to find the mapping for the scalar version of this intrinsic and the + // exact vector width of the call operands in the TargetLibraryInfo. First, + // check with a non-masked variant, and if that fails try with a masked one. + const VecDesc *VD = + TLI.getVectorMappingInfo(ScalarName, VF, /*Masked*/ false); + if (!VD && !(VD = TLI.getVectorMappingInfo(ScalarName, VF, /*Masked*/ true))) + return false; - if (!TLI.isFunctionVectorizable(ScalarName)) { - // The TargetLibraryInfo does not contain a vectorized version of - // the scalar function. + LLVM_DEBUG(dbgs() << DEBUG_TYPE << ": Found TLI mapping from: `" << ScalarName + << "` and vector width " << VF << " to: `" + << VD->getVectorFnName() << "`.\n"); + + // Replace the call to the intrinsic with a call to the vector library + // function. + Type *ScalarRetTy = CallToReplace.getType()->getScalarType(); + FunctionType *ScalarFTy = + FunctionType::get(ScalarRetTy, ScalarArgTypes, /*isVarArg*/ false); + const std::string MangledName = VD->getVectorFunctionABIVariantString(); + auto OptInfo = VFABI::tryDemangleForVFABI(MangledName, ScalarFTy); + if (!OptInfo) return false; - } - // Try to find the mapping for the scalar version of this intrinsic - // and the exact vector width of the call operands in the - // TargetLibraryInfo. - StringRef TLIName = TLI.getVectorizedFunction(ScalarName, VF); - - LLVM_DEBUG(dbgs() << DEBUG_TYPE << ": Looking up TLI mapping for `" - << ScalarName << "` and vector width " << VF << ".\n"); - - if (!TLIName.empty()) { - // Found the correct mapping in the TargetLibraryInfo, - // replace the call to the intrinsic with a call to - // the vector library function. - LLVM_DEBUG(dbgs() << DEBUG_TYPE << ": Found TLI function `" << TLIName - << "`.\n"); - return replaceWithTLIFunction(CI, TLIName); - } + FunctionType *VectorFTy = VFABI::createFunctionType(*OptInfo, ScalarFTy); + if (!VectorFTy) + return false; + + Function *FuncToReplace = CallToReplace.getCalledFunction(); + Function *TLIFunc = getTLIFunction(CallToReplace.getModule(), VectorFTy, + VD->getVectorFnName(), FuncToReplace); + replaceWithTLIFunction(CallToReplace, *OptInfo, TLIFunc); - return false; + LLVM_DEBUG(dbgs() << DEBUG_TYPE << ": Replaced call to `" + << FuncToReplace->getName() << "` with call to `" + << TLIFunc->getName() << "`.\n"); + ++NumCallsReplaced; + return true; } static bool runImpl(const TargetLibraryInfo &TLI, Function &F) { @@ -185,9 +187,8 @@ static bool runImpl(const TargetLibraryInfo &TLI, Function &F) { } // Erase the calls to the intrinsics that have been replaced // with calls to the vector library. - for (auto *CI : ReplacedCalls) { + for (auto *CI : ReplacedCalls) CI->eraseFromParent(); - } return Changed; } @@ -207,10 +208,10 @@ PreservedAnalyses ReplaceWithVeclib::run(Function &F, PA.preserve<DemandedBitsAnalysis>(); PA.preserve<OptimizationRemarkEmitterAnalysis>(); return PA; - } else { - // The pass did not replace any calls, hence it preserves all analyses. - return PreservedAnalyses::all(); } + + // The pass did not replace any calls, hence it preserves all analyses. + return PreservedAnalyses::all(); } //////////////////////////////////////////////////////////////////////////////// diff --git a/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index c782ad117ce6..0d46c7868d87 100644 --- a/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -13703,8 +13703,7 @@ SDValue DAGCombiner::visitZERO_EXTEND(SDNode *N) { if (N0.getOpcode() == ISD::AND && N0.getOperand(0).getOpcode() == ISD::TRUNCATE && N0.getOperand(1).getOpcode() == ISD::Constant && - (!TLI.isTruncateFree(N0.getOperand(0).getOperand(0).getValueType(), - N0.getValueType()) || + (!TLI.isTruncateFree(N0.getOperand(0).getOperand(0), N0.getValueType()) || !TLI.isZExtFree(N0.getValueType(), VT))) { SDValue X = N0.getOperand(0).getOperand(0); X = DAG.getAnyExtOrTrunc(X, SDLoc(X), VT); @@ -13935,8 +13934,7 @@ SDValue DAGCombiner::visitANY_EXTEND(SDNode *N) { if (N0.getOpcode() == ISD::AND && N0.getOperand(0).getOpcode() == ISD::TRUNCATE && N0.getOperand(1).getOpcode() == ISD::Constant && - !TLI.isTruncateFree(N0.getOperand(0).getOperand(0).getValueType(), - N0.getValueType())) { + !TLI.isTruncateFree(N0.getOperand(0).getOperand(0), N0.getValueType())) { SDLoc DL(N); SDValue X = DAG.getAnyExtOrTrunc(N0.getOperand(0).getOperand(0), DL, VT); SDValue Y = DAG.getNode(ISD::ANY_EXTEND, DL, VT, N0.getOperand(1)); @@ -14759,6 +14757,7 @@ SDValue DAGCombiner::visitTRUNCATE(SDNode *N) { // Attempt to pre-truncate BUILD_VECTOR sources. if (N0.getOpcode() == ISD::BUILD_VECTOR && !LegalOperations && + N0.hasOneUse() && TLI.isTruncateFree(SrcVT.getScalarType(), VT.getScalarType()) && // Avoid creating illegal types if running after type legalizer. (!LegalTypes || TLI.isTypeLegal(VT.getScalarType()))) { @@ -14818,11 +14817,11 @@ SDValue DAGCombiner::visitTRUNCATE(SDNode *N) { if (SDValue Reduced = reduceLoadWidth(N)) return Reduced; - // Handle the case where the load remains an extending load even - // after truncation. + // Handle the case where the truncated result is at least as wide as the + // loaded type. if (N0.hasOneUse() && ISD::isUNINDEXEDLoad(N0.getNode())) { auto *LN0 = cast<LoadSDNode>(N0); - if (LN0->isSimple() && LN0->getMemoryVT().bitsLT(VT)) { + if (LN0->isSimple() && LN0->getMemoryVT().bitsLE(VT)) { SDValue NewLoad = DAG.getExtLoad( LN0->getExtensionType(), SDLoc(LN0), VT, LN0->getChain(), LN0->getBasePtr(), LN0->getMemoryVT(), LN0->getMemOperand()); @@ -15165,8 +15164,7 @@ SDValue DAGCombiner::visitBITCAST(SDNode *N) { *LN0->getMemOperand())) { SDValue Load = DAG.getLoad(VT, SDLoc(N), LN0->getChain(), LN0->getBasePtr(), - LN0->getPointerInfo(), LN0->getAlign(), - LN0->getMemOperand()->getFlags(), LN0->getAAInfo()); + LN0->getMemOperand()); DAG.ReplaceAllUsesOfValueWith(N0.getValue(1), Load.getValue(1)); return Load; } @@ -18855,8 +18853,7 @@ struct LoadedSlice { void addSliceGain(const LoadedSlice &LS) { // Each slice saves a truncate. const TargetLowering &TLI = LS.DAG->getTargetLoweringInfo(); - if (!TLI.isTruncateFree(LS.Inst->getOperand(0).getValueType(), - LS.Inst->getValueType(0))) + if (!TLI.isTruncateFree(LS.Inst->getOperand(0), LS.Inst->getValueType(0))) ++Truncates; // If there is a shift amount, this slice gets rid of it. if (LS.Shift) diff --git a/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp b/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp index a83129586339..f3d8edb8926b 100644 --- a/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp +++ b/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp @@ -1000,8 +1000,7 @@ bool FastISel::lowerCallTo(CallLoweringInfo &CLI) { if (!CanLowerReturn) return false; - for (unsigned I = 0, E = RetTys.size(); I != E; ++I) { - EVT VT = RetTys[I]; + for (EVT VT : RetTys) { MVT RegisterVT = TLI.getRegisterType(CLI.RetTy->getContext(), VT); unsigned NumRegs = TLI.getNumRegisters(CLI.RetTy->getContext(), VT); for (unsigned i = 0; i != NumRegs; ++i) { diff --git a/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp b/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp index 03cba892a167..5926a6058111 100644 --- a/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp +++ b/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp @@ -377,8 +377,7 @@ Register FunctionLoweringInfo::CreateRegs(Type *Ty, bool isDivergent) { ComputeValueVTs(*TLI, MF->getDataLayout(), Ty, ValueVTs); Register FirstReg; - for (unsigned Value = 0, e = ValueVTs.size(); Value != e; ++Value) { - EVT ValueVT = ValueVTs[Value]; + for (EVT ValueVT : ValueVTs) { MVT RegisterVT = TLI->getRegisterType(Ty->getContext(), ValueVT); unsigned NumRegs = TLI->getNumRegisters(Ty->getContext(), ValueVT); diff --git a/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 5e1f9fbcdde0..4e317062cec4 100644 --- a/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -913,14 +913,17 @@ void SelectionDAGLegalize::LegalizeLoadOps(SDNode *Node) { // normal undefined upper bits behavior to allow using an in-reg extend // with the illegal FP type, so load as an integer and do the // from-integer conversion. - if (SrcVT.getScalarType() == MVT::f16) { + EVT SVT = SrcVT.getScalarType(); + if (SVT == MVT::f16 || SVT == MVT::bf16) { EVT ISrcVT = SrcVT.changeTypeToInteger(); EVT IDestVT = DestVT.changeTypeToInteger(); EVT ILoadVT = TLI.getRegisterType(IDestVT.getSimpleVT()); SDValue Result = DAG.getExtLoad(ISD::ZEXTLOAD, dl, ILoadVT, Chain, Ptr, ISrcVT, LD->getMemOperand()); - Value = DAG.getNode(ISD::FP16_TO_FP, dl, DestVT, Result); + Value = + DAG.getNode(SVT == MVT::f16 ? ISD::FP16_TO_FP : ISD::BF16_TO_FP, + dl, DestVT, Result); Chain = Result.getValue(1); break; } @@ -4905,7 +4908,9 @@ void SelectionDAGLegalize::ConvertNodeToLibcall(SDNode *Node) { static MVT getPromotedVectorElementType(const TargetLowering &TLI, MVT EltVT, MVT NewEltVT) { unsigned OldEltsPerNewElt = EltVT.getSizeInBits() / NewEltVT.getSizeInBits(); - MVT MidVT = MVT::getVectorVT(NewEltVT, OldEltsPerNewElt); + MVT MidVT = OldEltsPerNewElt == 1 + ? NewEltVT + : MVT::getVectorVT(NewEltVT, OldEltsPerNewElt); assert(TLI.isTypeLegal(MidVT) && "unexpected"); return MidVT; } @@ -5349,6 +5354,7 @@ void SelectionDAGLegalize::PromoteNode(SDNode *Node) { case ISD::FEXP: case ISD::FEXP2: case ISD::FEXP10: + case ISD::FCANONICALIZE: Tmp1 = DAG.getNode(ISD::FP_EXTEND, dl, NVT, Node->getOperand(0)); Tmp2 = DAG.getNode(Node->getOpcode(), dl, NVT, Tmp1); Results.push_back( @@ -5391,7 +5397,7 @@ void SelectionDAGLegalize::PromoteNode(SDNode *Node) { assert(NVT.isVector() && OVT.getSizeInBits() == NVT.getSizeInBits() && "Invalid promote type for build_vector"); - assert(NewEltVT.bitsLT(EltVT) && "not handled"); + assert(NewEltVT.bitsLE(EltVT) && "not handled"); MVT MidVT = getPromotedVectorElementType(TLI, EltVT, NewEltVT); @@ -5402,7 +5408,9 @@ void SelectionDAGLegalize::PromoteNode(SDNode *Node) { } SDLoc SL(Node); - SDValue Concat = DAG.getNode(ISD::CONCAT_VECTORS, SL, NVT, NewOps); + SDValue Concat = + DAG.getNode(MidVT == NewEltVT ? ISD::BUILD_VECTOR : ISD::CONCAT_VECTORS, + SL, NVT, NewOps); SDValue CvtVec = DAG.getNode(ISD::BITCAST, SL, OVT, Concat); Results.push_back(CvtVec); break; diff --git a/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp b/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp index c4605a6b9598..65919a64b806 100644 --- a/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp +++ b/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp @@ -2214,6 +2214,9 @@ bool DAGTypeLegalizer::PromoteFloatOperand(SDNode *N, unsigned OpNo) { case ISD::FP_TO_UINT_SAT: R = PromoteFloatOp_FP_TO_XINT_SAT(N, OpNo); break; case ISD::FP_EXTEND: R = PromoteFloatOp_FP_EXTEND(N, OpNo); break; + case ISD::STRICT_FP_EXTEND: + R = PromoteFloatOp_STRICT_FP_EXTEND(N, OpNo); + break; case ISD::SELECT_CC: R = PromoteFloatOp_SELECT_CC(N, OpNo); break; case ISD::SETCC: R = PromoteFloatOp_SETCC(N, OpNo); break; case ISD::STORE: R = PromoteFloatOp_STORE(N, OpNo); break; @@ -2276,6 +2279,26 @@ SDValue DAGTypeLegalizer::PromoteFloatOp_FP_EXTEND(SDNode *N, unsigned OpNo) { return DAG.getNode(ISD::FP_EXTEND, SDLoc(N), VT, Op); } +SDValue DAGTypeLegalizer::PromoteFloatOp_STRICT_FP_EXTEND(SDNode *N, + unsigned OpNo) { + assert(OpNo == 1); + + SDValue Op = GetPromotedFloat(N->getOperand(1)); + EVT VT = N->getValueType(0); + + // Desired VT is same as promoted type. Use promoted float directly. + if (VT == Op->getValueType(0)) { + ReplaceValueWith(SDValue(N, 1), N->getOperand(0)); + return Op; + } + + // Else, extend the promoted float value to the desired VT. + SDValue Res = DAG.getNode(ISD::STRICT_FP_EXTEND, SDLoc(N), N->getVTList(), + N->getOperand(0), Op); + ReplaceValueWith(SDValue(N, 1), Res.getValue(1)); + return Res; +} + // Promote the float operands used for comparison. The true- and false- // operands have the same type as the result and are promoted, if needed, by // PromoteFloatRes_SELECT_CC diff --git a/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp index 362fa92dd44b..3d21bd22e6ef 100644 --- a/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp +++ b/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp @@ -1871,6 +1871,9 @@ bool DAGTypeLegalizer::PromoteIntegerOperand(SDNode *N, unsigned OpNo) { case ISD::EXPERIMENTAL_VP_STRIDED_STORE: Res = PromoteIntOp_VP_STRIDED(N, OpNo); break; + case ISD::EXPERIMENTAL_VP_SPLICE: + Res = PromoteIntOp_VP_SPLICE(N, OpNo); + break; } // If the result is null, the sub-method took care of registering results etc. @@ -2549,6 +2552,20 @@ SDValue DAGTypeLegalizer::PromoteIntOp_VP_STRIDED(SDNode *N, unsigned OpNo) { return SDValue(DAG.UpdateNodeOperands(N, NewOps), 0); } +SDValue DAGTypeLegalizer::PromoteIntOp_VP_SPLICE(SDNode *N, unsigned OpNo) { + SmallVector<SDValue, 6> NewOps(N->op_begin(), N->op_end()); + + if (OpNo == 2) { // Offset operand + NewOps[OpNo] = SExtPromotedInteger(N->getOperand(OpNo)); + return SDValue(DAG.UpdateNodeOperands(N, NewOps), 0); + } + + assert((OpNo == 4 || OpNo == 5) && "Unexpected operand for promotion"); + + NewOps[OpNo] = ZExtPromotedInteger(N->getOperand(OpNo)); + return SDValue(DAG.UpdateNodeOperands(N, NewOps), 0); +} + //===----------------------------------------------------------------------===// // Integer Result Expansion //===----------------------------------------------------------------------===// diff --git a/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h index 9d5931b44ac6..84b1b2c71fd0 100644 --- a/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h +++ b/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h @@ -410,6 +410,7 @@ private: SDValue PromoteIntOp_STACKMAP(SDNode *N, unsigned OpNo); SDValue PromoteIntOp_PATCHPOINT(SDNode *N, unsigned OpNo); SDValue PromoteIntOp_VP_STRIDED(SDNode *N, unsigned OpNo); + SDValue PromoteIntOp_VP_SPLICE(SDNode *N, unsigned OpNo); void PromoteSetCCOperands(SDValue &LHS,SDValue &RHS, ISD::CondCode Code); @@ -712,6 +713,7 @@ private: SDValue PromoteFloatOp_BITCAST(SDNode *N, unsigned OpNo); SDValue PromoteFloatOp_FCOPYSIGN(SDNode *N, unsigned OpNo); SDValue PromoteFloatOp_FP_EXTEND(SDNode *N, unsigned OpNo); + SDValue PromoteFloatOp_STRICT_FP_EXTEND(SDNode *N, unsigned OpNo); SDValue PromoteFloatOp_UnaryOp(SDNode *N, unsigned OpNo); SDValue PromoteFloatOp_FP_TO_XINT_SAT(SDNode *N, unsigned OpNo); SDValue PromoteFloatOp_STORE(SDNode *N, unsigned OpNo); diff --git a/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp b/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp index ab4c33c9e976..f73ddfee2b90 100644 --- a/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp +++ b/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp @@ -296,28 +296,24 @@ SUnit *ScheduleDAGFast::CopyAndMoveSuccessors(SUnit *SU) { if (isNewLoad) AddPred(LoadSU, ChainPred); } - for (unsigned i = 0, e = LoadPreds.size(); i != e; ++i) { - const SDep &Pred = LoadPreds[i]; + for (const SDep &Pred : LoadPreds) { RemovePred(SU, Pred); if (isNewLoad) { AddPred(LoadSU, Pred); } } - for (unsigned i = 0, e = NodePreds.size(); i != e; ++i) { - const SDep &Pred = NodePreds[i]; + for (const SDep &Pred : NodePreds) { RemovePred(SU, Pred); AddPred(NewSU, Pred); } - for (unsigned i = 0, e = NodeSuccs.size(); i != e; ++i) { - SDep D = NodeSuccs[i]; + for (SDep D : NodeSuccs) { SUnit *SuccDep = D.getSUnit(); D.setSUnit(SU); RemovePred(SuccDep, D); D.setSUnit(NewSU); AddPred(SuccDep, D); } - for (unsigned i = 0, e = ChainSuccs.size(); i != e; ++i) { - SDep D = ChainSuccs[i]; + for (SDep D : ChainSuccs) { SUnit *SuccDep = D.getSUnit(); D.setSUnit(SU); RemovePred(SuccDep, D); diff --git a/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 5be1892a44f6..81facf92e55a 100644 --- a/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -6858,8 +6858,8 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT, // expanding copies of large vectors from registers. This only works for // fixed length vectors, since we need to know the exact number of // elements. - if (N2C && N1.getOperand(0).getValueType().isFixedLengthVector() && - N1.getOpcode() == ISD::CONCAT_VECTORS && N1.getNumOperands() > 0) { + if (N2C && N1.getOpcode() == ISD::CONCAT_VECTORS && + N1.getOperand(0).getValueType().isFixedLengthVector()) { unsigned Factor = N1.getOperand(0).getValueType().getVectorNumElements(); return getNode(ISD::EXTRACT_VECTOR_ELT, DL, VT, @@ -6976,7 +6976,7 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT, // EXTRACT_SUBVECTOR of CONCAT_VECTOR can be simplified if the pieces of // the concat have the same type as the extract. - if (N1.getOpcode() == ISD::CONCAT_VECTORS && N1.getNumOperands() > 0 && + if (N1.getOpcode() == ISD::CONCAT_VECTORS && VT == N1.getOperand(0).getValueType()) { unsigned Factor = VT.getVectorMinNumElements(); return N1.getOperand(N2C->getZExtValue() / Factor); diff --git a/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 12ed4a82ee91..3c4b285cb067 100644 --- a/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -10627,8 +10627,7 @@ TargetLowering::LowerCallTo(TargetLowering::CallLoweringInfo &CLI) const { else if (CLI.RetZExt) AssertOp = ISD::AssertZext; unsigned CurReg = 0; - for (unsigned I = 0, E = RetTys.size(); I != E; ++I) { - EVT VT = RetTys[I]; + for (EVT VT : RetTys) { MVT RegisterVT = getRegisterTypeForCallingConv(CLI.RetTy->getContext(), CLI.CallConv, VT); unsigned NumRegs = getNumRegistersForCallingConv(CLI.RetTy->getContext(), diff --git a/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index a1cf4cbbee1b..3dc6e4bbcf46 100644 --- a/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -2786,7 +2786,7 @@ CheckInteger(const unsigned char *MatcherTable, unsigned &MatcherIndex, Val = decodeSignRotatedValue(Val); ConstantSDNode *C = dyn_cast<ConstantSDNode>(N); - return C && C->getSExtValue() == Val; + return C && C->getAPIntValue().trySExtValue() == Val; } LLVM_ATTRIBUTE_ALWAYS_INLINE static bool @@ -3612,12 +3612,24 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch, CurDAG->getTargetConstant(Val, SDLoc(NodeToMatch), VT), nullptr)); continue; } - case OPC_EmitRegister: { - MVT::SimpleValueType VT = - static_cast<MVT::SimpleValueType>(MatcherTable[MatcherIndex++]); + case OPC_EmitRegister: + case OPC_EmitRegisterI32: + case OPC_EmitRegisterI64: { + MVT::SimpleValueType VT; + switch (Opcode) { + case OPC_EmitRegisterI32: + VT = MVT::i32; + break; + case OPC_EmitRegisterI64: + VT = MVT::i64; + break; + default: + VT = static_cast<MVT::SimpleValueType>(MatcherTable[MatcherIndex++]); + break; + } unsigned RegNo = MatcherTable[MatcherIndex++]; - RecordedNodes.push_back(std::pair<SDValue, SDNode*>( - CurDAG->getRegister(RegNo, VT), nullptr)); + RecordedNodes.push_back(std::pair<SDValue, SDNode *>( + CurDAG->getRegister(RegNo, VT), nullptr)); continue; } case OPC_EmitRegister2: { diff --git a/contrib/llvm-project/llvm/lib/CodeGen/ShadowStackGCLowering.cpp b/contrib/llvm-project/llvm/lib/CodeGen/ShadowStackGCLowering.cpp index 38f658084294..d4840d117110 100644 --- a/contrib/llvm-project/llvm/lib/CodeGen/ShadowStackGCLowering.cpp +++ b/contrib/llvm-project/llvm/lib/CodeGen/ShadowStackGCLowering.cpp @@ -115,7 +115,7 @@ Constant *ShadowStackGCLowering::GetFrameMap(Function &F) { Constant *C = cast<Constant>(Roots[I].first->getArgOperand(1)); if (!C->isNullValue()) NumMeta = I + 1; - Metadata.push_back(ConstantExpr::getBitCast(C, VoidPtr)); + Metadata.push_back(C); } Metadata.resize(NumMeta); @@ -173,7 +173,7 @@ Type *ShadowStackGCLowering::GetConcreteStackEntryType(Function &F) { bool ShadowStackGCLowering::doInitialization(Module &M) { bool Active = false; for (Function &F : M) { - if (F.hasGC() && F.getGC() == std::string("shadow-stack")) { + if (F.hasGC() && F.getGC() == "shadow-stack") { Active = true; break; } @@ -292,8 +292,7 @@ void ShadowStackGCLowering::getAnalysisUsage(AnalysisUsage &AU) const { /// runOnFunction - Insert code to maintain the shadow stack. bool ShadowStackGCLowering::runOnFunction(Function &F) { // Quick exit for functions that do not use the shadow stack GC. - if (!F.hasGC() || - F.getGC() != std::string("shadow-stack")) + if (!F.hasGC() || F.getGC() != "shadow-stack") return false; LLVMContext &Context = F.getContext(); diff --git a/contrib/llvm-project/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/contrib/llvm-project/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index 9a0dd92bb58e..6e69dc66429d 100644 --- a/contrib/llvm-project/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/contrib/llvm-project/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -2681,6 +2681,13 @@ MCSection *TargetLoweringObjectFileGOFF::getExplicitSectionGlobal( return SelectSectionForGlobal(GO, Kind, TM); } +MCSection *TargetLoweringObjectFileGOFF::getSectionForLSDA( + const Function &F, const MCSymbol &FnSym, const TargetMachine &TM) const { + std::string Name = ".gcc_exception_table." + F.getName().str(); + return getContext().getGOFFSection(Name, SectionKind::getData(), nullptr, + nullptr); +} + MCSection *TargetLoweringObjectFileGOFF::SelectSectionForGlobal( const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { auto *Symbol = TM.getSymbol(GO); diff --git a/contrib/llvm-project/llvm/lib/CodeGen/TargetPassConfig.cpp b/contrib/llvm-project/llvm/lib/CodeGen/TargetPassConfig.cpp index faa5466b69e8..4003a08a5422 100644 --- a/contrib/llvm-project/llvm/lib/CodeGen/TargetPassConfig.cpp +++ b/contrib/llvm-project/llvm/lib/CodeGen/TargetPassConfig.cpp @@ -947,6 +947,7 @@ void TargetPassConfig::addPassesToHandleExceptions() { case ExceptionHandling::DwarfCFI: case ExceptionHandling::ARM: case ExceptionHandling::AIX: + case ExceptionHandling::ZOS: addPass(createDwarfEHPass(getOptLevel())); break; case ExceptionHandling::WinEH: diff --git a/contrib/llvm-project/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp b/contrib/llvm-project/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp index bf689dbd308f..526cb847e8a0 100644 --- a/contrib/llvm-project/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp +++ b/contrib/llvm-project/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp @@ -1124,8 +1124,7 @@ bool TwoAddressInstructionPass::rescheduleKillAboveMI( } } - for (unsigned i = 0, e = OtherDefs.size(); i != e; ++i) { - Register MOReg = OtherDefs[i]; + for (Register MOReg : OtherDefs) { if (regOverlapsSet(Uses, MOReg)) return false; if (MOReg.isPhysical() && regOverlapsSet(LiveDefs, MOReg)) |
