[ms-cxxabi] Use inalloca on win32 when passing non-trivial C++ objects

When a non-trivial parameter is present, clang now gathers up all the
parameters that lack inreg and puts them into a packed struct.  MSVC
always aligns each parameter to 4 bytes and no more, so this is a pretty
simple struct to lay out.

On win64, non-trivial records are passed indirectly.  Prior to this
change, clang was incorrectly using byval on win64.

I'm able to self-host a working clang with this change and additional
LLVM patches.

Reviewers: rsmith

Differential Revision: http://llvm-reviews.chandlerc.com/D2636

llvm-svn: 200597
This commit is contained in:
Reid Kleckner
2014-02-01 00:04:45 +00:00
parent f5b76518c9
commit 314ef7bafd
17 changed files with 699 additions and 129 deletions

View File

@@ -276,6 +276,14 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) {
if (CGM.getCodeGenOpts().EmitDeclMetadata)
EmitDeclMetadata();
for (SmallVectorImpl<std::pair<llvm::Instruction *, llvm::Value *> >::iterator
I = DeferredReplacements.begin(),
E = DeferredReplacements.end();
I != E; ++I) {
I->first->replaceAllUsesWith(I->second);
I->first->eraseFromParent();
}
}
/// ShouldInstrumentFunction - Return true if the current function should be
@@ -592,6 +600,14 @@ void CodeGenFunction::StartFunction(GlobalDecl GD,
// Indirect aggregate return; emit returned value directly into sret slot.
// This reduces code size, and affects correctness in C++.
ReturnValue = CurFn->arg_begin();
} else if (CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::InAlloca &&
!hasScalarEvaluationKind(CurFnInfo->getReturnType())) {
// Load the sret pointer from the argument struct and return into that.
unsigned Idx = CurFnInfo->getReturnInfo().getInAllocaFieldIndex();
llvm::Function::arg_iterator EI = CurFn->arg_end();
--EI;
llvm::Value *Addr = Builder.CreateStructGEP(EI, Idx);
ReturnValue = Builder.CreateLoad(Addr, "agg.result");
} else {
ReturnValue = CreateIRTemp(RetTy, "retval");