aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Stump <mrs@apple.com>2009-11-04 00:53:51 +0000
committerMike Stump <mrs@apple.com>2009-11-04 00:53:51 +0000
commitd0fe5366d4040545d5f72c547ae54e2c21e4cb68 (patch)
treef87df83d0d7fe12ed41258c1f5dcd195e4112ec5
parent082fb9ae304a25aa6be1f74d9b9720c52a96231e (diff)
Split out return adjustments in thunks from this adjustment in thunks
so the optimizer can tailcall into the return value adjustment thunk. This improves codesize for complex hierarchies. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@85988 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/CGCXX.cpp11
-rw-r--r--test/CodeGenCXX/virt.cpp20
2 files changed, 26 insertions, 5 deletions
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp
index e22670c37b..6dbc53d764 100644
--- a/lib/CodeGen/CGCXX.cpp
+++ b/lib/CodeGen/CGCXX.cpp
@@ -779,9 +779,17 @@ llvm::Constant *CodeGenFunction::GenerateCovariantThunk(llvm::Function *Fn,
QualType ArgType = MD->getThisType(getContext());
llvm::Value *Arg = Builder.CreateLoad(LocalDeclMap[ThisDecl], "this");
- if (nv_t || v_t)
+ if (nv_t || v_t) {
// Do the this adjustment.
+ const llvm::Type *OrigTy = Callee->getType();
Arg = DynamicTypeAdjust(Arg, nv_t, v_t);
+ if (nv_r || v_r) {
+ Callee = CGM.BuildCovariantThunk(MD, Extern, 0, 0, nv_r, v_r);
+ Callee = Builder.CreateBitCast(Callee, OrigTy);
+ nv_r = v_r = 0;
+ }
+ }
+
CallArgs.push_back(std::make_pair(RValue::get(Arg), ArgType));
for (FunctionDecl::param_const_iterator i = MD->param_begin(),
@@ -795,7 +803,6 @@ llvm::Constant *CodeGenFunction::GenerateCovariantThunk(llvm::Function *Fn,
CallArgs.push_back(std::make_pair(EmitCallArg(Arg, ArgType), ArgType));
}
- // FIXME: be sure to call the right function when we thunk to a thunk
RValue RV = EmitCall(CGM.getTypes().getFunctionInfo(ResultType, CallArgs),
Callee, CallArgs, MD);
if (nv_r || v_r) {
diff --git a/test/CodeGenCXX/virt.cpp b/test/CodeGenCXX/virt.cpp
index cd0d24fa70..7911940c6d 100644
--- a/test/CodeGenCXX/virt.cpp
+++ b/test/CodeGenCXX/virt.cpp
@@ -93,10 +93,10 @@ int main() {
// FIXME: This is the wrong thunk, but until these issues are fixed, better
// than nothing.
-// CHECK-LP64: __ZTcvn16_n72_v16_n32_N8test16_D4foo1Ev27:
-// CHECK-LP64-NEXT:Leh_func_begin33:
+// CHECK-LP64: __ZTcvn16_n72_v16_n32_N8test16_D4foo1Ev:
+// CHECK-LP64-NEXT:Leh_func_begin43:
// CHECK-LP64-NEXT: subq $24, %rsp
-// CHECK-LP64-NEXT:Llabel33:
+// CHECK-LP64-NEXT:Llabel43:
// CHECK-LP64-NEXT: movq %rdi, %rax
// CHECK-LP64-NEXT: movq %rax, 8(%rsp)
// CHECK-LP64-NEXT: movq 8(%rsp), %rax
@@ -108,6 +108,20 @@ int main() {
// CHECK-LP64-NEXT: addq %rax, %rcx
// CHECK-LP64-NEXT: movq %rcx, %rax
// CHECK-LP64-NEXT: movq %rax, %rdi
+// CHECK-LP64-NEXT: call __ZTch0_v16_n32_N8test16_D4foo1Ev
+// CHECK-LP64-NEXT: movq %rax, 16(%rsp)
+// CHECK-LP64-NEXT: movq 16(%rsp), %rax
+// CHECK-LP64-NEXT: addq $24, %rsp
+// CHECK-LP64-NEXT: ret
+
+// CHECK-LP64: __ZTch0_v16_n32_N8test16_D4foo1Ev:
+// CHECK-LP64-NEXT:Leh_func_begin44:
+// CHECK-LP64-NEXT: subq $24, %rsp
+// CHECK-LP64-NEXT:Llabel44:
+// CHECK-LP64-NEXT: movq %rdi, %rax
+// CHECK-LP64-NEXT: movq %rax, 8(%rsp)
+// CHECK-LP64-NEXT: movq 8(%rsp), %rax
+// CHECK-LP64-NEXT: movq %rax, %rdi
// CHECK-LP64-NEXT: call __ZN8test16_D4foo1Ev
// CHECK-LP64-NEXT: movq %rax, %rcx
// CHECK-LP64-NEXT: movabsq $16, %rdx