From 90f535f3f6d57403ce3d9177745900b2d015dcee Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sun, 10 Nov 2013 19:04:30 +0000 Subject: [PATCH] Keep the old function order in CodeGenModule::applyReplacements. The original decls are created when used. The replacements are created at the end of the TU in reverse order. This makes the original order far better for testing. This is particularly important since the replacement logic could be used even when -mconstructor-aliases is not used, but that would make many tests hard to read. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@194357 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CodeGenModule.cpp | 16 ++++++++++++++-- test/CodeGenCXX/destructors.cpp | 16 ++++++++-------- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 74f3bbb045..ee70080743 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -181,8 +181,20 @@ void CodeGenModule::applyReplacements() { llvm::GlobalValue *Entry = GetGlobalValue(MangledName); if (!Entry) continue; - Entry->replaceAllUsesWith(Replacement); - Entry->eraseFromParent(); + llvm::Function *OldF = cast(Entry); + llvm::Function *NewF = dyn_cast(Replacement); + if (!NewF) { + llvm::ConstantExpr *CE = cast(Replacement); + assert(CE->getOpcode() == llvm::Instruction::BitCast || + CE->getOpcode() == llvm::Instruction::GetElementPtr); + NewF = cast(CE->getOperand(0)); + } + + // Replace old with new, but keep the old order. + OldF->replaceAllUsesWith(Replacement); + NewF->removeFromParent(); + OldF->getParent()->getFunctionList().insertAfter(OldF, NewF); + OldF->eraseFromParent(); } } diff --git a/test/CodeGenCXX/destructors.cpp b/test/CodeGenCXX/destructors.cpp index 5b29ce5de4..59c97b7dca 100644 --- a/test/CodeGenCXX/destructors.cpp +++ b/test/CodeGenCXX/destructors.cpp @@ -36,13 +36,13 @@ namespace PR7526 { struct allocator_derived : allocator { }; + // CHECK-LABEL: define void @_ZN6PR75263fooEv() + // CHECK: call void {{.*}} @_ZN6PR75269allocatorD2Ev + // CHECK-LABEL: define void @_ZN6PR75269allocatorD2Ev(%"struct.PR7526::allocator"* %this) unnamed_addr // CHECK: call void @__cxa_call_unexpected allocator::~allocator() throw() { foo(); } - // CHECK-LABEL: define void @_ZN6PR75263fooEv() - // CHECK: call void {{.*}} @_ZN6PR75269allocatorD2Ev - void foo() { allocator_derived ad; } @@ -393,16 +393,16 @@ namespace test10 { // CHECK: call void @_ZN5test312_GLOBAL__N_11DD0Ev( // CHECK: ret void - // CHECK-LABEL: define internal void @_ZN5test312_GLOBAL__N_11CD2Ev(%"struct.test3::::C"* %this) unnamed_addr - // CHECK: invoke void @_ZN5test31BD2Ev( - // CHECK: call void @_ZN5test31AD2Ev( - // CHECK: ret void - // CHECK-LABEL: define internal void @_ZThn8_N5test312_GLOBAL__N_11CD1Ev( // CHECK: getelementptr inbounds i8* {{.*}}, i64 -8 // CHECK: call void @_ZN5test312_GLOBAL__N_11CD2Ev( // CHECK: ret void + // CHECK-LABEL: define internal void @_ZN5test312_GLOBAL__N_11CD2Ev(%"struct.test3::::C"* %this) unnamed_addr + // CHECK: invoke void @_ZN5test31BD2Ev( + // CHECK: call void @_ZN5test31AD2Ev( + // CHECK: ret void + // CHECK: declare void @_ZN5test31BD2Ev( // CHECK: declare void @_ZN5test31AD2Ev( -- 2.40.0