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.

llvm-svn: 194357
This commit is contained in:
Rafael Espindola 2013-11-10 19:04:30 +00:00
parent 760c1e0b0a
commit 732c99c4ae
2 changed files with 22 additions and 10 deletions

View File

@ -181,8 +181,20 @@ void CodeGenModule::applyReplacements() {
llvm::GlobalValue *Entry = GetGlobalValue(MangledName);
if (!Entry)
continue;
Entry->replaceAllUsesWith(Replacement);
Entry->eraseFromParent();
llvm::Function *OldF = cast<llvm::Function>(Entry);
llvm::Function *NewF = dyn_cast<llvm::Function>(Replacement);
if (!NewF) {
llvm::ConstantExpr *CE = cast<llvm::ConstantExpr>(Replacement);
assert(CE->getOpcode() == llvm::Instruction::BitCast ||
CE->getOpcode() == llvm::Instruction::GetElementPtr);
NewF = cast<llvm::Function>(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();
}
}

View File

@ -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::<anonymous namespace>::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::<anonymous namespace>::C"* %this) unnamed_addr
// CHECK: invoke void @_ZN5test31BD2Ev(
// CHECK: call void @_ZN5test31AD2Ev(
// CHECK: ret void
// CHECK: declare void @_ZN5test31BD2Ev(
// CHECK: declare void @_ZN5test31AD2Ev(