Revert r237385, "[CodeGen] Reuse stack space from unused function results"
It broke clang stage2, at least tblgen. llvm-svn: 237418
This commit is contained in:
parent
95a2a7e612
commit
1a6756bba0
|
@ -3077,18 +3077,10 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
|
||||||
// If the call returns a temporary with struct return, create a temporary
|
// If the call returns a temporary with struct return, create a temporary
|
||||||
// alloca to hold the result, unless one is given to us.
|
// alloca to hold the result, unless one is given to us.
|
||||||
llvm::Value *SRetPtr = nullptr;
|
llvm::Value *SRetPtr = nullptr;
|
||||||
size_t UnusedReturnSize = 0;
|
|
||||||
if (RetAI.isIndirect() || RetAI.isInAlloca()) {
|
if (RetAI.isIndirect() || RetAI.isInAlloca()) {
|
||||||
SRetPtr = ReturnValue.getValue();
|
SRetPtr = ReturnValue.getValue();
|
||||||
if (!SRetPtr) {
|
if (!SRetPtr)
|
||||||
SRetPtr = CreateMemTemp(RetTy);
|
SRetPtr = CreateMemTemp(RetTy);
|
||||||
if (HaveInsertPoint()) {
|
|
||||||
uint64_t size =
|
|
||||||
CGM.getDataLayout().getTypeAllocSize(ConvertTypeForMem(RetTy));
|
|
||||||
if (EmitLifetimeStart(size, SRetPtr))
|
|
||||||
UnusedReturnSize = size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (IRFunctionArgs.hasSRetArg()) {
|
if (IRFunctionArgs.hasSRetArg()) {
|
||||||
IRCallArgs[IRFunctionArgs.getSRetArgNo()] = SRetPtr;
|
IRCallArgs[IRFunctionArgs.getSRetArgNo()] = SRetPtr;
|
||||||
} else {
|
} else {
|
||||||
|
@ -3420,10 +3412,6 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
|
||||||
// insertion point; this allows the rest of IRgen to discard
|
// insertion point; this allows the rest of IRgen to discard
|
||||||
// unreachable code.
|
// unreachable code.
|
||||||
if (CS.doesNotReturn()) {
|
if (CS.doesNotReturn()) {
|
||||||
if (UnusedReturnSize)
|
|
||||||
EmitLifetimeEnd(llvm::ConstantInt::get(Int64Ty, UnusedReturnSize),
|
|
||||||
SRetPtr);
|
|
||||||
|
|
||||||
Builder.CreateUnreachable();
|
Builder.CreateUnreachable();
|
||||||
Builder.ClearInsertionPoint();
|
Builder.ClearInsertionPoint();
|
||||||
|
|
||||||
|
@ -3452,13 +3440,8 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
|
||||||
RValue Ret = [&] {
|
RValue Ret = [&] {
|
||||||
switch (RetAI.getKind()) {
|
switch (RetAI.getKind()) {
|
||||||
case ABIArgInfo::InAlloca:
|
case ABIArgInfo::InAlloca:
|
||||||
case ABIArgInfo::Indirect: {
|
case ABIArgInfo::Indirect:
|
||||||
RValue ret = convertTempToRValue(SRetPtr, RetTy, SourceLocation());
|
return convertTempToRValue(SRetPtr, RetTy, SourceLocation());
|
||||||
if (UnusedReturnSize)
|
|
||||||
EmitLifetimeEnd(llvm::ConstantInt::get(Int64Ty, UnusedReturnSize),
|
|
||||||
SRetPtr);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
case ABIArgInfo::Ignore:
|
case ABIArgInfo::Ignore:
|
||||||
// If we are ignoring an argument that had a result, make sure to
|
// If we are ignoring an argument that had a result, make sure to
|
||||||
|
|
|
@ -1,125 +0,0 @@
|
||||||
// RUN: %clang -target armv7l-unknown-linux-gnueabihf -S %s -o - -emit-llvm -O1 -disable-llvm-optzns | FileCheck %s
|
|
||||||
|
|
||||||
// Stack should be reused when possible, no need to allocate two separate slots
|
|
||||||
// if they have disjoint lifetime.
|
|
||||||
|
|
||||||
// Sizes of objects are related to previously existed threshold of 32. In case
|
|
||||||
// of S_large stack size is rounded to 40 bytes.
|
|
||||||
|
|
||||||
// 32B
|
|
||||||
struct S_small {
|
|
||||||
int a[8];
|
|
||||||
};
|
|
||||||
|
|
||||||
// 36B
|
|
||||||
struct S_large {
|
|
||||||
int a[9];
|
|
||||||
};
|
|
||||||
|
|
||||||
extern S_small foo_small();
|
|
||||||
extern S_large foo_large();
|
|
||||||
extern void bar_small(S_small*);
|
|
||||||
extern void bar_large(S_large*);
|
|
||||||
|
|
||||||
// Prevent mangling of function names.
|
|
||||||
extern "C" {
|
|
||||||
|
|
||||||
void small_rvoed_unnamed_temporary_object() {
|
|
||||||
// CHECK-LABEL: define void @small_rvoed_unnamed_temporary_object
|
|
||||||
// CHECK: call void @llvm.lifetime.start
|
|
||||||
// CHECK: call void @_Z9foo_smallv
|
|
||||||
// CHECK: call void @llvm.lifetime.end
|
|
||||||
// CHECK: call void @llvm.lifetime.start
|
|
||||||
// CHECK: call void @_Z9foo_smallv
|
|
||||||
// CHECK: call void @llvm.lifetime.end
|
|
||||||
|
|
||||||
foo_small();
|
|
||||||
foo_small();
|
|
||||||
}
|
|
||||||
|
|
||||||
void large_rvoed_unnamed_temporary_object() {
|
|
||||||
// CHECK-LABEL: define void @large_rvoed_unnamed_temporary_object
|
|
||||||
// CHECK: call void @llvm.lifetime.start
|
|
||||||
// CHECK: call void @_Z9foo_largev
|
|
||||||
// CHECK: call void @llvm.lifetime.end
|
|
||||||
// CHECK: call void @llvm.lifetime.start
|
|
||||||
// CHECK: call void @_Z9foo_largev
|
|
||||||
// CHECK: call void @llvm.lifetime.end
|
|
||||||
|
|
||||||
foo_large();
|
|
||||||
foo_large();
|
|
||||||
}
|
|
||||||
|
|
||||||
void small_rvoed_named_temporary_object() {
|
|
||||||
// CHECK-LABEL: define void @small_rvoed_named_temporary_object
|
|
||||||
// CHECK: call void @llvm.lifetime.start
|
|
||||||
// CHECK: call void @_Z9foo_smallv
|
|
||||||
// CHECK: call void @llvm.lifetime.end
|
|
||||||
// CHECK: call void @llvm.lifetime.start
|
|
||||||
// CHECK: call void @_Z9foo_smallv
|
|
||||||
// CHECK: call void @llvm.lifetime.end
|
|
||||||
|
|
||||||
{
|
|
||||||
S_small s = foo_small();
|
|
||||||
}
|
|
||||||
{
|
|
||||||
S_small s = foo_small();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void large_rvoed_named_temporary_object() {
|
|
||||||
// CHECK-LABEL: define void @large_rvoed_named_temporary_object
|
|
||||||
// CHECK: call void @llvm.lifetime.start
|
|
||||||
// CHECK: call void @_Z9foo_largev
|
|
||||||
// CHECK: call void @llvm.lifetime.end
|
|
||||||
// CHECK: call void @llvm.lifetime.start
|
|
||||||
// CHECK: call void @_Z9foo_largev
|
|
||||||
// CHECK: call void @llvm.lifetime.end
|
|
||||||
|
|
||||||
{
|
|
||||||
S_large s = foo_large();
|
|
||||||
}
|
|
||||||
{
|
|
||||||
S_large s = foo_large();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void small_auto_object() {
|
|
||||||
// CHECK-LABEL: define void @small_auto_object
|
|
||||||
// CHECK: call void @llvm.lifetime.start
|
|
||||||
// CHECK: call void @_Z9bar_smallP7S_small
|
|
||||||
// CHECK: call void @llvm.lifetime.end
|
|
||||||
// CHECK: call void @llvm.lifetime.start
|
|
||||||
// CHECK: call void @_Z9bar_smallP7S_small
|
|
||||||
// CHECK: call void @llvm.lifetime.end
|
|
||||||
|
|
||||||
{
|
|
||||||
S_small s;
|
|
||||||
bar_small(&s);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
S_small s;
|
|
||||||
bar_small(&s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void large_auto_object() {
|
|
||||||
// CHECK-LABEL: define void @large_auto_object
|
|
||||||
// CHECK: call void @llvm.lifetime.start
|
|
||||||
// CHECK: call void @_Z9bar_largeP7S_large
|
|
||||||
// CHECK: call void @llvm.lifetime.end
|
|
||||||
// CHECK: call void @llvm.lifetime.start
|
|
||||||
// CHECK: call void @_Z9bar_largeP7S_large
|
|
||||||
// CHECK: call void @llvm.lifetime.end
|
|
||||||
|
|
||||||
{
|
|
||||||
S_large s;
|
|
||||||
bar_large(&s);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
S_large s;
|
|
||||||
bar_large(&s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in New Issue