diff options
author | Artem Pianykh <artem.pyanykh@gmail.com> | 2024-11-20 23:36:55 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-11-20 23:36:55 +0000 |
commit | f5002a0faee76609a6b054d579e1e09312ab9ac9 (patch) | |
tree | 039dfea6a41402cd84f245d72b332b2c6b2a15a0 /llvm/lib/Transforms/Utils/CloneFunction.cpp | |
parent | ecda14069f0e98f6ec06ca98277505f4798f486e (diff) | |
download | llvm-f5002a0faee76609a6b054d579e1e09312ab9ac9.zip llvm-f5002a0faee76609a6b054d579e1e09312ab9ac9.tar.gz llvm-f5002a0faee76609a6b054d579e1e09312ab9ac9.tar.bz2 |
[Utils] Extract CollectDebugInfoForCloning from CloneFunctionInto (#114537)
Summary:
Consolidate the logic in a single function. We do an extra pass over
Instructions but this is necessary to untangle things and extract
metadata cloning in a future diff.
Test Plan:
```
$ ninja check-llvm-unit check-llvm
[211/213] Running the LLVM regression tests
Testing Time: 106.06s
Total Discovered Tests: 62601
Skipped : 17 (0.03%)
Unsupported : 2518 (4.02%)
Passed : 59911 (95.70%)
Expectedly Failed: 155 (0.25%)
[212/213] Running lit suite
Testing Time: 12.47s
Total Discovered Tests: 8474
Skipped: 17 (0.20%)
Passed : 8457 (99.80%)
```
Extracted from #109032 (commit 3) (there are more refactors and cleanups
in subsequent commits)
Diffstat (limited to 'llvm/lib/Transforms/Utils/CloneFunction.cpp')
-rw-r--r-- | llvm/lib/Transforms/Utils/CloneFunction.cpp | 59 |
1 files changed, 39 insertions, 20 deletions
diff --git a/llvm/lib/Transforms/Utils/CloneFunction.cpp b/llvm/lib/Transforms/Utils/CloneFunction.cpp index 4c8a555..cb6a4e3 100644 --- a/llvm/lib/Transforms/Utils/CloneFunction.cpp +++ b/llvm/lib/Transforms/Utils/CloneFunction.cpp @@ -23,6 +23,7 @@ #include "llvm/IR/DebugInfo.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Function.h" +#include "llvm/IR/InstIterator.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/LLVMContext.h" @@ -136,6 +137,26 @@ void llvm::CloneFunctionAttributesInto(Function *NewFunc, OldAttrs.getRetAttrs(), NewArgAttrs)); } +DISubprogram *llvm::CollectDebugInfoForCloning(const Function &F, + CloneFunctionChangeType Changes, + DebugInfoFinder &DIFinder) { + DISubprogram *SPClonedWithinModule = nullptr; + if (Changes < CloneFunctionChangeType::DifferentModule) { + SPClonedWithinModule = F.getSubprogram(); + } + if (SPClonedWithinModule) + DIFinder.processSubprogram(SPClonedWithinModule); + + const Module *M = F.getParent(); + if (Changes != CloneFunctionChangeType::ClonedModule && M) { + // Inspect instructions to process e.g. DILexicalBlocks of inlined functions + for (const auto &I : instructions(F)) + DIFinder.processInstruction(*M, I); + } + + return SPClonedWithinModule; +} + // Clone OldFunc into NewFunc, transforming the old arguments into references to // VMap values. void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc, @@ -168,23 +189,19 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc, // duplicate instructions and then freeze them in the MD map. We also record // information about dbg.value and dbg.declare to avoid duplicating the // types. - std::optional<DebugInfoFinder> DIFinder; + DebugInfoFinder DIFinder; // Track the subprogram attachment that needs to be cloned to fine-tune the // mapping within the same module. - DISubprogram *SPClonedWithinModule = nullptr; if (Changes < CloneFunctionChangeType::DifferentModule) { + // Need to find subprograms, types, and compile units. + assert((NewFunc->getParent() == nullptr || NewFunc->getParent() == OldFunc->getParent()) && "Expected NewFunc to have the same parent, or no parent"); - - // Need to find subprograms, types, and compile units. - DIFinder.emplace(); - - SPClonedWithinModule = OldFunc->getSubprogram(); - if (SPClonedWithinModule) - DIFinder->processSubprogram(SPClonedWithinModule); } else { + // Need to find all the compile units. + assert((NewFunc->getParent() == nullptr || NewFunc->getParent() != OldFunc->getParent()) && "Expected NewFunc to have different parents, or no parent"); @@ -192,20 +209,22 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc, if (Changes == CloneFunctionChangeType::DifferentModule) { assert(NewFunc->getParent() && "Need parent of new function to maintain debug info invariants"); - - // Need to find all the compile units. - DIFinder.emplace(); } } + DISubprogram *SPClonedWithinModule = + CollectDebugInfoForCloning(*OldFunc, Changes, DIFinder); + // Loop over all of the basic blocks in the function, cloning them as // appropriate. Note that we save BE this way in order to handle cloning of // recursive functions into themselves. for (const BasicBlock &BB : *OldFunc) { // Create a new basic block and copy instructions into it! - BasicBlock *CBB = CloneBasicBlock(&BB, VMap, NameSuffix, NewFunc, CodeInfo, - DIFinder ? &*DIFinder : nullptr); + // NOTE: don't pass DIFinder because instructions' debug info was processed + // in ProcessSubprogramAttachment. This will be cleaned up further. + BasicBlock *CBB = + CloneBasicBlock(&BB, VMap, NameSuffix, NewFunc, CodeInfo, nullptr); // Add basic block mapping. VMap[&BB] = CBB; @@ -228,7 +247,7 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc, } if (Changes < CloneFunctionChangeType::DifferentModule && - DIFinder->subprogram_count() > 0) { + DIFinder.subprogram_count() > 0) { // Turn on module-level changes, since we need to clone (some of) the // debug info metadata. // @@ -243,7 +262,7 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc, // Avoid cloning types, compile units, and (other) subprograms. SmallPtrSet<const DISubprogram *, 16> MappedToSelfSPs; - for (DISubprogram *ISP : DIFinder->subprograms()) { + for (DISubprogram *ISP : DIFinder.subprograms()) { if (ISP != SPClonedWithinModule) { mapToSelfIfNew(ISP); MappedToSelfSPs.insert(ISP); @@ -251,16 +270,16 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc, } // If a subprogram isn't going to be cloned skip its lexical blocks as well. - for (DIScope *S : DIFinder->scopes()) { + for (DIScope *S : DIFinder.scopes()) { auto *LScope = dyn_cast<DILocalScope>(S); if (LScope && MappedToSelfSPs.count(LScope->getSubprogram())) mapToSelfIfNew(S); } - for (DICompileUnit *CU : DIFinder->compile_units()) + for (DICompileUnit *CU : DIFinder.compile_units()) mapToSelfIfNew(CU); - for (DIType *Type : DIFinder->types()) + for (DIType *Type : DIFinder.types()) mapToSelfIfNew(Type); } else { assert(!SPClonedWithinModule && @@ -314,7 +333,7 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc, SmallPtrSet<const void *, 8> Visited; for (auto *Operand : NMD->operands()) Visited.insert(Operand); - for (auto *Unit : DIFinder->compile_units()) { + for (auto *Unit : DIFinder.compile_units()) { MDNode *MappedUnit = MapMetadata(Unit, VMap, RF_None, TypeMapper, Materializer); if (Visited.insert(MappedUnit).second) |