diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2024-01-24 19:17:23 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2024-04-19 21:24:44 +0000 |
commit | ab50317e96e57dee5b3ff4ad3f16f205b2a3359e (patch) | |
tree | 4b1f388eb6a07e574417aaacecd3ec4a83550718 /contrib/llvm-project/llvm/lib/Transforms/Utils | |
parent | 412542983a5ba62902141a8a7e155cceb9196a66 (diff) |
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Transforms/Utils')
15 files changed, 243 insertions, 174 deletions
diff --git a/contrib/llvm-project/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp b/contrib/llvm-project/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp index 8b5a6d618412..ec0482ac2cde 100644 --- a/contrib/llvm-project/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp +++ b/contrib/llvm-project/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp @@ -405,10 +405,17 @@ static bool DPValuesRemoveRedundantDbgInstrsUsingBackwardScan(BasicBlock *BB) { // 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); + if (R.second) + continue; + + if (DPV.isDbgAssign()) { + // Don't delete dbg.assign intrinsics that are linked to instructions. + if (!at::getAssignmentInsts(&DPV).empty()) + continue; + // Unlinked dbg.assign intrinsics can be treated like dbg.values. + } + + ToBeRemoved.push_back(&DPV); continue; } // Sequence with consecutive dbg.value instrs ended. Clear the map to @@ -495,14 +502,25 @@ static bool DPValuesRemoveRedundantDbgInstrsUsingForwardScan(BasicBlock *BB) { DebugVariable Key(DPV.getVariable(), std::nullopt, DPV.getDebugLoc()->getInlinedAt()); auto VMI = VariableMap.find(Key); + // A dbg.assign with no linked instructions can be treated like a + // dbg.value (i.e. can be deleted). + bool IsDbgValueKind = + (!DPV.isDbgAssign() || at::getAssignmentInsts(&DPV).empty()); + // 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()}; + if (IsDbgValueKind) + VariableMap[Key] = {Values, DPV.getExpression()}; + else + VariableMap[Key] = {Values, nullptr}; continue; } + // Don't delete dbg.assign intrinsics that are linked to instructions. + if (!IsDbgValueKind) + continue; // Found an identical mapping. Remember the instruction for later removal. ToBeRemoved.push_back(&DPV); } @@ -514,6 +532,42 @@ static bool DPValuesRemoveRedundantDbgInstrsUsingForwardScan(BasicBlock *BB) { return !ToBeRemoved.empty(); } +static bool DPValuesRemoveUndefDbgAssignsFromEntryBlock(BasicBlock *BB) { + assert(BB->isEntryBlock() && "expected entry block"); + SmallVector<DPValue *, 8> ToBeRemoved; + DenseSet<DebugVariable> SeenDefForAggregate; + // Returns the DebugVariable for DVI with no fragment info. + auto GetAggregateVariable = [](const DPValue &DPV) { + return DebugVariable(DPV.getVariable(), std::nullopt, + DPV.getDebugLoc().getInlinedAt()); + }; + + // Remove undef dbg.assign intrinsics that are encountered before + // any non-undef intrinsics from the entry block. + for (auto &I : *BB) { + for (DPValue &DPV : I.getDbgValueRange()) { + if (!DPV.isDbgValue() && !DPV.isDbgAssign()) + continue; + bool IsDbgValueKind = + (DPV.isDbgValue() || at::getAssignmentInsts(&DPV).empty()); + DebugVariable Aggregate = GetAggregateVariable(DPV); + if (!SeenDefForAggregate.contains(Aggregate)) { + bool IsKill = DPV.isKillLocation() && IsDbgValueKind; + if (!IsKill) { + SeenDefForAggregate.insert(Aggregate); + } else if (DPV.isDbgAssign()) { + ToBeRemoved.push_back(&DPV); + } + } + } + } + + for (DPValue *DPV : ToBeRemoved) + DPV->eraseFromParent(); + + return !ToBeRemoved.empty(); +} + static bool removeRedundantDbgInstrsUsingForwardScan(BasicBlock *BB) { if (BB->IsNewDbgInfoFormat) return DPValuesRemoveRedundantDbgInstrsUsingForwardScan(BB); @@ -536,7 +590,7 @@ static bool removeRedundantDbgInstrsUsingForwardScan(BasicBlock *BB) { SmallVector<Value *, 4> Values(DVI->getValues()); if (VMI == VariableMap.end() || VMI->second.first != Values || VMI->second.second != DVI->getExpression()) { - // Use a sentinal value (nullptr) for the DIExpression when we see a + // Use a sentinel value (nullptr) for the DIExpression when we see a // linked dbg.assign so that the next debug intrinsic will never match // it (i.e. always treat linked dbg.assigns as if they're unique). if (IsDbgValueKind) @@ -578,7 +632,10 @@ static bool removeRedundantDbgInstrsUsingForwardScan(BasicBlock *BB) { /// then (only) the instruction marked with (*) can be removed. /// Possible improvements: /// - Keep track of non-overlapping fragments. -static bool remomveUndefDbgAssignsFromEntryBlock(BasicBlock *BB) { +static bool removeUndefDbgAssignsFromEntryBlock(BasicBlock *BB) { + if (BB->IsNewDbgInfoFormat) + return DPValuesRemoveUndefDbgAssignsFromEntryBlock(BB); + assert(BB->isEntryBlock() && "expected entry block"); SmallVector<DbgAssignIntrinsic *, 8> ToBeRemoved; DenseSet<DebugVariable> SeenDefForAggregate; @@ -629,7 +686,7 @@ bool llvm::RemoveRedundantDbgInstrs(BasicBlock *BB) { MadeChanges |= removeRedundantDbgInstrsUsingBackwardScan(BB); if (BB->isEntryBlock() && isAssignmentTrackingEnabled(*BB->getParent()->getParent())) - MadeChanges |= remomveUndefDbgAssignsFromEntryBlock(BB); + MadeChanges |= removeUndefDbgAssignsFromEntryBlock(BB); MadeChanges |= removeRedundantDbgInstrsUsingForwardScan(BB); if (MadeChanges) diff --git a/contrib/llvm-project/llvm/lib/Transforms/Utils/CodeExtractor.cpp b/contrib/llvm-project/llvm/lib/Transforms/Utils/CodeExtractor.cpp index f5abed0dd517..278111883459 100644 --- a/contrib/llvm-project/llvm/lib/Transforms/Utils/CodeExtractor.cpp +++ b/contrib/llvm-project/llvm/lib/Transforms/Utils/CodeExtractor.cpp @@ -1589,11 +1589,14 @@ static void fixupDebugInfoPostExtraction(Function &OldFunc, Function &NewFunc, for (auto &DPV : I.getDbgValueRange()) { // Apply the two updates that dbg.values get: invalid operands, and // variable metadata fixup. - // FIXME: support dbg.assign form of DPValues. if (any_of(DPV.location_ops(), IsInvalidLocation)) { DPVsToDelete.push_back(&DPV); continue; } + if (DPV.isDbgAssign() && IsInvalidLocation(DPV.getAddress())) { + DPVsToDelete.push_back(&DPV); + continue; + } if (!DPV.getDebugLoc().getInlinedAt()) DPV.setVariable(GetUpdatedDIVariable(DPV.getVariable())); DPV.setDebugLoc(DebugLoc::replaceInlinedAtSubprogram(DPV.getDebugLoc(), @@ -1735,13 +1738,9 @@ CodeExtractor::extractCodeRegion(const CodeExtractorAnalysisCache &CEAC, NumExitBlocks = ExitBlocks.size(); for (BasicBlock *Block : Blocks) { - Instruction *TI = Block->getTerminator(); - for (unsigned i = 0, e = TI->getNumSuccessors(); i != e; ++i) { - if (Blocks.count(TI->getSuccessor(i))) - continue; - BasicBlock *OldTarget = TI->getSuccessor(i); - OldTargets.push_back(OldTarget); - } + for (BasicBlock *OldTarget : successors(Block)) + if (!Blocks.contains(OldTarget)) + OldTargets.push_back(OldTarget); } // If we have to split PHI nodes of the entry or exit blocks, do so now. diff --git a/contrib/llvm-project/llvm/lib/Transforms/Utils/InjectTLIMappings.cpp b/contrib/llvm-project/llvm/lib/Transforms/Utils/InjectTLIMappings.cpp index ea3135630665..9bfac2ac9167 100644 --- a/contrib/llvm-project/llvm/lib/Transforms/Utils/InjectTLIMappings.cpp +++ b/contrib/llvm-project/llvm/lib/Transforms/Utils/InjectTLIMappings.cpp @@ -19,6 +19,7 @@ #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Analysis/VectorUtils.h" #include "llvm/IR/InstIterator.h" +#include "llvm/IR/VFABIDemangler.h" #include "llvm/Transforms/Utils/ModuleUtils.h" using namespace llvm; diff --git a/contrib/llvm-project/llvm/lib/Transforms/Utils/InlineFunction.cpp b/contrib/llvm-project/llvm/lib/Transforms/Utils/InlineFunction.cpp index 39d5f6e53c1d..d4d4bf5ebdf3 100644 --- a/contrib/llvm-project/llvm/lib/Transforms/Utils/InlineFunction.cpp +++ b/contrib/llvm-project/llvm/lib/Transforms/Utils/InlineFunction.cpp @@ -1789,13 +1789,15 @@ static at::StorageToVarsMap collectEscapedLocals(const DataLayout &DL, continue; // Find all local variables associated with the backing storage. - for (auto *DAI : at::getAssignmentMarkers(Base)) { + auto CollectAssignsForStorage = [&](auto *DbgAssign) { // Skip variables from inlined functions - they are not local variables. - if (DAI->getDebugLoc().getInlinedAt()) - continue; - LLVM_DEBUG(errs() << " > DEF : " << *DAI << "\n"); - EscapedLocals[Base].insert(at::VarRecord(DAI)); - } + if (DbgAssign->getDebugLoc().getInlinedAt()) + return; + LLVM_DEBUG(errs() << " > DEF : " << *DbgAssign << "\n"); + EscapedLocals[Base].insert(at::VarRecord(DbgAssign)); + }; + for_each(at::getAssignmentMarkers(Base), CollectAssignsForStorage); + for_each(at::getDPVAssignmentMarkers(Base), CollectAssignsForStorage); } return EscapedLocals; } @@ -1827,6 +1829,10 @@ static void fixupAssignments(Function::iterator Start, Function::iterator End) { // attachment or use, replace it with a new version. for (auto BBI = Start; BBI != End; ++BBI) { for (Instruction &I : *BBI) { + for (DPValue &DPV : I.getDbgValueRange()) { + if (DPV.isDbgAssign()) + DPV.setAssignId(GetNewID(DPV.getAssignID())); + } if (auto *ID = I.getMetadata(LLVMContext::MD_DIAssignID)) I.setMetadata(LLVMContext::MD_DIAssignID, GetNewID(ID)); else if (auto *DAI = dyn_cast<DbgAssignIntrinsic>(&I)) diff --git a/contrib/llvm-project/llvm/lib/Transforms/Utils/Local.cpp b/contrib/llvm-project/llvm/lib/Transforms/Utils/Local.cpp index b9cad764aaef..459e3d980592 100644 --- a/contrib/llvm-project/llvm/lib/Transforms/Utils/Local.cpp +++ b/contrib/llvm-project/llvm/lib/Transforms/Utils/Local.cpp @@ -1724,20 +1724,6 @@ void llvm::ConvertDebugDeclareToDebugValue(DbgVariableIntrinsic *DII, SI->getIterator()); } -namespace llvm { -// RemoveDIs: duplicate the getDebugValueLoc method using DPValues instead of -// dbg.value intrinsics. In llvm namespace so that it overloads the -// DbgVariableIntrinsic version. -static DebugLoc getDebugValueLoc(DPValue *DPV) { - // Original dbg.declare must have a location. - const DebugLoc &DeclareLoc = DPV->getDebugLoc(); - MDNode *Scope = DeclareLoc.getScope(); - DILocation *InlinedAt = DeclareLoc.getInlinedAt(); - // Produce an unknown location with the correct scope / inlinedAt fields. - return DILocation::get(DPV->getContext(), 0, 0, Scope, InlinedAt); -} -} // namespace llvm - /// Inserts a llvm.dbg.value intrinsic before a load of an alloca'd value /// that has an associated llvm.dbg.declare intrinsic. void llvm::ConvertDebugDeclareToDebugValue(DbgVariableIntrinsic *DII, @@ -1767,7 +1753,7 @@ void llvm::ConvertDebugDeclareToDebugValue(DbgVariableIntrinsic *DII, void llvm::ConvertDebugDeclareToDebugValue(DPValue *DPV, StoreInst *SI, DIBuilder &Builder) { - assert(DPV->isAddressOfVariable()); + assert(DPV->isAddressOfVariable() || DPV->isDbgAssign()); auto *DIVar = DPV->getVariable(); assert(DIVar && "Missing variable"); auto *DIExpr = DPV->getExpression(); @@ -2130,9 +2116,8 @@ void llvm::insertDebugValuesForPHIs(BasicBlock *BB, bool llvm::replaceDbgDeclare(Value *Address, Value *NewAddress, DIBuilder &Builder, uint8_t DIExprFlags, int Offset) { - SmallVector<DbgDeclareInst *, 1> DbgDeclares; - SmallVector<DPValue *, 1> DPValues; - findDbgDeclares(DbgDeclares, Address, &DPValues); + TinyPtrVector<DbgDeclareInst *> DbgDeclares = findDbgDeclares(Address); + TinyPtrVector<DPValue *> DPVDeclares = findDPVDeclares(Address); auto ReplaceOne = [&](auto *DII) { assert(DII->getVariable() && "Missing variable"); @@ -2143,9 +2128,9 @@ bool llvm::replaceDbgDeclare(Value *Address, Value *NewAddress, }; for_each(DbgDeclares, ReplaceOne); - for_each(DPValues, ReplaceOne); + for_each(DPVDeclares, ReplaceOne); - return !DbgDeclares.empty() || !DPValues.empty(); + return !DbgDeclares.empty() || !DPVDeclares.empty(); } static void updateOneDbgValueForAlloca(const DebugLoc &Loc, @@ -2204,14 +2189,13 @@ void llvm::salvageDebugInfo(Instruction &I) { salvageDebugInfoForDbgValues(I, DbgUsers, DPUsers); } -/// Salvage the address component of \p DAI. -static void salvageDbgAssignAddress(DbgAssignIntrinsic *DAI) { - Instruction *I = dyn_cast<Instruction>(DAI->getAddress()); +template <typename T> static void salvageDbgAssignAddress(T *Assign) { + Instruction *I = dyn_cast<Instruction>(Assign->getAddress()); // Only instructions can be salvaged at the moment. if (!I) return; - assert(!DAI->getAddressExpression()->getFragmentInfo().has_value() && + assert(!Assign->getAddressExpression()->getFragmentInfo().has_value() && "address-expression shouldn't have fragment info"); // The address component of a dbg.assign cannot be variadic. @@ -2225,16 +2209,16 @@ static void salvageDbgAssignAddress(DbgAssignIntrinsic *DAI) { return; DIExpression *SalvagedExpr = DIExpression::appendOpsToArg( - DAI->getAddressExpression(), Ops, 0, /*StackValue=*/false); + Assign->getAddressExpression(), Ops, 0, /*StackValue=*/false); assert(!SalvagedExpr->getFragmentInfo().has_value() && "address-expression shouldn't have fragment info"); // Salvage succeeds if no additional values are required. if (AdditionalValues.empty()) { - DAI->setAddress(NewV); - DAI->setAddressExpression(SalvagedExpr); + Assign->setAddress(NewV); + Assign->setAddressExpression(SalvagedExpr); } else { - DAI->setKillAddress(); + Assign->setKillAddress(); } } @@ -2308,10 +2292,19 @@ void llvm::salvageDebugInfoForDbgValues( } // Duplicate of above block for DPValues. for (auto *DPV : DPUsers) { + if (DPV->isDbgAssign()) { + if (DPV->getAddress() == &I) { + salvageDbgAssignAddress(DPV); + Salvaged = true; + } + if (DPV->getValue() != &I) + continue; + } + // Do not add DW_OP_stack_value for DbgDeclare and DbgAddr, because they // are implicitly pointing out the value as a DWARF memory location // description. - bool StackValue = DPV->getType() == DPValue::LocationType::Value; + bool StackValue = DPV->getType() != DPValue::LocationType::Declare; auto DPVLocation = DPV->location_ops(); assert( is_contained(DPVLocation, &I) && @@ -2345,7 +2338,7 @@ void llvm::salvageDebugInfoForDbgValues( SalvagedExpr->getNumElements() <= MaxExpressionSize; if (AdditionalValues.empty() && IsValidSalvageExpr) { DPV->setExpression(SalvagedExpr); - } else if (DPV->getType() == DPValue::LocationType::Value && + } else if (DPV->getType() != DPValue::LocationType::Declare && IsValidSalvageExpr && DPV->getNumVariableLocationOps() + AdditionalValues.size() <= MaxDebugArgs) { @@ -2355,8 +2348,7 @@ void llvm::salvageDebugInfoForDbgValues( // currently only valid for stack value expressions. // Also do not salvage if the resulting DIArgList would contain an // unreasonably large number of values. - Value *Undef = UndefValue::get(I.getOperand(0)->getType()); - DPV->replaceVariableLocationOp(I.getOperand(0), Undef); + DPV->setKillLocation(); } LLVM_DEBUG(dbgs() << "SALVAGE: " << DPV << '\n'); Salvaged = true; diff --git a/contrib/llvm-project/llvm/lib/Transforms/Utils/MemoryOpRemark.cpp b/contrib/llvm-project/llvm/lib/Transforms/Utils/MemoryOpRemark.cpp index 47c6bcbaf26e..d671a9373bf0 100644 --- a/contrib/llvm-project/llvm/lib/Transforms/Utils/MemoryOpRemark.cpp +++ b/contrib/llvm-project/llvm/lib/Transforms/Utils/MemoryOpRemark.cpp @@ -321,9 +321,6 @@ void MemoryOpRemark::visitVariable(const Value *V, bool FoundDI = false; // Try to get an llvm.dbg.declare, which has a DILocalVariable giving us the // real debug info name and size of the variable. - SmallVector<DbgDeclareInst *, 1> DbgDeclares; - SmallVector<DPValue *, 1> DPValues; - findDbgDeclares(DbgDeclares, const_cast<Value *>(V), &DPValues); auto FindDI = [&](const auto *DVI) { if (DILocalVariable *DILV = DVI->getVariable()) { std::optional<uint64_t> DISize = getSizeInBytes(DILV->getSizeInBits()); @@ -334,8 +331,8 @@ void MemoryOpRemark::visitVariable(const Value *V, } } }; - for_each(DbgDeclares, FindDI); - for_each(DPValues, FindDI); + for_each(findDbgDeclares(const_cast<Value *>(V)), FindDI); + for_each(findDPVDeclares(const_cast<Value *>(V)), FindDI); if (FoundDI) { assert(!Result.empty()); diff --git a/contrib/llvm-project/llvm/lib/Transforms/Utils/ModuleUtils.cpp b/contrib/llvm-project/llvm/lib/Transforms/Utils/ModuleUtils.cpp index 7de0959ca57e..209a6a34a3c9 100644 --- a/contrib/llvm-project/llvm/lib/Transforms/Utils/ModuleUtils.cpp +++ b/contrib/llvm-project/llvm/lib/Transforms/Utils/ModuleUtils.cpp @@ -329,35 +329,6 @@ std::string llvm::getUniqueModuleId(Module *M) { return ("." + Str).str(); } -void VFABI::setVectorVariantNames(CallInst *CI, - ArrayRef<std::string> VariantMappings) { - if (VariantMappings.empty()) - return; - - SmallString<256> Buffer; - llvm::raw_svector_ostream Out(Buffer); - for (const std::string &VariantMapping : VariantMappings) - Out << VariantMapping << ","; - // Get rid of the trailing ','. - assert(!Buffer.str().empty() && "Must have at least one char."); - Buffer.pop_back(); - - Module *M = CI->getModule(); -#ifndef NDEBUG - for (const std::string &VariantMapping : VariantMappings) { - LLVM_DEBUG(dbgs() << "VFABI: adding mapping '" << VariantMapping << "'\n"); - std::optional<VFInfo> VI = - VFABI::tryDemangleForVFABI(VariantMapping, CI->getFunctionType()); - assert(VI && "Cannot add an invalid VFABI name."); - assert(M->getNamedValue(VI->VectorName) && - "Cannot add variant to attribute: " - "vector function declaration is missing."); - } -#endif - CI->addFnAttr( - Attribute::get(M->getContext(), MappingsAttrName, Buffer.str())); -} - void llvm::embedBufferInModule(Module &M, MemoryBufferRef Buf, StringRef SectionName, Align Alignment) { // Embed the memory buffer into the module. diff --git a/contrib/llvm-project/llvm/lib/Transforms/Utils/MoveAutoInit.cpp b/contrib/llvm-project/llvm/lib/Transforms/Utils/MoveAutoInit.cpp index a977ad87b79f..9a5dba219cee 100644 --- a/contrib/llvm-project/llvm/lib/Transforms/Utils/MoveAutoInit.cpp +++ b/contrib/llvm-project/llvm/lib/Transforms/Utils/MoveAutoInit.cpp @@ -164,6 +164,9 @@ static bool runMoveAutoInit(Function &F, DominatorTree &DT, MemorySSA &MSSA) { if (TransitiveSuccessors.count(Pred)) continue; + if (!DT.isReachableFromEntry(Pred)) + continue; + DominatingPredecessor = DominatingPredecessor ? DT.findNearestCommonDominator(DominatingPredecessor, Pred) @@ -178,9 +181,10 @@ static bool runMoveAutoInit(Function &F, DominatorTree &DT, MemorySSA &MSSA) { // CatchSwitchInst blocks can only have one instruction, so they are not // good candidates for insertion. - while (isa<CatchSwitchInst>(UsersDominator->getFirstInsertionPt())) { + while (isa<CatchSwitchInst>(UsersDominator->getFirstNonPHI())) { for (BasicBlock *Pred : predecessors(UsersDominator)) - UsersDominator = DT.findNearestCommonDominator(UsersDominator, Pred); + if (DT.isReachableFromEntry(Pred)) + UsersDominator = DT.findNearestCommonDominator(UsersDominator, Pred); } // We finally found a place where I can be moved while not introducing extra diff --git a/contrib/llvm-project/llvm/lib/Transforms/Utils/NameAnonGlobals.cpp b/contrib/llvm-project/llvm/lib/Transforms/Utils/NameAnonGlobals.cpp index f41a14cdfbec..9655cb9cf6f4 100644 --- a/contrib/llvm-project/llvm/lib/Transforms/Utils/NameAnonGlobals.cpp +++ b/contrib/llvm-project/llvm/lib/Transforms/Utils/NameAnonGlobals.cpp @@ -54,7 +54,7 @@ public: Hasher.final(Hash); SmallString<32> Result; MD5::stringifyResult(Hash, Result); - TheHash = std::string(Result.str()); + TheHash = std::string(Result); return TheHash; } }; diff --git a/contrib/llvm-project/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp b/contrib/llvm-project/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp index 717b6d301c8c..88b05aab8db4 100644 --- a/contrib/llvm-project/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp +++ b/contrib/llvm-project/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp @@ -101,12 +101,30 @@ bool llvm::isAllocaPromotable(const AllocaInst *AI) { namespace { +static DPValue *createDebugValue(DIBuilder &DIB, Value *NewValue, + DILocalVariable *Variable, + DIExpression *Expression, const DILocation *DI, + DPValue *InsertBefore) { + (void)DIB; + return DPValue::createDPValue(NewValue, Variable, Expression, DI, + *InsertBefore); +} +static DbgValueInst *createDebugValue(DIBuilder &DIB, Value *NewValue, + DILocalVariable *Variable, + DIExpression *Expression, + const DILocation *DI, + Instruction *InsertBefore) { + return static_cast<DbgValueInst *>(DIB.insertDbgValueIntrinsic( + NewValue, Variable, Expression, DI, InsertBefore)); +} + /// Helper for updating assignment tracking debug info when promoting allocas. class AssignmentTrackingInfo { /// DbgAssignIntrinsics linked to the alloca with at most one per variable /// fragment. (i.e. not be a comprehensive set if there are multiple /// dbg.assigns for one variable fragment). SmallVector<DbgVariableIntrinsic *> DbgAssigns; + SmallVector<DPValue *> DPVAssigns; public: void init(AllocaInst *AI) { @@ -115,16 +133,21 @@ public: if (Vars.insert(DebugVariable(DAI)).second) DbgAssigns.push_back(DAI); } + for (DPValue *DPV : at::getDPVAssignmentMarkers(AI)) { + if (Vars.insert(DebugVariable(DPV)).second) + DPVAssigns.push_back(DPV); + } } /// Update assignment tracking debug info given for the to-be-deleted store /// \p ToDelete that stores to this alloca. - void updateForDeletedStore( - StoreInst *ToDelete, DIBuilder &DIB, - SmallSet<DbgAssignIntrinsic *, 8> *DbgAssignsToDelete) const { + void + updateForDeletedStore(StoreInst *ToDelete, DIBuilder &DIB, + SmallSet<DbgAssignIntrinsic *, 8> *DbgAssignsToDelete, + SmallSet<DPValue *, 8> *DPVAssignsToDelete) const { // There's nothing to do if the alloca doesn't have any variables using // assignment tracking. - if (DbgAssigns.empty()) + if (DbgAssigns.empty() && DPVAssigns.empty()) return; // Insert a dbg.value where the linked dbg.assign is and remember to delete @@ -134,13 +157,17 @@ public: // dbg.assign for each variable fragment for the untracked store handling // (after this loop). SmallSet<DebugVariableAggregate, 2> VarHasDbgAssignForStore; - for (DbgAssignIntrinsic *DAI : at::getAssignmentMarkers(ToDelete)) { - VarHasDbgAssignForStore.insert(DebugVariableAggregate(DAI)); - DbgAssignsToDelete->insert(DAI); - DIB.insertDbgValueIntrinsic(DAI->getValue(), DAI->getVariable(), - DAI->getExpression(), DAI->getDebugLoc(), - DAI); - } + auto InsertValueForAssign = [&](auto *DbgAssign, auto *&AssignList) { + VarHasDbgAssignForStore.insert(DebugVariableAggregate(DbgAssign)); + AssignList->insert(DbgAssign); + createDebugValue(DIB, DbgAssign->getValue(), DbgAssign->getVariable(), + DbgAssign->getExpression(), DbgAssign->getDebugLoc(), + DbgAssign); + }; + for (auto *Assign : at::getAssignmentMarkers(ToDelete)) + InsertValueForAssign(Assign, DbgAssignsToDelete); + for (auto *Assign : at::getDPVAssignmentMarkers(ToDelete)) + InsertValueForAssign(Assign, DPVAssignsToDelete); // It's possible for variables using assignment tracking to have no // dbg.assign linked to this store. These are variables in DbgAssigns that @@ -150,11 +177,13 @@ public: // cannot be represented using assignment tracking (non-const offset or // size) or one that is trackable but has had its DIAssignID attachment // dropped accidentally. - for (auto *DAI : DbgAssigns) { - if (VarHasDbgAssignForStore.contains(DebugVariableAggregate(DAI))) - continue; - ConvertDebugDeclareToDebugValue(DAI, ToDelete, DIB); - } + auto ConvertUnlinkedAssignToValue = [&](auto *Assign) { + if (VarHasDbgAssignForStore.contains(DebugVariableAggregate(Assign))) + return; + ConvertDebugDeclareToDebugValue(Assign, ToDelete, DIB); + }; + for_each(DbgAssigns, ConvertUnlinkedAssignToValue); + for_each(DPVAssigns, ConvertUnlinkedAssignToValue); } /// Update assignment tracking debug info given for the newly inserted PHI \p @@ -165,10 +194,15 @@ public: // debug-phi. for (auto *DAI : DbgAssigns) ConvertDebugDeclareToDebugValue(DAI, NewPhi, DIB); + for (auto *DPV : DPVAssigns) + ConvertDebugDeclareToDebugValue(DPV, NewPhi, DIB); } - void clear() { DbgAssigns.clear(); } - bool empty() { return DbgAssigns.empty(); } + void clear() { + DbgAssigns.clear(); + DPVAssigns.clear(); + } + bool empty() { return DbgAssigns.empty() && DPVAssigns.empty(); } }; struct AllocaInfo { @@ -229,11 +263,15 @@ struct AllocaInfo { } } DbgUserVec AllDbgUsers; - findDbgUsers(AllDbgUsers, AI, &DPUsers); + SmallVector<DPValue *> AllDPUsers; + findDbgUsers(AllDbgUsers, AI, &AllDPUsers); std::copy_if(AllDbgUsers.begin(), AllDbgUsers.end(), std::back_inserter(DbgUsers), [](DbgVariableIntrinsic *DII) { return !isa<DbgAssignIntrinsic>(DII); }); + std::copy_if(AllDPUsers.begin(), AllDPUsers.end(), + std::back_inserter(DPUsers), + [](DPValue *DPV) { return !DPV->isDbgAssign(); }); AssignmentTracking.init(AI); } }; @@ -341,6 +379,7 @@ struct PromoteMem2Reg { /// A set of dbg.assigns to delete because they've been demoted to /// dbg.values. Call cleanUpDbgAssigns to delete them. SmallSet<DbgAssignIntrinsic *, 8> DbgAssignsToDelete; + SmallSet<DPValue *, 8> DPVAssignsToDelete; /// The set of basic blocks the renamer has already visited. SmallPtrSet<BasicBlock *, 16> Visited; @@ -390,6 +429,9 @@ private: for (auto *DAI : DbgAssignsToDelete) DAI->eraseFromParent(); DbgAssignsToDelete.clear(); + for (auto *DPV : DPVAssignsToDelete) + DPV->eraseFromParent(); + DPVAssignsToDelete.clear(); } }; @@ -462,10 +504,12 @@ static void removeIntrinsicUsers(AllocaInst *AI) { /// false there were some loads which were not dominated by the single store /// and thus must be phi-ed with undef. We fall back to the standard alloca /// promotion algorithm in that case. -static bool rewriteSingleStoreAlloca( - AllocaInst *AI, AllocaInfo &Info, LargeBlockInfo &LBI, const DataLayout &DL, - DominatorTree &DT, AssumptionCache *AC, - SmallSet<DbgAssignIntrinsic *, 8> *DbgAssignsToDelete) { +static bool +rewriteSingleStoreAlloca(AllocaInst *AI, AllocaInfo &Info, LargeBlockInfo &LBI, + const DataLayout &DL, DominatorTree &DT, + AssumptionCache *AC, + SmallSet<DbgAssignIntrinsic *, 8> *DbgAssignsToDelete, + SmallSet<DPValue *, 8> *DPVAssignsToDelete) { StoreInst *OnlyStore = Info.OnlyStore; bool StoringGlobalVal = !isa<Instruction>(OnlyStore->getOperand(0)); BasicBlock *StoreBB = OnlyStore->getParent(); @@ -525,8 +569,8 @@ static bool rewriteSingleStoreAlloca( DIBuilder DIB(*AI->getModule(), /*AllowUnresolved*/ false); // Update assignment tracking info for the store we're going to delete. - Info.AssignmentTracking.updateForDeletedStore(Info.OnlyStore, DIB, - DbgAssignsToDelete); + Info.AssignmentTracking.updateForDeletedStore( + Info.OnlyStore, DIB, DbgAssignsToDelete, DPVAssignsToDelete); // Record debuginfo for the store and remove the declaration's // debuginfo. @@ -570,10 +614,12 @@ static bool rewriteSingleStoreAlloca( /// use(t); /// *A = 42; /// } -static bool promoteSingleBlockAlloca( - AllocaInst *AI, const AllocaInfo &Info, LargeBlockInfo &LBI, - const DataLayout &DL, DominatorTree &DT, AssumptionCache *AC, - SmallSet<DbgAssignIntrinsic *, 8> *DbgAssignsToDelete) { +static bool +promoteSingleBlockAlloca(AllocaInst *AI, const AllocaInfo &Info, + LargeBlockInfo &LBI, const DataLayout &DL, + DominatorTree &DT, AssumptionCache *AC, + SmallSet<DbgAssignIntrinsic *, 8> *DbgAssignsToDelete, + SmallSet<DPValue *, 8> *DPVAssignsToDelete) { // The trickiest case to handle is when we have large blocks. Because of this, // this code is optimized assuming that large blocks happen. This does not // significantly pessimize the small block case. This uses LargeBlockInfo to @@ -637,8 +683,8 @@ static bool promoteSingleBlockAlloca( while (!AI->use_empty()) { StoreInst *SI = cast<StoreInst>(AI->user_back()); // Update assignment tracking info for the store we're going to delete. - Info.AssignmentTracking.updateForDeletedStore(SI, DIB, DbgAssignsToDelete); - + Info.AssignmentTracking.updateForDeletedStore(SI, DIB, DbgAssignsToDelete, + DPVAssignsToDelete); // Record debuginfo for the store before removing it. auto DbgUpdateForStore = [&](auto &Container) { for (auto *DbgItem : Container) { @@ -710,7 +756,7 @@ void PromoteMem2Reg::run() { // it that are directly dominated by the definition with the value stored. if (Info.DefiningBlocks.size() == 1) { if (rewriteSingleStoreAlloca(AI, Info, LBI, SQ.DL, DT, AC, - &DbgAssignsToDelete)) { + &DbgAssignsToDelete, &DPVAssignsToDelete)) { // The alloca has been processed, move on. RemoveFromAllocasList(AllocaNum); ++NumSingleStore; @@ -722,7 +768,7 @@ void PromoteMem2Reg::run() { // linear sweep over the block to eliminate it. if (Info.OnlyUsedInOneBlock && promoteSingleBlockAlloca(AI, Info, LBI, SQ.DL, DT, AC, - &DbgAssignsToDelete)) { + &DbgAssignsToDelete, &DPVAssignsToDelete)) { // The alloca has been processed, move on. RemoveFromAllocasList(AllocaNum); continue; @@ -1128,8 +1174,8 @@ NextIteration: // Record debuginfo for the store before removing it. IncomingLocs[AllocaNo] = SI->getDebugLoc(); - AllocaATInfo[AllocaNo].updateForDeletedStore(SI, DIB, - &DbgAssignsToDelete); + AllocaATInfo[AllocaNo].updateForDeletedStore(SI, DIB, &DbgAssignsToDelete, + &DPVAssignsToDelete); auto ConvertDbgDeclares = [&](auto &Container) { for (auto *DbgItem : Container) if (DbgItem->isAddressOfVariable()) diff --git a/contrib/llvm-project/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp b/contrib/llvm-project/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp index cd3ac317cd23..a1d7f0f9ba0f 100644 --- a/contrib/llvm-project/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp +++ b/contrib/llvm-project/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp @@ -169,12 +169,8 @@ Value *SCEVExpander::InsertNoopCastOfTo(Value *V, Type *Ty) { // during expansion. if (Op == Instruction::IntToPtr) { auto *PtrTy = cast<PointerType>(Ty); - if (DL.isNonIntegralPointerType(PtrTy)) { - assert(DL.getTypeAllocSize(Builder.getInt8Ty()) == 1 && - "alloc size of i8 must by 1 byte for the GEP to be correct"); - return Builder.CreateGEP( - Builder.getInt8Ty(), Constant::getNullValue(PtrTy), V, "scevgep"); - } + if (DL.isNonIntegralPointerType(PtrTy)) + return Builder.CreatePtrAdd(Constant::getNullValue(PtrTy), V, "scevgep"); } // Short-circuit unnecessary bitcasts. if (Op == Instruction::BitCast) { @@ -321,7 +317,7 @@ Value *SCEVExpander::expandAddToGEP(const SCEV *Offset, Value *V) { // Fold a GEP with constant operands. if (Constant *CLHS = dyn_cast<Constant>(V)) if (Constant *CRHS = dyn_cast<Constant>(Idx)) - return Builder.CreateGEP(Builder.getInt8Ty(), CLHS, CRHS); + return Builder.CreatePtrAdd(CLHS, CRHS); // Do a quick scan to see if we have this GEP nearby. If so, reuse it. unsigned ScanLimit = 6; @@ -358,7 +354,7 @@ Value *SCEVExpander::expandAddToGEP(const SCEV *Offset, Value *V) { } // Emit a GEP. - return Builder.CreateGEP(Builder.getInt8Ty(), V, Idx, "scevgep"); + return Builder.CreatePtrAdd(V, Idx, "scevgep"); } /// PickMostRelevantLoop - Given two loops pick the one that's most relevant for @@ -2123,9 +2119,9 @@ Value *SCEVExpander::generateOverflowCheck(const SCEVAddRecExpr *AR, if (isa<PointerType>(ARTy)) { Value *NegMulV = Builder.CreateNeg(MulV); if (NeedPosCheck) - Add = Builder.CreateGEP(Builder.getInt8Ty(), StartValue, MulV); + Add = Builder.CreatePtrAdd(StartValue, MulV); if (NeedNegCheck) - Sub = Builder.CreateGEP(Builder.getInt8Ty(), StartValue, NegMulV); + Sub = Builder.CreatePtrAdd(StartValue, NegMulV); } else { if (NeedPosCheck) Add = Builder.CreateAdd(StartValue, MulV); diff --git a/contrib/llvm-project/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/contrib/llvm-project/llvm/lib/Transforms/Utils/SimplifyCFG.cpp index 7515e539e7fb..13eae549b2ce 100644 --- a/contrib/llvm-project/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/contrib/llvm-project/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -1770,6 +1770,11 @@ bool SimplifyCFGOpt::hoistSuccIdenticalTerminatorToSwitchOrIf( Locs.push_back(I1->getDebugLoc()); for (auto *OtherSuccTI : OtherSuccTIs) Locs.push_back(OtherSuccTI->getDebugLoc()); + // Also clone DPValues from the existing terminator, and all others (to + // duplicate existing hoisting behaviour). + NT->cloneDebugInfoFrom(I1); + for (Instruction *OtherSuccTI : OtherSuccTIs) + NT->cloneDebugInfoFrom(OtherSuccTI); NT->setDebugLoc(DILocation::getMergedLocations(Locs)); // PHIs created below will adopt NT's merged DebugLoc. @@ -3101,10 +3106,12 @@ bool SimplifyCFGOpt::SpeculativelyExecuteBB(BranchInst *BI, // %merge = select %cond, %two, %one // store %merge, %x.dest, !DIAssignID !2 // dbg.assign %merge, "x", ..., !2 - for (auto *DAI : at::getAssignmentMarkers(SpeculatedStore)) { - if (llvm::is_contained(DAI->location_ops(), OrigV)) - DAI->replaceVariableLocationOp(OrigV, S); - } + auto replaceVariable = [OrigV, S](auto *DbgAssign) { + if (llvm::is_contained(DbgAssign->location_ops(), OrigV)) + DbgAssign->replaceVariableLocationOp(OrigV, S); + }; + for_each(at::getAssignmentMarkers(SpeculatedStore), replaceVariable); + for_each(at::getDPVAssignmentMarkers(SpeculatedStore), replaceVariable); } // Metadata can be dependent on the condition we are hoisting above. @@ -3133,7 +3140,9 @@ bool SimplifyCFGOpt::SpeculativelyExecuteBB(BranchInst *BI, // instructions, in the same way that dbg.value intrinsics are dropped at the // end of this block. for (auto &It : make_range(ThenBB->begin(), ThenBB->end())) - It.dropDbgValues(); + for (DPValue &DPV : make_early_inc_range(It.getDbgValueRange())) + if (!DPV.isDbgAssign()) + It.dropOneDbgValue(&DPV); BB->splice(BI->getIterator(), ThenBB, ThenBB->begin(), std::prev(ThenBB->end())); @@ -5414,13 +5423,11 @@ static bool CasesAreContiguous(SmallVectorImpl<ConstantInt *> &Cases) { } static void createUnreachableSwitchDefault(SwitchInst *Switch, - DomTreeUpdater *DTU, - bool RemoveOrigDefaultBlock = true) { + DomTreeUpdater *DTU) { LLVM_DEBUG(dbgs() << "SimplifyCFG: switch default is dead.\n"); auto *BB = Switch->getParent(); auto *OrigDefaultBlock = Switch->getDefaultDest(); - if (RemoveOrigDefaultBlock) - OrigDefaultBlock->removePredecessor(BB); + OrigDefaultBlock->removePredecessor(BB); BasicBlock *NewDefaultBlock = BasicBlock::Create( BB->getContext(), BB->getName() + ".unreachabledefault", BB->getParent(), OrigDefaultBlock); @@ -5429,8 +5436,7 @@ static void createUnreachableSwitchDefault(SwitchInst *Switch, if (DTU) { SmallVector<DominatorTree::UpdateType, 2> Updates; Updates.push_back({DominatorTree::Insert, BB, &*NewDefaultBlock}); - if (RemoveOrigDefaultBlock && - !is_contained(successors(BB), OrigDefaultBlock)) + if (!is_contained(successors(BB), OrigDefaultBlock)) Updates.push_back({DominatorTree::Delete, BB, &*OrigDefaultBlock}); DTU->applyUpdates(Updates); } @@ -5612,28 +5618,10 @@ static bool eliminateDeadSwitchCases(SwitchInst *SI, DomTreeUpdater *DTU, Known.getBitWidth() - (Known.Zero | Known.One).popcount(); assert(NumUnknownBits <= Known.getBitWidth()); if (HasDefault && DeadCases.empty() && - NumUnknownBits < 64 /* avoid overflow */) { - uint64_t AllNumCases = 1ULL << NumUnknownBits; - if (SI->getNumCases() == AllNumCases) { - createUnreachableSwitchDefault(SI, DTU); - return true; - } - // When only one case value is missing, replace default with that case. - // Eliminating the default branch will provide more opportunities for - // optimization, such as lookup tables. - if (SI->getNumCases() == AllNumCases - 1) { - assert(NumUnknownBits > 1 && "Should be canonicalized to a branch"); - uint64_t MissingCaseVal = 0; - for (const auto &Case : SI->cases()) - MissingCaseVal ^= Case.getCaseValue()->getValue().getLimitedValue(); - auto *MissingCase = - cast<ConstantInt>(ConstantInt::get(Cond->getType(), MissingCaseVal)); - SwitchInstProfUpdateWrapper SIW(*SI); - SIW.addCase(MissingCase, SI->getDefaultDest(), SIW.getSuccessorWeight(0)); - createUnreachableSwitchDefault(SI, DTU, /*RemoveOrigDefaultBlock*/ false); - SIW.setSuccessorWeight(0, 0); - return true; - } + NumUnknownBits < 64 /* avoid overflow */ && + SI->getNumCases() == (1ULL << NumUnknownBits)) { + createUnreachableSwitchDefault(SI, DTU); + return true; } if (DeadCases.empty()) diff --git a/contrib/llvm-project/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp b/contrib/llvm-project/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp index 42e7c4006b42..0ed3324a27b6 100644 --- a/contrib/llvm-project/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp +++ b/contrib/llvm-project/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp @@ -1753,7 +1753,7 @@ Instruction *WidenIV::widenIVUse(WidenIV::NarrowIVDefUse DU, SCEVExpander &Rewri } // This narrow use can be widened by a sext if it's non-negative or its narrow - // def was widended by a sext. Same for zext. + // def was widened by a sext. Same for zext. auto canWidenBySExt = [&]() { return DU.NeverNegative || getExtendKind(DU.NarrowDef) == ExtendKind::Sign; }; diff --git a/contrib/llvm-project/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/contrib/llvm-project/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp index a7cd68e860e4..52eef9ab58a4 100644 --- a/contrib/llvm-project/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp +++ b/contrib/llvm-project/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp @@ -2495,13 +2495,17 @@ Value *LibCallSimplifier::optimizeLog(CallInst *Log, IRBuilderBase &B) { // log(pow(x,y)) -> y*log(x) AttributeList NoAttrs; - if (ArgLb == PowLb || ArgID == Intrinsic::pow) { + if (ArgLb == PowLb || ArgID == Intrinsic::pow || ArgID == Intrinsic::powi) { Value *LogX = Log->doesNotAccessMemory() ? B.CreateCall(Intrinsic::getDeclaration(Mod, LogID, Ty), Arg->getOperand(0), "log") : emitUnaryFloatFnCall(Arg->getOperand(0), TLI, LogNm, B, NoAttrs); - Value *MulY = B.CreateFMul(Arg->getArgOperand(1), LogX, "mul"); + Value *Y = Arg->getArgOperand(1); + // Cast exponent to FP if integer. + if (ArgID == Intrinsic::powi) + Y = B.CreateSIToFP(Y, Ty, "cast"); + Value *MulY = B.CreateFMul(Y, LogX, "mul"); // Since pow() may have side effects, e.g. errno, // dead code elimination may not be trusted to remove it. substituteInParent(Arg, MulY); diff --git a/contrib/llvm-project/llvm/lib/Transforms/Utils/ValueMapper.cpp b/contrib/llvm-project/llvm/lib/Transforms/Utils/ValueMapper.cpp index 71d0f09e4771..380541ffdd49 100644 --- a/contrib/llvm-project/llvm/lib/Transforms/Utils/ValueMapper.cpp +++ b/contrib/llvm-project/llvm/lib/Transforms/Utils/ValueMapper.cpp @@ -544,6 +544,16 @@ void Mapper::remapDPValue(DPValue &V) { V.setVariable(cast<DILocalVariable>(MappedVar)); V.setDebugLoc(DebugLoc(cast<DILocation>(MappedDILoc))); + bool IgnoreMissingLocals = Flags & RF_IgnoreMissingLocals; + + if (V.isDbgAssign()) { + auto *NewAddr = mapValue(V.getAddress()); + if (!IgnoreMissingLocals && !NewAddr) + V.setKillAddress(); + else if (NewAddr) + V.setAddress(NewAddr); + } + // Find Value operands and remap those. SmallVector<Value *, 4> Vals, NewVals; for (Value *Val : V.location_ops()) @@ -555,8 +565,6 @@ void Mapper::remapDPValue(DPValue &V) { if (Vals == NewVals) return; - bool IgnoreMissingLocals = Flags & RF_IgnoreMissingLocals; - // Otherwise, do some replacement. if (!IgnoreMissingLocals && llvm::any_of(NewVals, [&](Value *V) { return V == nullptr; })) { |