Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
tkelman committed Apr 12, 2016
1 parent d8e0c97 commit 376436b
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 0 deletions.
1 change: 1 addition & 0 deletions deps/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -728,6 +728,7 @@ $(eval $(call LLVM_PATCH,llvm-3.8.0_winshlib))
$(eval $(call LLVM_PATCH,llvm-3.8.0_threads))
# fix replutil test on unix
$(eval $(call LLVM_PATCH,llvm-D17165))
$(eval $(call LLVM_PATCH,llvm-D18583))
endif # LLVM_VER

ifeq ($(LLVM_VER),3.7.1)
Expand Down
99 changes: 99 additions & 0 deletions deps/llvm-D18583.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
From af289e04413504c3bdc252e08c3fe17bf7ea6dc8 Mon Sep 17 00:00:00 2001
From: Peter Collingbourne <peter@pcc.me.uk>
Date: Wed, 30 Mar 2016 22:05:13 +0000
Subject: [PATCH] Cloning: Reduce complexity of debug info cloning and fix
correctness issue.

Commit r260791 contained an error in that it would introduce a cross-module
reference in the old module. It also introduced O(N^2) complexity in the
module cloner by requiring the entire module to be visited for each function.
Fix both of these problems by avoiding use of the CloneDebugInfoMetadata
function (which is only designed to do intra-module cloning) and cloning
function-attached metadata in the same way that we clone all other metadata.

Differential Revision: http://reviews.llvm.org/D18583

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@264935 91177308-0d34-0410-b5e6-96231b3b80d8
---
include/llvm/Transforms/Utils/Cloning.h | 5 -----
lib/Transforms/Utils/CloneFunction.cpp | 13 +++++++++++--
lib/Transforms/Utils/CloneModule.cpp | 1 -
unittests/Transforms/Utils/Cloning.cpp | 6 ++++++
4 files changed, 17 insertions(+), 8 deletions(-)

diff --git a/include/llvm/Transforms/Utils/Cloning.h b/include/llvm/Transforms/Utils/Cloning.h
index 0bae2bd..4f006f2 100644
--- a/include/llvm/Transforms/Utils/Cloning.h
+++ b/include/llvm/Transforms/Utils/Cloning.h
@@ -130,11 +130,6 @@ Function *CloneFunction(const Function *F, ValueToValueMapTy &VMap,
bool ModuleLevelChanges,
ClonedCodeInfo *CodeInfo = nullptr);

-/// Clone the module-level debug info associated with OldFunc. The cloned data
-/// will point to NewFunc instead.
-void CloneDebugInfoMetadata(Function *NewFunc, const Function *OldFunc,
- ValueToValueMapTy &VMap);
-
/// Clone OldFunc into NewFunc, transforming the old arguments into references
/// to VMap values. Note that if NewFunc already has basic blocks, the ones
/// cloned into it will be added to the end of the function. This function
diff --git a/lib/Transforms/Utils/CloneFunction.cpp b/lib/Transforms/Utils/CloneFunction.cpp
index 05b0a17..8e1715a 100644
--- a/lib/Transforms/Utils/CloneFunction.cpp
+++ b/lib/Transforms/Utils/CloneFunction.cpp
@@ -119,6 +119,15 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
.addAttributes(NewFunc->getContext(), AttributeSet::FunctionIndex,
OldAttrs.getFnAttributes()));

+ SmallVector<std::pair<unsigned, MDNode *>, 1> MDs;
+ OldFunc->getAllMetadata(MDs);
+ for (auto MD : MDs)
+ NewFunc->setMetadata(
+ MD.first,
+ MapMetadata(MD.second, VMap,
+ ModuleLevelChanges ? RF_None : RF_NoModuleLevelChanges,
+ TypeMapper, Materializer));
+
// 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.
@@ -187,8 +196,8 @@ static void AddOperand(DICompileUnit *CU, DISubprogramArray SPs,

// Clone the module-level debug info associated with OldFunc. The cloned data
// will point to NewFunc instead.
-void llvm::CloneDebugInfoMetadata(Function *NewFunc, const Function *OldFunc,
- ValueToValueMapTy &VMap) {
+static void CloneDebugInfoMetadata(Function *NewFunc, const Function *OldFunc,
+ ValueToValueMapTy &VMap) {
DebugInfoFinder Finder;
Finder.processModule(*OldFunc->getParent());

diff --git a/lib/Transforms/Utils/CloneModule.cpp b/lib/Transforms/Utils/CloneModule.cpp
index 494e275..929f51b 100644
--- a/lib/Transforms/Utils/CloneModule.cpp
+++ b/lib/Transforms/Utils/CloneModule.cpp
@@ -138,7 +138,6 @@ std::unique_ptr<Module> llvm::CloneModule(
VMap[&*J] = &*DestI++;
}

- CloneDebugInfoMetadata(F, &*I, VMap);
SmallVector<ReturnInst*, 8> Returns; // Ignore returns cloned.
CloneFunctionInto(F, &*I, VMap, /*ModuleLevelChanges=*/true, Returns);
}
diff --git a/unittests/Transforms/Utils/Cloning.cpp b/unittests/Transforms/Utils/Cloning.cpp
index b761e4e..f06a20f 100644
--- a/unittests/Transforms/Utils/Cloning.cpp
+++ b/unittests/Transforms/Utils/Cloning.cpp
@@ -464,6 +464,12 @@ TEST_F(CloneModule, Verify) {
EXPECT_FALSE(verifyModule(*NewM));
}

+TEST_F(CloneModule, OldModuleUnchanged) {
+ DebugInfoFinder Finder;
+ Finder.processModule(*OldM);
+ EXPECT_EQ(1U, Finder.subprogram_count());
+}
+
TEST_F(CloneModule, Subprogram) {
Function *NewF = NewM->getFunction("f");
DISubprogram *SP = NewF->getSubprogram();

0 comments on commit 376436b

Please sign in to comment.