diff options
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 27 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h | 10 | ||||
-rw-r--r-- | llvm/lib/CodeGen/CodeGenPrepare.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/CodeGen/MIRSampleProfile.cpp | 5 | ||||
-rw-r--r-- | llvm/lib/CodeGen/MachineBlockPlacement.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/CodeGen/MachineBranchProbabilityInfo.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/CodeGen/ReachingDefAnalysis.cpp | 144 | ||||
-rw-r--r-- | llvm/lib/CodeGen/RegAllocGreedy.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/CodeGen/RegisterCoalescer.cpp | 75 | ||||
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 8 | ||||
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp | 25 | ||||
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp | 6 | ||||
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp | 6 |
14 files changed, 179 insertions, 136 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 7bd3fb3..3ba4590 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -3914,21 +3914,22 @@ static void emitGlobalConstantImpl(const DataLayout &DL, const Constant *CV, if (isa<ConstantAggregateZero>(CV)) { StructType *structType; if (AliasList && (structType = llvm::dyn_cast<StructType>(CV->getType()))) { - // Handle cases of aliases to direct struct elements - const StructLayout *Layout = DL.getStructLayout(structType); - uint64_t SizeSoFar = 0; - for (unsigned int i = 0, n = structType->getNumElements(); i < n - 1; - ++i) { - uint64_t GapToNext = Layout->getElementOffset(i + 1) - SizeSoFar; - AP.OutStreamer->emitZeros(GapToNext); - SizeSoFar += GapToNext; - emitGlobalAliasInline(AP, Offset + SizeSoFar, AliasList); + unsigned numElements = {structType->getNumElements()}; + if (numElements != 0) { + // Handle cases of aliases to direct struct elements + const StructLayout *Layout = DL.getStructLayout(structType); + uint64_t SizeSoFar = 0; + for (unsigned int i = 0; i < numElements - 1; ++i) { + uint64_t GapToNext = Layout->getElementOffset(i + 1) - SizeSoFar; + AP.OutStreamer->emitZeros(GapToNext); + SizeSoFar += GapToNext; + emitGlobalAliasInline(AP, Offset + SizeSoFar, AliasList); + } + AP.OutStreamer->emitZeros(Size - SizeSoFar); + return; } - AP.OutStreamer->emitZeros(Size - SizeSoFar); - return; - } else { - return AP.OutStreamer->emitZeros(Size); } + return AP.OutStreamer->emitZeros(Size); } if (isa<UndefValue>(CV)) diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index e1291e2..11de4b6 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -3789,6 +3789,7 @@ void DwarfDebug::addDwarfTypeUnitType(DwarfCompileUnit &CU, // they depend on addresses, throwing them out and rebuilding them. setCurrentDWARF5AccelTable(DWARF5AccelTableKind::CU); CU.constructTypeDIE(RefDie, cast<DICompositeType>(CTy)); + CU.updateAcceleratorTables(CTy->getScope(), CTy, RefDie); return; } diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h index 0225654..1632053 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h @@ -315,6 +315,11 @@ public: /// Get context owner's DIE. DIE *createTypeDIE(const DICompositeType *Ty); + /// If this is a named finished type then include it in the list of types for + /// the accelerator tables. + void updateAcceleratorTables(const DIScope *Context, const DIType *Ty, + const DIE &TyDIE); + protected: ~DwarfUnit(); @@ -357,11 +362,6 @@ private: virtual void finishNonUnitTypeDIE(DIE& D, const DICompositeType *CTy) = 0; - /// If this is a named finished type then include it in the list of types for - /// the accelerator tables. - void updateAcceleratorTables(const DIScope *Context, const DIType *Ty, - const DIE &TyDIE); - virtual bool isDwoUnit() const = 0; const MCSymbol *getCrossSectionRelativeBaseAddress() const override; diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp index 5c712e4..ba1b10e 100644 --- a/llvm/lib/CodeGen/CodeGenPrepare.cpp +++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp @@ -152,7 +152,7 @@ static cl::opt<bool> static cl::opt<bool> EnableAndCmpSinking("enable-andcmp-sinking", cl::Hidden, cl::init(true), - cl::desc("Enable sinkinig and/cmp into branches.")); + cl::desc("Enable sinking and/cmp into branches.")); static cl::opt<bool> DisableStoreExtract( "disable-cgp-store-extract", cl::Hidden, cl::init(false), diff --git a/llvm/lib/CodeGen/MIRSampleProfile.cpp b/llvm/lib/CodeGen/MIRSampleProfile.cpp index 23db09b..9bba50e8 100644 --- a/llvm/lib/CodeGen/MIRSampleProfile.cpp +++ b/llvm/lib/CodeGen/MIRSampleProfile.cpp @@ -46,8 +46,9 @@ static cl::opt<bool> ShowFSBranchProb( cl::desc("Print setting flow sensitive branch probabilities")); static cl::opt<unsigned> FSProfileDebugProbDiffThreshold( "fs-profile-debug-prob-diff-threshold", cl::init(10), - cl::desc("Only show debug message if the branch probility is greater than " - "this value (in percentage).")); + cl::desc( + "Only show debug message if the branch probability is greater than " + "this value (in percentage).")); static cl::opt<unsigned> FSProfileDebugBWThreshold( "fs-profile-debug-bw-threshold", cl::init(10000), diff --git a/llvm/lib/CodeGen/MachineBlockPlacement.cpp b/llvm/lib/CodeGen/MachineBlockPlacement.cpp index 0f68313..05bc4cf 100644 --- a/llvm/lib/CodeGen/MachineBlockPlacement.cpp +++ b/llvm/lib/CodeGen/MachineBlockPlacement.cpp @@ -149,7 +149,7 @@ static cl::opt<unsigned> JumpInstCost("jump-inst-cost", static cl::opt<bool> TailDupPlacement("tail-dup-placement", cl::desc("Perform tail duplication during placement. " - "Creates more fallthrough opportunites in " + "Creates more fallthrough opportunities in " "outline branches."), cl::init(true), cl::Hidden); diff --git a/llvm/lib/CodeGen/MachineBranchProbabilityInfo.cpp b/llvm/lib/CodeGen/MachineBranchProbabilityInfo.cpp index 56fffff..2e92dd8 100644 --- a/llvm/lib/CodeGen/MachineBranchProbabilityInfo.cpp +++ b/llvm/lib/CodeGen/MachineBranchProbabilityInfo.cpp @@ -29,7 +29,7 @@ namespace llvm { cl::opt<unsigned> StaticLikelyProb("static-likely-prob", cl::desc("branch probability threshold in percentage" - "to be considered very likely"), + " to be considered very likely"), cl::init(80), cl::Hidden); cl::opt<unsigned> ProfileLikelyProb( diff --git a/llvm/lib/CodeGen/ReachingDefAnalysis.cpp b/llvm/lib/CodeGen/ReachingDefAnalysis.cpp index 79b0fa6..3ab6315 100644 --- a/llvm/lib/CodeGen/ReachingDefAnalysis.cpp +++ b/llvm/lib/CodeGen/ReachingDefAnalysis.cpp @@ -30,22 +30,22 @@ static bool isValidRegUse(const MachineOperand &MO) { return isValidReg(MO) && MO.isUse(); } -static bool isValidRegUseOf(const MachineOperand &MO, MCRegister PhysReg, +static bool isValidRegUseOf(const MachineOperand &MO, MCRegister Reg, const TargetRegisterInfo *TRI) { if (!isValidRegUse(MO)) return false; - return TRI->regsOverlap(MO.getReg(), PhysReg); + return TRI->regsOverlap(MO.getReg(), Reg); } static bool isValidRegDef(const MachineOperand &MO) { return isValidReg(MO) && MO.isDef(); } -static bool isValidRegDefOf(const MachineOperand &MO, MCRegister PhysReg, +static bool isValidRegDefOf(const MachineOperand &MO, MCRegister Reg, const TargetRegisterInfo *TRI) { if (!isValidRegDef(MO)) return false; - return TRI->regsOverlap(MO.getReg(), PhysReg); + return TRI->regsOverlap(MO.getReg(), Reg); } void ReachingDefAnalysis::enterBasicBlock(MachineBasicBlock *MBB) { @@ -261,7 +261,7 @@ void ReachingDefAnalysis::traverse() { } int ReachingDefAnalysis::getReachingDef(MachineInstr *MI, - MCRegister PhysReg) const { + MCRegister Reg) const { assert(InstIds.count(MI) && "Unexpected machine instuction."); int InstId = InstIds.lookup(MI); int DefRes = ReachingDefDefaultVal; @@ -269,7 +269,7 @@ int ReachingDefAnalysis::getReachingDef(MachineInstr *MI, assert(MBBNumber < MBBReachingDefs.numBlockIDs() && "Unexpected basic block number."); int LatestDef = ReachingDefDefaultVal; - for (MCRegUnit Unit : TRI->regunits(PhysReg)) { + for (MCRegUnit Unit : TRI->regunits(Reg)) { for (int Def : MBBReachingDefs.defs(MBBNumber, Unit)) { if (Def >= InstId) break; @@ -280,22 +280,21 @@ int ReachingDefAnalysis::getReachingDef(MachineInstr *MI, return LatestDef; } -MachineInstr * -ReachingDefAnalysis::getReachingLocalMIDef(MachineInstr *MI, - MCRegister PhysReg) const { - return hasLocalDefBefore(MI, PhysReg) - ? getInstFromId(MI->getParent(), getReachingDef(MI, PhysReg)) - : nullptr; +MachineInstr *ReachingDefAnalysis::getReachingLocalMIDef(MachineInstr *MI, + MCRegister Reg) const { + return hasLocalDefBefore(MI, Reg) + ? getInstFromId(MI->getParent(), getReachingDef(MI, Reg)) + : nullptr; } bool ReachingDefAnalysis::hasSameReachingDef(MachineInstr *A, MachineInstr *B, - MCRegister PhysReg) const { + MCRegister Reg) const { MachineBasicBlock *ParentA = A->getParent(); MachineBasicBlock *ParentB = B->getParent(); if (ParentA != ParentB) return false; - return getReachingDef(A, PhysReg) == getReachingDef(B, PhysReg); + return getReachingDef(A, Reg) == getReachingDef(B, Reg); } MachineInstr *ReachingDefAnalysis::getInstFromId(MachineBasicBlock *MBB, @@ -318,19 +317,18 @@ MachineInstr *ReachingDefAnalysis::getInstFromId(MachineBasicBlock *MBB, return nullptr; } -int ReachingDefAnalysis::getClearance(MachineInstr *MI, - MCRegister PhysReg) const { +int ReachingDefAnalysis::getClearance(MachineInstr *MI, MCRegister Reg) const { assert(InstIds.count(MI) && "Unexpected machine instuction."); - return InstIds.lookup(MI) - getReachingDef(MI, PhysReg); + return InstIds.lookup(MI) - getReachingDef(MI, Reg); } bool ReachingDefAnalysis::hasLocalDefBefore(MachineInstr *MI, - MCRegister PhysReg) const { - return getReachingDef(MI, PhysReg) >= 0; + MCRegister Reg) const { + return getReachingDef(MI, Reg) >= 0; } void ReachingDefAnalysis::getReachingLocalUses(MachineInstr *Def, - MCRegister PhysReg, + MCRegister Reg, InstSet &Uses) const { MachineBasicBlock *MBB = Def->getParent(); MachineBasicBlock::iterator MI = MachineBasicBlock::iterator(Def); @@ -340,11 +338,11 @@ void ReachingDefAnalysis::getReachingLocalUses(MachineInstr *Def, // If/when we find a new reaching def, we know that there's no more uses // of 'Def'. - if (getReachingLocalMIDef(&*MI, PhysReg) != Def) + if (getReachingLocalMIDef(&*MI, Reg) != Def) return; for (auto &MO : MI->operands()) { - if (!isValidRegUseOf(MO, PhysReg, TRI)) + if (!isValidRegUseOf(MO, Reg, TRI)) continue; Uses.insert(&*MI); @@ -354,15 +352,14 @@ void ReachingDefAnalysis::getReachingLocalUses(MachineInstr *Def, } } -bool ReachingDefAnalysis::getLiveInUses(MachineBasicBlock *MBB, - MCRegister PhysReg, +bool ReachingDefAnalysis::getLiveInUses(MachineBasicBlock *MBB, MCRegister Reg, InstSet &Uses) const { for (MachineInstr &MI : instructionsWithoutDebug(MBB->instr_begin(), MBB->instr_end())) { for (auto &MO : MI.operands()) { - if (!isValidRegUseOf(MO, PhysReg, TRI)) + if (!isValidRegUseOf(MO, Reg, TRI)) continue; - if (getReachingDef(&MI, PhysReg) >= 0) + if (getReachingDef(&MI, Reg) >= 0) return false; Uses.insert(&MI); } @@ -370,18 +367,18 @@ bool ReachingDefAnalysis::getLiveInUses(MachineBasicBlock *MBB, auto Last = MBB->getLastNonDebugInstr(); if (Last == MBB->end()) return true; - return isReachingDefLiveOut(&*Last, PhysReg); + return isReachingDefLiveOut(&*Last, Reg); } -void ReachingDefAnalysis::getGlobalUses(MachineInstr *MI, MCRegister PhysReg, +void ReachingDefAnalysis::getGlobalUses(MachineInstr *MI, MCRegister Reg, InstSet &Uses) const { MachineBasicBlock *MBB = MI->getParent(); // Collect the uses that each def touches within the block. - getReachingLocalUses(MI, PhysReg, Uses); + getReachingLocalUses(MI, Reg, Uses); // Handle live-out values. - if (auto *LiveOut = getLocalLiveOutMIDef(MI->getParent(), PhysReg)) { + if (auto *LiveOut = getLocalLiveOutMIDef(MI->getParent(), Reg)) { if (LiveOut != MI) return; @@ -389,9 +386,9 @@ void ReachingDefAnalysis::getGlobalUses(MachineInstr *MI, MCRegister PhysReg, SmallPtrSet<MachineBasicBlock*, 4>Visited; while (!ToVisit.empty()) { MachineBasicBlock *MBB = ToVisit.pop_back_val(); - if (Visited.count(MBB) || !MBB->isLiveIn(PhysReg)) + if (Visited.count(MBB) || !MBB->isLiveIn(Reg)) continue; - if (getLiveInUses(MBB, PhysReg, Uses)) + if (getLiveInUses(MBB, Reg, Uses)) llvm::append_range(ToVisit, MBB->successors()); Visited.insert(MBB); } @@ -399,25 +396,25 @@ void ReachingDefAnalysis::getGlobalUses(MachineInstr *MI, MCRegister PhysReg, } void ReachingDefAnalysis::getGlobalReachingDefs(MachineInstr *MI, - MCRegister PhysReg, + MCRegister Reg, InstSet &Defs) const { - if (auto *Def = getUniqueReachingMIDef(MI, PhysReg)) { + if (auto *Def = getUniqueReachingMIDef(MI, Reg)) { Defs.insert(Def); return; } for (auto *MBB : MI->getParent()->predecessors()) - getLiveOuts(MBB, PhysReg, Defs); + getLiveOuts(MBB, Reg, Defs); } -void ReachingDefAnalysis::getLiveOuts(MachineBasicBlock *MBB, - MCRegister PhysReg, InstSet &Defs) const { +void ReachingDefAnalysis::getLiveOuts(MachineBasicBlock *MBB, MCRegister Reg, + InstSet &Defs) const { SmallPtrSet<MachineBasicBlock*, 2> VisitedBBs; - getLiveOuts(MBB, PhysReg, Defs, VisitedBBs); + getLiveOuts(MBB, Reg, Defs, VisitedBBs); } -void ReachingDefAnalysis::getLiveOuts(MachineBasicBlock *MBB, - MCRegister PhysReg, InstSet &Defs, +void ReachingDefAnalysis::getLiveOuts(MachineBasicBlock *MBB, MCRegister Reg, + InstSet &Defs, BlockSet &VisitedBBs) const { if (VisitedBBs.count(MBB)) return; @@ -425,28 +422,28 @@ void ReachingDefAnalysis::getLiveOuts(MachineBasicBlock *MBB, VisitedBBs.insert(MBB); LiveRegUnits LiveRegs(*TRI); LiveRegs.addLiveOuts(*MBB); - if (LiveRegs.available(PhysReg)) + if (LiveRegs.available(Reg)) return; - if (auto *Def = getLocalLiveOutMIDef(MBB, PhysReg)) + if (auto *Def = getLocalLiveOutMIDef(MBB, Reg)) Defs.insert(Def); else for (auto *Pred : MBB->predecessors()) - getLiveOuts(Pred, PhysReg, Defs, VisitedBBs); + getLiveOuts(Pred, Reg, Defs, VisitedBBs); } MachineInstr * ReachingDefAnalysis::getUniqueReachingMIDef(MachineInstr *MI, - MCRegister PhysReg) const { + MCRegister Reg) const { // If there's a local def before MI, return it. - MachineInstr *LocalDef = getReachingLocalMIDef(MI, PhysReg); + MachineInstr *LocalDef = getReachingLocalMIDef(MI, Reg); if (LocalDef && InstIds.lookup(LocalDef) < InstIds.lookup(MI)) return LocalDef; SmallPtrSet<MachineInstr*, 2> Incoming; MachineBasicBlock *Parent = MI->getParent(); for (auto *Pred : Parent->predecessors()) - getLiveOuts(Pred, PhysReg, Incoming); + getLiveOuts(Pred, Reg, Incoming); // Check that we have a single incoming value and that it does not // come from the same block as MI - since it would mean that the def @@ -469,13 +466,13 @@ MachineInstr *ReachingDefAnalysis::getMIOperand(MachineInstr *MI, } bool ReachingDefAnalysis::isRegUsedAfter(MachineInstr *MI, - MCRegister PhysReg) const { + MCRegister Reg) const { MachineBasicBlock *MBB = MI->getParent(); LiveRegUnits LiveRegs(*TRI); LiveRegs.addLiveOuts(*MBB); // Yes if the register is live out of the basic block. - if (!LiveRegs.available(PhysReg)) + if (!LiveRegs.available(Reg)) return true; // Walk backwards through the block to see if the register is live at some @@ -483,62 +480,61 @@ bool ReachingDefAnalysis::isRegUsedAfter(MachineInstr *MI, for (MachineInstr &Last : instructionsWithoutDebug(MBB->instr_rbegin(), MBB->instr_rend())) { LiveRegs.stepBackward(Last); - if (!LiveRegs.available(PhysReg)) + if (!LiveRegs.available(Reg)) return InstIds.lookup(&Last) > InstIds.lookup(MI); } return false; } bool ReachingDefAnalysis::isRegDefinedAfter(MachineInstr *MI, - MCRegister PhysReg) const { + MCRegister Reg) const { MachineBasicBlock *MBB = MI->getParent(); auto Last = MBB->getLastNonDebugInstr(); if (Last != MBB->end() && - getReachingDef(MI, PhysReg) != getReachingDef(&*Last, PhysReg)) + getReachingDef(MI, Reg) != getReachingDef(&*Last, Reg)) return true; - if (auto *Def = getLocalLiveOutMIDef(MBB, PhysReg)) - return Def == getReachingLocalMIDef(MI, PhysReg); + if (auto *Def = getLocalLiveOutMIDef(MBB, Reg)) + return Def == getReachingLocalMIDef(MI, Reg); return false; } bool ReachingDefAnalysis::isReachingDefLiveOut(MachineInstr *MI, - MCRegister PhysReg) const { + MCRegister Reg) const { MachineBasicBlock *MBB = MI->getParent(); LiveRegUnits LiveRegs(*TRI); LiveRegs.addLiveOuts(*MBB); - if (LiveRegs.available(PhysReg)) + if (LiveRegs.available(Reg)) return false; auto Last = MBB->getLastNonDebugInstr(); - int Def = getReachingDef(MI, PhysReg); - if (Last != MBB->end() && getReachingDef(&*Last, PhysReg) != Def) + int Def = getReachingDef(MI, Reg); + if (Last != MBB->end() && getReachingDef(&*Last, Reg) != Def) return false; // Finally check that the last instruction doesn't redefine the register. for (auto &MO : Last->operands()) - if (isValidRegDefOf(MO, PhysReg, TRI)) + if (isValidRegDefOf(MO, Reg, TRI)) return false; return true; } -MachineInstr * -ReachingDefAnalysis::getLocalLiveOutMIDef(MachineBasicBlock *MBB, - MCRegister PhysReg) const { +MachineInstr *ReachingDefAnalysis::getLocalLiveOutMIDef(MachineBasicBlock *MBB, + MCRegister Reg) const { LiveRegUnits LiveRegs(*TRI); LiveRegs.addLiveOuts(*MBB); - if (LiveRegs.available(PhysReg)) + if (LiveRegs.available(Reg)) return nullptr; auto Last = MBB->getLastNonDebugInstr(); if (Last == MBB->end()) return nullptr; - int Def = getReachingDef(&*Last, PhysReg); + int Def = getReachingDef(&*Last, Reg); for (auto &MO : Last->operands()) - if (isValidRegDefOf(MO, PhysReg, TRI)) + if (isValidRegDefOf(MO, Reg, TRI)) return &*Last; return Def < 0 ? nullptr : getInstFromId(MBB, Def); @@ -650,7 +646,7 @@ ReachingDefAnalysis::isSafeToRemove(MachineInstr *MI, InstSet &Visited, void ReachingDefAnalysis::collectKilledOperands(MachineInstr *MI, InstSet &Dead) const { Dead.insert(MI); - auto IsDead = [this, &Dead](MachineInstr *Def, MCRegister PhysReg) { + auto IsDead = [this, &Dead](MachineInstr *Def, MCRegister Reg) { if (mayHaveSideEffects(*Def)) return false; @@ -666,7 +662,7 @@ void ReachingDefAnalysis::collectKilledOperands(MachineInstr *MI, return false; SmallPtrSet<MachineInstr*, 4> Uses; - getGlobalUses(Def, PhysReg, Uses); + getGlobalUses(Def, Reg, Uses); return llvm::set_is_subset(Uses, Dead); }; @@ -680,18 +676,18 @@ void ReachingDefAnalysis::collectKilledOperands(MachineInstr *MI, } bool ReachingDefAnalysis::isSafeToDefRegAt(MachineInstr *MI, - MCRegister PhysReg) const { + MCRegister Reg) const { SmallPtrSet<MachineInstr*, 1> Ignore; - return isSafeToDefRegAt(MI, PhysReg, Ignore); + return isSafeToDefRegAt(MI, Reg, Ignore); } -bool ReachingDefAnalysis::isSafeToDefRegAt(MachineInstr *MI, MCRegister PhysReg, +bool ReachingDefAnalysis::isSafeToDefRegAt(MachineInstr *MI, MCRegister Reg, InstSet &Ignore) const { // Check for any uses of the register after MI. - if (isRegUsedAfter(MI, PhysReg)) { - if (auto *Def = getReachingLocalMIDef(MI, PhysReg)) { + if (isRegUsedAfter(MI, Reg)) { + if (auto *Def = getReachingLocalMIDef(MI, Reg)) { SmallPtrSet<MachineInstr*, 2> Uses; - getGlobalUses(Def, PhysReg, Uses); + getGlobalUses(Def, Reg, Uses); if (!llvm::set_is_subset(Uses, Ignore)) return false; } else @@ -700,13 +696,13 @@ bool ReachingDefAnalysis::isSafeToDefRegAt(MachineInstr *MI, MCRegister PhysReg, MachineBasicBlock *MBB = MI->getParent(); // Check for any defs after MI. - if (isRegDefinedAfter(MI, PhysReg)) { + if (isRegDefinedAfter(MI, Reg)) { auto I = MachineBasicBlock::iterator(MI); for (auto E = MBB->end(); I != E; ++I) { if (Ignore.count(&*I)) continue; for (auto &MO : I->operands()) - if (isValidRegDefOf(MO, PhysReg, TRI)) + if (isValidRegDefOf(MO, Reg, TRI)) return false; } } diff --git a/llvm/lib/CodeGen/RegAllocGreedy.cpp b/llvm/lib/CodeGen/RegAllocGreedy.cpp index e61dad5..b94992c 100644 --- a/llvm/lib/CodeGen/RegAllocGreedy.cpp +++ b/llvm/lib/CodeGen/RegAllocGreedy.cpp @@ -140,7 +140,7 @@ static cl::opt<bool> GreedyReverseLocalAssignment( static cl::opt<unsigned> SplitThresholdForRegWithHint( "split-threshold-for-reg-with-hint", cl::desc("The threshold for splitting a virtual register with a hint, in " - "percentate"), + "percentage"), cl::init(75), cl::Hidden); static RegisterRegAlloc greedyRegAlloc("greedy", "greedy register allocator", diff --git a/llvm/lib/CodeGen/RegisterCoalescer.cpp b/llvm/lib/CodeGen/RegisterCoalescer.cpp index 20ad644..8313927 100644 --- a/llvm/lib/CodeGen/RegisterCoalescer.cpp +++ b/llvm/lib/CodeGen/RegisterCoalescer.cpp @@ -113,7 +113,7 @@ static cl::opt<unsigned> LargeIntervalSizeThreshold( static cl::opt<unsigned> LargeIntervalFreqThreshold( "large-interval-freq-threshold", cl::Hidden, - cl::desc("For a large interval, if it is coalesed with other live " + cl::desc("For a large interval, if it is coalesced with other live " "intervals many times more than the threshold, stop its " "coalescing to control the compile time. "), cl::init(256)); @@ -1325,11 +1325,6 @@ bool RegisterCoalescer::reMaterializeTrivialDef(const CoalescerPair &CP, const MCInstrDesc &MCID = DefMI->getDesc(); if (MCID.getNumDefs() != 1) return false; - // Only support subregister destinations when the def is read-undef. - MachineOperand &DstOperand = CopyMI->getOperand(0); - Register CopyDstReg = DstOperand.getReg(); - if (DstOperand.getSubReg() && !DstOperand.isUndef()) - return false; // If both SrcIdx and DstIdx are set, correct rematerialization would widen // the register substantially (beyond both source and dest size). This is bad @@ -1339,6 +1334,32 @@ bool RegisterCoalescer::reMaterializeTrivialDef(const CoalescerPair &CP, if (SrcIdx && DstIdx) return false; + // Only support subregister destinations when the def is read-undef. + MachineOperand &DstOperand = CopyMI->getOperand(0); + Register CopyDstReg = DstOperand.getReg(); + if (DstOperand.getSubReg() && !DstOperand.isUndef()) + return false; + + // In the physical register case, checking that the def is read-undef is not + // enough. We're widening the def and need to avoid clobbering other live + // values in the unused register pieces. + // + // TODO: Targets may support rewriting the rematerialized instruction to only + // touch relevant lanes, in which case we don't need any liveness check. + if (CopyDstReg.isPhysical() && CP.isPartial()) { + for (MCRegUnit Unit : TRI->regunits(DstReg)) { + // Ignore the register units we are writing anyway. + if (is_contained(TRI->regunits(CopyDstReg), Unit)) + continue; + + // Check if the other lanes we are defining are live at the + // rematerialization point. + LiveRange &LR = LIS->getRegUnit(Unit); + if (LR.liveAt(CopyIdx)) + return false; + } + } + const unsigned DefSubIdx = DefMI->getOperand(0).getSubReg(); const TargetRegisterClass *DefRC = TII->getRegClass(MCID, 0, TRI, *MF); if (!DefMI->isImplicitDef()) { @@ -1375,27 +1396,6 @@ bool RegisterCoalescer::reMaterializeTrivialDef(const CoalescerPair &CP, NewMI.setDebugLoc(DL); // In a situation like the following: - // - // undef %2.subreg:reg = INST %1:reg ; DefMI (rematerializable), - // ; DefSubIdx = subreg - // %3:reg = COPY %2 ; SrcIdx = DstIdx = 0 - // .... = SOMEINSTR %3:reg - // - // there are no subranges for %3 so after rematerialization we need - // to explicitly create them. Undefined subranges are removed later on. - if (DstReg.isVirtual() && DefSubIdx && !CP.getSrcIdx() && !CP.getDstIdx() && - MRI->shouldTrackSubRegLiveness(DstReg)) { - LiveInterval &DstInt = LIS->getInterval(DstReg); - if (!DstInt.hasSubRanges()) { - LaneBitmask FullMask = MRI->getMaxLaneMaskForVReg(DstReg); - LaneBitmask UsedLanes = TRI->getSubRegIndexLaneMask(DefSubIdx); - LaneBitmask UnusedLanes = FullMask & ~UsedLanes; - DstInt.createSubRangeFrom(LIS->getVNInfoAllocator(), UsedLanes, DstInt); - DstInt.createSubRangeFrom(LIS->getVNInfoAllocator(), UnusedLanes, DstInt); - } - } - - // In a situation like the following: // %0:subreg = instr ; DefMI, subreg = DstIdx // %1 = copy %0:subreg ; CopyMI, SrcIdx = 0 // instead of widening %1 to the register class of %0 simply do: @@ -1523,6 +1523,27 @@ bool RegisterCoalescer::reMaterializeTrivialDef(const CoalescerPair &CP, // sure that "undef" is not set. if (NewIdx == 0) NewMI.getOperand(0).setIsUndef(false); + + // In a situation like the following: + // + // undef %2.subreg:reg = INST %1:reg ; DefMI (rematerializable), + // ; Defines only some of lanes, + // ; so DefSubIdx = NewIdx = subreg + // %3:reg = COPY %2 ; Copy full reg + // .... = SOMEINSTR %3:reg ; Use full reg + // + // there are no subranges for %3 so after rematerialization we need + // to explicitly create them. Undefined subranges are removed later on. + if (NewIdx && !DstInt.hasSubRanges() && + MRI->shouldTrackSubRegLiveness(DstReg)) { + LaneBitmask FullMask = MRI->getMaxLaneMaskForVReg(DstReg); + LaneBitmask UsedLanes = TRI->getSubRegIndexLaneMask(NewIdx); + LaneBitmask UnusedLanes = FullMask & ~UsedLanes; + VNInfo::Allocator &Alloc = LIS->getVNInfoAllocator(); + DstInt.createSubRangeFrom(Alloc, UsedLanes, DstInt); + DstInt.createSubRangeFrom(Alloc, UnusedLanes, DstInt); + } + // Add dead subregister definitions if we are defining the whole register // but only part of it is live. // This could happen if the rematerialization instruction is rematerializing diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index e89e7ef..da3c834 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -141,7 +141,7 @@ static cl::opt<bool> EnableReduceLoadOpStoreWidth( static cl::opt<bool> ReduceLoadOpStoreWidthForceNarrowingProfitable( "combiner-reduce-load-op-store-width-force-narrowing-profitable", cl::Hidden, cl::init(false), - cl::desc("DAG combiner force override the narrowing profitable check when" + cl::desc("DAG combiner force override the narrowing profitable check when " "reducing the width of load/op/store sequences")); static cl::opt<bool> EnableShrinkLoadReplaceStoreWithStore( @@ -20455,10 +20455,8 @@ SDValue DAGCombiner::TransformFPLoadStorePair(SDNode *N) { Value.hasOneUse()) { LoadSDNode *LD = cast<LoadSDNode>(Value); EVT VT = LD->getMemoryVT(); - if (!VT.isFloatingPoint() || - VT != ST->getMemoryVT() || - LD->isNonTemporal() || - ST->isNonTemporal() || + if (!VT.isSimple() || !VT.isFloatingPoint() || VT != ST->getMemoryVT() || + LD->isNonTemporal() || ST->isNonTemporal() || LD->getPointerInfo().getAddrSpace() != 0 || ST->getPointerInfo().getAddrSpace() != 0) return SDValue(); diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp index e8404a1..89a00c5 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp @@ -1777,6 +1777,31 @@ void VectorLegalizer::ExpandUINT_TO_FLOAT(SDNode *Node, assert((BW == 64 || BW == 32) && "Elements in vector-UINT_TO_FP must be 32 or 64 bits wide"); + // If STRICT_/FMUL is not supported by the target (in case of f16) replace the + // UINT_TO_FP with a larger float and round to the smaller type + if ((!IsStrict && !TLI.isOperationLegalOrCustom(ISD::FMUL, DstVT)) || + (IsStrict && !TLI.isOperationLegalOrCustom(ISD::STRICT_FMUL, DstVT))) { + EVT FPVT = BW == 32 ? MVT::f32 : MVT::f64; + SDValue UIToFP; + SDValue Result; + SDValue TargetZero = DAG.getIntPtrConstant(0, DL, /*isTarget=*/true); + EVT FloatVecVT = SrcVT.changeVectorElementType(FPVT); + if (IsStrict) { + UIToFP = DAG.getNode(ISD::STRICT_UINT_TO_FP, DL, {FloatVecVT, MVT::Other}, + {Node->getOperand(0), Src}); + Result = DAG.getNode(ISD::STRICT_FP_ROUND, DL, {DstVT, MVT::Other}, + {Node->getOperand(0), UIToFP, TargetZero}); + Results.push_back(Result); + Results.push_back(Result.getValue(1)); + } else { + UIToFP = DAG.getNode(ISD::UINT_TO_FP, DL, FloatVecVT, Src); + Result = DAG.getNode(ISD::FP_ROUND, DL, DstVT, UIToFP, TargetZero); + Results.push_back(Result); + } + + return; + } + SDValue HalfWord = DAG.getConstant(BW / 2, DL, SrcVT); // Constants to clear the upper part of the word. diff --git a/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp b/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp index 9e5867c..51ee3cc 100644 --- a/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp @@ -125,9 +125,9 @@ static cl::opt<int> MaxReorderWindow( cl::desc("Number of instructions to allow ahead of the critical path " "in sched=list-ilp")); -static cl::opt<unsigned> AvgIPC( - "sched-avg-ipc", cl::Hidden, cl::init(1), - cl::desc("Average inst/cycle whan no target itinerary exists.")); +static cl::opt<unsigned> + AvgIPC("sched-avg-ipc", cl::Hidden, cl::init(1), + cl::desc("Average inst/cycle when no target itinerary exists.")); namespace { diff --git a/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp b/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp index 26fc75c..dff7243 100644 --- a/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp @@ -43,9 +43,9 @@ STATISTIC(LoadsClustered, "Number of loads clustered together"); // without a target itinerary. The choice of number here has more to do with // balancing scheduler heuristics than with the actual machine latency. static cl::opt<int> HighLatencyCycles( - "sched-high-latency-cycles", cl::Hidden, cl::init(10), - cl::desc("Roughly estimate the number of cycles that 'long latency'" - "instructions take for targets with no itinerary")); + "sched-high-latency-cycles", cl::Hidden, cl::init(10), + cl::desc("Roughly estimate the number of cycles that 'long latency' " + "instructions take for targets with no itinerary")); ScheduleDAGSDNodes::ScheduleDAGSDNodes(MachineFunction &mf) : ScheduleDAG(mf), InstrItins(mf.getSubtarget().getInstrItineraryData()) {} |