Commit e26c24b8 authored by Erik Pilkington's avatar Erik Pilkington
Browse files

Revert "[IRGen] Emit lifetime intrinsics around temporary aggregate argument allocas"

This reverts commit fafc6e4f.

Should fix ppc stage2 failure: http://lab.llvm.org:8011/builders/clang-ppc64be-linux-multistage/builds/23546

Conflicts:
	clang/lib/CodeGen/CGCall.cpp
parent bfaf5357
Loading
Loading
Loading
Loading
+1 −21
Original line number Diff line number Diff line
@@ -3692,24 +3692,7 @@ void CodeGenFunction::EmitCallArg(CallArgList &args, const Expr *E,
    return;
  }

  AggValueSlot ArgSlot = AggValueSlot::ignored();
  Address ArgSlotAlloca = Address::invalid();
  if (hasAggregateEvaluationKind(E->getType())) {
    ArgSlot = CreateAggTemp(E->getType(), "agg.tmp", &ArgSlotAlloca);

    // Emit a lifetime start/end for this temporary. If the type has a
    // destructor, then we need to keep it alive. FIXME: We should still be able
    // to end the lifetime after the destructor returns.
    if (!E->getType().isDestructedType()) {
      uint64_t size =
          CGM.getDataLayout().getTypeAllocSize(ConvertTypeForMem(E->getType()));
      if (auto *lifetimeSize =
              EmitLifetimeStart(size, ArgSlotAlloca.getPointer()))
        args.addLifetimeCleanup({ArgSlotAlloca.getPointer(), lifetimeSize});
    }
  }

  args.add(EmitAnyExpr(E, ArgSlot), type);
  args.add(EmitAnyExprToTemp(E), type);
}

QualType CodeGenFunction::getVarArgType(const Expr *Arg) {
@@ -4810,9 +4793,6 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
  for (CallLifetimeEnd &LifetimeEnd : CallLifetimeEndAfterCall)
    LifetimeEnd.Emit(*this, /*Flags=*/{});

  for (auto &LT : CallArgs.getLifetimeCleanups())
    EmitLifetimeEnd(LT.Size, LT.Addr);

  return Ret;
}

+0 −20
Original line number Diff line number Diff line
@@ -283,11 +283,6 @@ public:
    llvm::Instruction *IsActiveIP;
  };

  struct EndLifetimeInfo {
    llvm::Value *Addr;
    llvm::Value *Size;
  };

  void add(RValue rvalue, QualType type) { push_back(CallArg(rvalue, type)); }

  void addUncopiedAggregate(LValue LV, QualType type) {
@@ -304,9 +299,6 @@ public:
    CleanupsToDeactivate.insert(CleanupsToDeactivate.end(),
                                other.CleanupsToDeactivate.begin(),
                                other.CleanupsToDeactivate.end());
    LifetimeCleanups.insert(LifetimeCleanups.end(),
                            other.LifetimeCleanups.begin(),
                            other.LifetimeCleanups.end());
    assert(!(StackBase && other.StackBase) && "can't merge stackbases");
    if (!StackBase)
      StackBase = other.StackBase;
@@ -346,14 +338,6 @@ public:
  /// memory.
  bool isUsingInAlloca() const { return StackBase; }

  void addLifetimeCleanup(EndLifetimeInfo Info) {
    LifetimeCleanups.push_back(Info);
  }

  ArrayRef<EndLifetimeInfo> getLifetimeCleanups() const {
    return LifetimeCleanups;
  }

private:
  SmallVector<Writeback, 1> Writebacks;

@@ -362,10 +346,6 @@ private:
  /// occurs.
  SmallVector<CallArgCleanup, 1> CleanupsToDeactivate;

  /// Lifetime information needed to call llvm.lifetime.end for any temporary
  /// argument allocas.
  SmallVector<EndLifetimeInfo, 2> LifetimeCleanups;

  /// The stacksave call.  It dominates all of the argument evaluation.
  llvm::CallInst *StackBase;
};
+0 −83
Original line number Diff line number Diff line
// RUN: %clang -cc1                  -triple x86_64-apple-macos -O1 -disable-llvm-passes %s -S -emit-llvm -o - | FileCheck %s --implicit-check-not=llvm.lifetime
// RUN: %clang -cc1 -xc++ -std=c++17 -triple x86_64-apple-macos -O1 -disable-llvm-passes %s -S -emit-llvm -o - | FileCheck %s --implicit-check-not=llvm.lifetime --check-prefix=CHECK --check-prefix=CXX
// RUN: %clang -cc1 -xobjective-c    -triple x86_64-apple-macos -O1 -disable-llvm-passes %s -S -emit-llvm -o - | FileCheck %s --implicit-check-not=llvm.lifetime --check-prefix=CHECK --check-prefix=OBJC

typedef struct { int x[100]; } aggregate;

#ifdef __cplusplus
extern "C" {
#endif

void takes_aggregate(aggregate);
aggregate gives_aggregate();

// CHECK-LABEL: define void @t1
void t1() {
  takes_aggregate(gives_aggregate());

  // CHECK: [[AGGTMP:%.*]] = alloca %struct.aggregate, align 8
  // CHECK: [[CAST:%.*]] = bitcast %struct.aggregate* [[AGGTMP]] to i8*
  // CHECK: call void @llvm.lifetime.start.p0i8(i64 400, i8* [[CAST]])
  // CHECK: call void{{.*}} @gives_aggregate(%struct.aggregate* sret [[AGGTMP]])
  // CHECK: call void @takes_aggregate(%struct.aggregate* byval(%struct.aggregate) align 8 [[AGGTMP]])
  // CHECK: [[CAST:%.*]] = bitcast %struct.aggregate* [[AGGTMP]] to i8*
  // CHECK: call void @llvm.lifetime.end.p0i8(i64 400, i8* [[CAST]])
}

// CHECK: declare {{.*}}llvm.lifetime.start
// CHECK: declare {{.*}}llvm.lifetime.end

#ifdef __cplusplus
// CXX: define void @t2
void t2() {
  struct S {
    S(aggregate) {}
  };
  S{gives_aggregate()};

  // CXX: [[AGG:%.*]] = alloca %struct.aggregate
  // CXX: call void @llvm.lifetime.start.p0i8(i64 400, i8*
  // CXX: call void @gives_aggregate(%struct.aggregate* sret [[AGG]])
  // CXX: call void @_ZZ2t2EN1SC1E9aggregate(%struct.S* {{.*}}, %struct.aggregate* byval(%struct.aggregate) align 8 [[AGG]])
  // CXX: call void @llvm.lifetime.end.p0i8(i64 400, i8*
}

struct Dtor {
  ~Dtor();
};

void takes_dtor(Dtor);
Dtor gives_dtor();

// CXX: define void @t3
void t3() {
  takes_dtor(gives_dtor());

  // CXX-NOT @llvm.lifetime
  // CXX: ret void
}

#endif

#ifdef __OBJC__

@interface X
-m:(aggregate)x;
@end

// OBJC: define void @t4
void t4(X *x) {
  [x m: gives_aggregate()];

  // OBJC: [[AGG:%.*]] = alloca %struct.aggregate
  // OBJC: call void @llvm.lifetime.start.p0i8(i64 400, i8*
  // OBJC: call void{{.*}} @gives_aggregate(%struct.aggregate* sret [[AGGTMP]])
  // OBJC: call {{.*}}@objc_msgSend
  // OBJC: call void @llvm.lifetime.end.p0i8(i64 400, i8*
}

#endif

#ifdef __cplusplus
}
#endif
+0 −19
Original line number Diff line number Diff line
// RUN: %clang_cc1 -triple amdgcn-amd-amdhsa -emit-llvm -O3 -disable-llvm-passes -o - %s | FileCheck %s

struct A {
  float x, y, z, w;
};

void foo(A a);

// CHECK-LABEL: @_Z4testv
// CHECK: %[[lvar:.*]] = alloca %struct.A, align 4, addrspace(5)
// CHECK: %[[atmp:.*]] = alloca %struct.A, align 4, addrspace(5)
// CHECK: %[[lcst:.*]] = bitcast %struct.A addrspace(5)* %[[lvar]] to i8 addrspace(5)*
// CHECK: call void @llvm.lifetime.start.p5i8(i64 16, i8 addrspace(5)* %[[lcst]]
// CHECK: %[[acst:.*]] = bitcast %struct.A addrspace(5)* %[[atmp]] to i8 addrspace(5)*
// CHECK: call void @llvm.lifetime.start.p5i8(i64 16, i8 addrspace(5)* %[[acst]]
void test() {
  A a;
  foo(a);
}
+0 −9
Original line number Diff line number Diff line
@@ -26,8 +26,6 @@ const char * f(S s)
// CHECK: [[T2:%.*]] = alloca %class.T, align 4
// CHECK: [[T3:%.*]] = alloca %class.T, align 4
//
// CHECK: [[AGG:%.*]] = alloca %class.S, align 4
//
// FIXME: We could defer starting the lifetime of the return object of concat
// until the call.
// CHECK: [[T1i8:%.*]] = bitcast %class.T* [[T1]] to i8*
@@ -39,15 +37,8 @@ const char * f(S s)
//
// CHECK: [[T3i8:%.*]] = bitcast %class.T* [[T3]] to i8*
// CHECK: call void @llvm.lifetime.start.p0i8(i64 16, i8* [[T3i8]])
//
// CHECK: [[AGGi8:%.*]] = bitcast %class.S* [[AGG]] to i8*
// CHECK: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[AGGi8]])
//
// CHECK: [[T5:%.*]] = call %class.T* @_ZN1TC1E1S(%class.T* [[T3]], [2 x i32] %{{.*}})
//
// CHECK: [[AGGi8:%.*]] = bitcast %class.S* {{.*}} to i8*
// CHECK: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[AGGi8]])
//
// CHECK: call void @_ZNK1T6concatERKS_(%class.T* sret [[T1]], %class.T* [[T2]], %class.T* dereferenceable(16) [[T3]])
// CHECK: [[T6:%.*]] = call i8* @_ZNK1T3strEv(%class.T* [[T1]])
//