diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2023-12-18 20:30:12 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2024-04-06 20:11:55 +0000 |
| commit | 5f757f3ff9144b609b3c433dfd370cc6bdc191ad (patch) | |
| tree | 1b4e980b866cd26a00af34c0a653eb640bd09caf /contrib/llvm-project/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp | |
| parent | 3e1c8a35f741a5d114d0ba670b15191355711fe9 (diff) | |
| parent | 312c0ed19cc5276a17bacf2120097bec4515b0f1 (diff) | |
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp')
| -rw-r--r-- | contrib/llvm-project/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp | 157 |
1 files changed, 122 insertions, 35 deletions
diff --git a/contrib/llvm-project/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp b/contrib/llvm-project/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp index f06ea89cc61d..8b5a6d618412 100644 --- a/contrib/llvm-project/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp +++ b/contrib/llvm-project/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp @@ -194,7 +194,7 @@ bool llvm::MergeBlockIntoPredecessor(BasicBlock *BB, DomTreeUpdater *DTU, // Don't break unwinding instructions or terminators with other side-effects. Instruction *PTI = PredBB->getTerminator(); - if (PTI->isExceptionalTerminator() || PTI->mayHaveSideEffects()) + if (PTI->isSpecialTerminator() || PTI->mayHaveSideEffects()) return false; // Can't merge if there are multiple distinct successors. @@ -300,7 +300,7 @@ bool llvm::MergeBlockIntoPredecessor(BasicBlock *BB, DomTreeUpdater *DTU, PredBB->back().eraseFromParent(); // Move terminator instruction. - PredBB->splice(PredBB->end(), BB); + BB->back().moveBeforePreserving(*PredBB, PredBB->end()); // Terminator may be a memory accessing instruction too. if (MSSAU) @@ -382,7 +382,51 @@ bool llvm::MergeBlockSuccessorsIntoGivenBlocks( /// - Check fully overlapping fragments and not only identical fragments. /// - Support dbg.declare. dbg.label, and possibly other meta instructions being /// part of the sequence of consecutive instructions. +static bool DPValuesRemoveRedundantDbgInstrsUsingBackwardScan(BasicBlock *BB) { + SmallVector<DPValue *, 8> ToBeRemoved; + SmallDenseSet<DebugVariable> VariableSet; + for (auto &I : reverse(*BB)) { + for (DPValue &DPV : reverse(I.getDbgValueRange())) { + // Skip declare-type records, as the debug intrinsic method only works + // on dbg.value intrinsics. + if (DPV.getType() == DPValue::LocationType::Declare) { + // The debug intrinsic method treats dbg.declares are "non-debug" + // instructions (i.e., a break in a consecutive range of debug + // intrinsics). Emulate that to create identical outputs. See + // "Possible improvements" above. + // FIXME: Delete the line below. + VariableSet.clear(); + continue; + } + + DebugVariable Key(DPV.getVariable(), DPV.getExpression(), + DPV.getDebugLoc()->getInlinedAt()); + auto R = VariableSet.insert(Key); + // If the same variable fragment is described more than once it is enough + // to keep the last one (i.e. the first found since we for reverse + // iteration). + // FIXME: add assignment tracking support (see parallel implementation + // below). + if (!R.second) + ToBeRemoved.push_back(&DPV); + continue; + } + // Sequence with consecutive dbg.value instrs ended. Clear the map to + // restart identifying redundant instructions if case we find another + // dbg.value sequence. + VariableSet.clear(); + } + + for (auto &DPV : ToBeRemoved) + DPV->eraseFromParent(); + + return !ToBeRemoved.empty(); +} + static bool removeRedundantDbgInstrsUsingBackwardScan(BasicBlock *BB) { + if (BB->IsNewDbgInfoFormat) + return DPValuesRemoveRedundantDbgInstrsUsingBackwardScan(BB); + SmallVector<DbgValueInst *, 8> ToBeRemoved; SmallDenseSet<DebugVariable> VariableSet; for (auto &I : reverse(*BB)) { @@ -440,7 +484,40 @@ static bool removeRedundantDbgInstrsUsingBackwardScan(BasicBlock *BB) { /// /// Possible improvements: /// - Keep track of non-overlapping fragments. +static bool DPValuesRemoveRedundantDbgInstrsUsingForwardScan(BasicBlock *BB) { + SmallVector<DPValue *, 8> ToBeRemoved; + DenseMap<DebugVariable, std::pair<SmallVector<Value *, 4>, DIExpression *>> + VariableMap; + for (auto &I : *BB) { + for (DPValue &DPV : I.getDbgValueRange()) { + if (DPV.getType() == DPValue::LocationType::Declare) + continue; + DebugVariable Key(DPV.getVariable(), std::nullopt, + DPV.getDebugLoc()->getInlinedAt()); + auto VMI = VariableMap.find(Key); + // Update the map if we found a new value/expression describing the + // variable, or if the variable wasn't mapped already. + SmallVector<Value *, 4> Values(DPV.location_ops()); + if (VMI == VariableMap.end() || VMI->second.first != Values || + VMI->second.second != DPV.getExpression()) { + VariableMap[Key] = {Values, DPV.getExpression()}; + continue; + } + // Found an identical mapping. Remember the instruction for later removal. + ToBeRemoved.push_back(&DPV); + } + } + + for (auto *DPV : ToBeRemoved) + DPV->eraseFromParent(); + + return !ToBeRemoved.empty(); +} + static bool removeRedundantDbgInstrsUsingForwardScan(BasicBlock *BB) { + if (BB->IsNewDbgInfoFormat) + return DPValuesRemoveRedundantDbgInstrsUsingForwardScan(BB); + SmallVector<DbgValueInst *, 8> ToBeRemoved; DenseMap<DebugVariable, std::pair<SmallVector<Value *, 4>, DIExpression *>> VariableMap; @@ -852,9 +929,11 @@ void llvm::createPHIsForSplitLoopExit(ArrayRef<BasicBlock *> Preds, continue; // Otherwise a new PHI is needed. Create one and populate it. - PHINode *NewPN = PHINode::Create( - PN.getType(), Preds.size(), "split", - SplitBB->isLandingPad() ? &SplitBB->front() : SplitBB->getTerminator()); + PHINode *NewPN = PHINode::Create(PN.getType(), Preds.size(), "split"); + BasicBlock::iterator InsertPos = + SplitBB->isLandingPad() ? SplitBB->begin() + : SplitBB->getTerminator()->getIterator(); + NewPN->insertBefore(InsertPos); for (BasicBlock *BB : Preds) NewPN->addIncoming(V, BB); @@ -877,7 +956,7 @@ llvm::SplitAllCriticalEdges(Function &F, return NumBroken; } -static BasicBlock *SplitBlockImpl(BasicBlock *Old, Instruction *SplitPt, +static BasicBlock *SplitBlockImpl(BasicBlock *Old, BasicBlock::iterator SplitPt, DomTreeUpdater *DTU, DominatorTree *DT, LoopInfo *LI, MemorySSAUpdater *MSSAU, const Twine &BBName, bool Before) { @@ -887,7 +966,7 @@ static BasicBlock *SplitBlockImpl(BasicBlock *Old, Instruction *SplitPt, DTU ? DTU : (DT ? &LocalDTU : nullptr), LI, MSSAU, BBName); } - BasicBlock::iterator SplitIt = SplitPt->getIterator(); + BasicBlock::iterator SplitIt = SplitPt; while (isa<PHINode>(SplitIt) || SplitIt->isEHPad()) { ++SplitIt; assert(SplitIt != SplitPt->getParent()->end()); @@ -933,14 +1012,14 @@ static BasicBlock *SplitBlockImpl(BasicBlock *Old, Instruction *SplitPt, return New; } -BasicBlock *llvm::SplitBlock(BasicBlock *Old, Instruction *SplitPt, +BasicBlock *llvm::SplitBlock(BasicBlock *Old, BasicBlock::iterator SplitPt, DominatorTree *DT, LoopInfo *LI, MemorySSAUpdater *MSSAU, const Twine &BBName, bool Before) { return SplitBlockImpl(Old, SplitPt, /*DTU=*/nullptr, DT, LI, MSSAU, BBName, Before); } -BasicBlock *llvm::SplitBlock(BasicBlock *Old, Instruction *SplitPt, +BasicBlock *llvm::SplitBlock(BasicBlock *Old, BasicBlock::iterator SplitPt, DomTreeUpdater *DTU, LoopInfo *LI, MemorySSAUpdater *MSSAU, const Twine &BBName, bool Before) { @@ -948,12 +1027,12 @@ BasicBlock *llvm::SplitBlock(BasicBlock *Old, Instruction *SplitPt, Before); } -BasicBlock *llvm::splitBlockBefore(BasicBlock *Old, Instruction *SplitPt, +BasicBlock *llvm::splitBlockBefore(BasicBlock *Old, BasicBlock::iterator SplitPt, DomTreeUpdater *DTU, LoopInfo *LI, MemorySSAUpdater *MSSAU, const Twine &BBName) { - BasicBlock::iterator SplitIt = SplitPt->getIterator(); + BasicBlock::iterator SplitIt = SplitPt; while (isa<PHINode>(SplitIt) || SplitIt->isEHPad()) ++SplitIt; std::string Name = BBName.str(); @@ -1137,14 +1216,11 @@ static void UpdatePHINodes(BasicBlock *OrigBB, BasicBlock *NewBB, // If all incoming values for the new PHI would be the same, just don't // make a new PHI. Instead, just remove the incoming values from the old // PHI. - - // NOTE! This loop walks backwards for a reason! First off, this minimizes - // the cost of removal if we end up removing a large number of values, and - // second off, this ensures that the indices for the incoming values - // aren't invalidated when we remove one. - for (int64_t i = PN->getNumIncomingValues() - 1; i >= 0; --i) - if (PredSet.count(PN->getIncomingBlock(i))) - PN->removeIncomingValue(i, false); + PN->removeIncomingValueIf( + [&](unsigned Idx) { + return PredSet.contains(PN->getIncomingBlock(Idx)); + }, + /* DeletePHIIfEmpty */ false); // Add an incoming value to the PHI node in the loop for the preheader // edge. @@ -1394,17 +1470,6 @@ void llvm::SplitLandingPadPredecessors(BasicBlock *OrigBB, ArrayRef<BasicBlock *> Preds, const char *Suffix1, const char *Suffix2, SmallVectorImpl<BasicBlock *> &NewBBs, - DominatorTree *DT, LoopInfo *LI, - MemorySSAUpdater *MSSAU, - bool PreserveLCSSA) { - return SplitLandingPadPredecessorsImpl( - OrigBB, Preds, Suffix1, Suffix2, NewBBs, - /*DTU=*/nullptr, DT, LI, MSSAU, PreserveLCSSA); -} -void llvm::SplitLandingPadPredecessors(BasicBlock *OrigBB, - ArrayRef<BasicBlock *> Preds, - const char *Suffix1, const char *Suffix2, - SmallVectorImpl<BasicBlock *> &NewBBs, DomTreeUpdater *DTU, LoopInfo *LI, MemorySSAUpdater *MSSAU, bool PreserveLCSSA) { @@ -1472,7 +1537,7 @@ ReturnInst *llvm::FoldReturnIntoUncondBranch(ReturnInst *RI, BasicBlock *BB, } Instruction *llvm::SplitBlockAndInsertIfThen(Value *Cond, - Instruction *SplitBefore, + BasicBlock::iterator SplitBefore, bool Unreachable, MDNode *BranchWeights, DomTreeUpdater *DTU, LoopInfo *LI, @@ -1485,7 +1550,7 @@ Instruction *llvm::SplitBlockAndInsertIfThen(Value *Cond, } Instruction *llvm::SplitBlockAndInsertIfElse(Value *Cond, - Instruction *SplitBefore, + BasicBlock::iterator SplitBefore, bool Unreachable, MDNode *BranchWeights, DomTreeUpdater *DTU, LoopInfo *LI, @@ -1497,7 +1562,7 @@ Instruction *llvm::SplitBlockAndInsertIfElse(Value *Cond, return ElseBlock->getTerminator(); } -void llvm::SplitBlockAndInsertIfThenElse(Value *Cond, Instruction *SplitBefore, +void llvm::SplitBlockAndInsertIfThenElse(Value *Cond, BasicBlock::iterator SplitBefore, Instruction **ThenTerm, Instruction **ElseTerm, MDNode *BranchWeights, @@ -1513,7 +1578,7 @@ void llvm::SplitBlockAndInsertIfThenElse(Value *Cond, Instruction *SplitBefore, } void llvm::SplitBlockAndInsertIfThenElse( - Value *Cond, Instruction *SplitBefore, BasicBlock **ThenBlock, + Value *Cond, BasicBlock::iterator SplitBefore, BasicBlock **ThenBlock, BasicBlock **ElseBlock, bool UnreachableThen, bool UnreachableElse, MDNode *BranchWeights, DomTreeUpdater *DTU, LoopInfo *LI) { assert((ThenBlock || ElseBlock) && @@ -1530,7 +1595,7 @@ void llvm::SplitBlockAndInsertIfThenElse( } LLVMContext &C = Head->getContext(); - BasicBlock *Tail = Head->splitBasicBlock(SplitBefore->getIterator()); + BasicBlock *Tail = Head->splitBasicBlock(SplitBefore); BasicBlock *TrueBlock = Tail; BasicBlock *FalseBlock = Tail; bool ThenToTailEdge = false; @@ -2077,3 +2142,25 @@ void llvm::InvertBranch(BranchInst *PBI, IRBuilderBase &Builder) { PBI->setCondition(NewCond); PBI->swapSuccessors(); } + +bool llvm::hasOnlySimpleTerminator(const Function &F) { + for (auto &BB : F) { + auto *Term = BB.getTerminator(); + if (!(isa<ReturnInst>(Term) || isa<UnreachableInst>(Term) || + isa<BranchInst>(Term))) + return false; + } + return true; +} + +bool llvm::isPresplitCoroSuspendExitEdge(const BasicBlock &Src, + const BasicBlock &Dest) { + assert(Src.getParent() == Dest.getParent()); + if (!Src.getParent()->isPresplitCoroutine()) + return false; + if (auto *SW = dyn_cast<SwitchInst>(Src.getTerminator())) + if (auto *Intr = dyn_cast<IntrinsicInst>(SW->getCondition())) + return Intr->getIntrinsicID() == Intrinsic::coro_suspend && + SW->getDefaultDest() == &Dest; + return false; +} |
