Author: Akira Hatanaka Date: 2021-02-05T06:00:05-08:00 New Revision: 2fbbb18c1dbeb124dfc3c2aebae97d4780ff9bd6
URL: https://github.com/llvm/llvm-project/commit/2fbbb18c1dbeb124dfc3c2aebae97d4780ff9bd6 DIFF: https://github.com/llvm/llvm-project/commit/2fbbb18c1dbeb124dfc3c2aebae97d4780ff9bd6.diff LOG: Revert "[ObjC][ARC] Use operand bundle 'clang.arc.rv' instead of explicitly" This reverts commit 3fe3946d9a958b7af6130241996d9cfcecf559d4. The commit violates layering by including a header from Analysis in lib/IR/AutoUpgrade.cpp. Added: llvm/test/Transforms/TailCallElim/deopt-bundle.ll Modified: clang/lib/CodeGen/CGObjC.cpp clang/lib/CodeGen/CodeGenFunction.h clang/lib/CodeGen/CodeGenModule.h clang/test/CodeGenObjC/arc-unsafeclaim.m llvm/docs/LangRef.rst llvm/include/llvm/IR/InstrTypes.h llvm/include/llvm/IR/Intrinsics.td llvm/include/llvm/IR/LLVMContext.h llvm/lib/Analysis/ObjCARCInstKind.cpp llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp llvm/lib/IR/AutoUpgrade.cpp llvm/lib/IR/Instructions.cpp llvm/lib/IR/LLVMContext.cpp llvm/lib/Target/AArch64/AArch64ISelLowering.cpp llvm/lib/Transforms/ObjCARC/ARCRuntimeEntryPoints.h llvm/lib/Transforms/ObjCARC/ObjCARC.cpp llvm/lib/Transforms/ObjCARC/ObjCARC.h llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp llvm/lib/Transforms/ObjCARC/PtrState.cpp llvm/lib/Transforms/ObjCARC/PtrState.h llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp llvm/lib/Transforms/Utils/InlineFunction.cpp llvm/test/Bitcode/operand-bundles-bc-analyzer.ll llvm/test/CodeGen/AArch64/call-rv-marker.ll llvm/test/Transforms/DeadArgElim/deadretval.ll llvm/test/Transforms/ObjCARC/contract-marker-funclet.ll llvm/test/Transforms/ObjCARC/contract.ll llvm/test/Transforms/ObjCARC/intrinsic-use.ll llvm/test/Transforms/ObjCARC/rv.ll Removed: clang/test/CodeGenObjC/arc-rv-attr.m llvm/include/llvm/Analysis/ObjCARCUtil.h llvm/test/Transforms/Inline/inline-retainRV-call.ll llvm/test/Transforms/ObjCARC/contract-rv-attr.ll llvm/test/Transforms/TailCallElim/operand-bundles.ll ################################################################################ diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp index ab3fba615335..3f930c76fe0a 100644 --- a/clang/lib/CodeGen/CGObjC.cpp +++ b/clang/lib/CodeGen/CGObjC.cpp @@ -23,7 +23,6 @@ #include "clang/Basic/Diagnostic.h" #include "clang/CodeGen/CGFunctionInfo.h" #include "llvm/ADT/STLExtras.h" -#include "llvm/Analysis/ObjCARCUtil.h" #include "llvm/BinaryFormat/MachO.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/InlineAsm.h" @@ -2079,15 +2078,6 @@ void CodeGenFunction::EmitARCIntrinsicUse(ArrayRef<llvm::Value*> values) { EmitNounwindRuntimeCall(fn, values); } -/// Emit a call to "clang.arc.noop.use", which consumes the result of a call -/// that has operand bundle "clang.arc.rv". -void CodeGenFunction::EmitARCNoopIntrinsicUse(ArrayRef<llvm::Value *> values) { - llvm::Function *&fn = CGM.getObjCEntrypoints().clang_arc_noop_use; - if (!fn) - fn = CGM.getIntrinsic(llvm::Intrinsic::objc_clang_arc_noop_use); - EmitNounwindRuntimeCall(fn, values); -} - static void setARCRuntimeFunctionLinkage(CodeGenModule &CGM, llvm::Value *RTF) { if (auto *F = dyn_cast<llvm::Function>(RTF)) { // If the target runtime doesn't naturally support ARC, emit weak @@ -2314,11 +2304,10 @@ static void emitAutoreleasedReturnValueMarker(CodeGenFunction &CGF) { // with this marker yet, so leave a breadcrumb for the ARC // optimizer to pick up. } else { - const char *retainRVMarkerKey = llvm::objcarc::getRVMarkerModuleFlagStr(); - if (!CGF.CGM.getModule().getModuleFlag(retainRVMarkerKey)) { + const char *markerKey = "clang.arc.retainAutoreleasedReturnValueMarker"; + if (!CGF.CGM.getModule().getModuleFlag(markerKey)) { auto *str = llvm::MDString::get(CGF.getLLVMContext(), assembly); - CGF.CGM.getModule().addModuleFlag(llvm::Module::Error, - retainRVMarkerKey, str); + CGF.CGM.getModule().addModuleFlag(llvm::Module::Error, markerKey, str); } } } @@ -2328,46 +2317,6 @@ static void emitAutoreleasedReturnValueMarker(CodeGenFunction &CGF) { CGF.Builder.CreateCall(marker, None, CGF.getBundlesForFunclet(marker)); } -static llvm::Value *emitOptimizedARCReturnCall(llvm::Value *value, - bool IsRetainRV, - CodeGenFunction &CGF) { - emitAutoreleasedReturnValueMarker(CGF); - - // Add operand bundle "clang.arc.rv" to the call instead of emitting retainRV - // or claimRV calls in the IR. We currently do this only when the optimization - // level isn't -O0 since global-isel, which is currently run at -O0, doesn't - // know about the operand bundle. - - // FIXME: Do this when the target isn't aarch64. - if (CGF.CGM.getCodeGenOpts().OptimizationLevel > 0 && - CGF.CGM.getTarget().getTriple().isAArch64()) { - llvm::Value *bundleArgs[] = {llvm::ConstantInt::get( - CGF.Int64Ty, llvm::objcarc::getRVOperandBundleEnum(IsRetainRV))}; - SmallVector<llvm::OperandBundleDef, 1> bundles; - bundles.emplace_back("clang.arc.rv", bundleArgs); - auto *oldCall = cast<llvm::CallBase>(value); - llvm::CallBase *newCall = llvm::CallBase::Create(oldCall, bundles, oldCall); - newCall->copyMetadata(*oldCall); - oldCall->replaceAllUsesWith(newCall); - oldCall->eraseFromParent(); - CGF.EmitARCNoopIntrinsicUse(newCall); - return newCall; - } - - bool isNoTail = - CGF.CGM.getTargetCodeGenInfo().markARCOptimizedReturnCallsAsNoTail(); - llvm::CallInst::TailCallKind tailKind = - isNoTail ? llvm::CallInst::TCK_NoTail : llvm::CallInst::TCK_None; - ObjCEntrypoints &EPs = CGF.CGM.getObjCEntrypoints(); - llvm::Function *&EP = IsRetainRV - ? EPs.objc_retainAutoreleasedReturnValue - : EPs.objc_unsafeClaimAutoreleasedReturnValue; - llvm::Intrinsic::ID IID = - IsRetainRV ? llvm::Intrinsic::objc_retainAutoreleasedReturnValue - : llvm::Intrinsic::objc_unsafeClaimAutoreleasedReturnValue; - return emitARCValueOperation(CGF, value, nullptr, EP, IID, tailKind); -} - /// Retain the given object which is the result of a function call. /// call i8* \@objc_retainAutoreleasedReturnValue(i8* %value) /// @@ -2375,7 +2324,15 @@ static llvm::Value *emitOptimizedARCReturnCall(llvm::Value *value, /// call with completely diff erent semantics. llvm::Value * CodeGenFunction::EmitARCRetainAutoreleasedReturnValue(llvm::Value *value) { - return emitOptimizedARCReturnCall(value, true, *this); + emitAutoreleasedReturnValueMarker(*this); + llvm::CallInst::TailCallKind tailKind = + CGM.getTargetCodeGenInfo().markARCOptimizedReturnCallsAsNoTail() + ? llvm::CallInst::TCK_NoTail + : llvm::CallInst::TCK_None; + return emitARCValueOperation( + *this, value, nullptr, + CGM.getObjCEntrypoints().objc_retainAutoreleasedReturnValue, + llvm::Intrinsic::objc_retainAutoreleasedReturnValue, tailKind); } /// Claim a possibly-autoreleased return value at +0. This is only @@ -2387,7 +2344,15 @@ CodeGenFunction::EmitARCRetainAutoreleasedReturnValue(llvm::Value *value) { /// call i8* \@objc_unsafeClaimAutoreleasedReturnValue(i8* %value) llvm::Value * CodeGenFunction::EmitARCUnsafeClaimAutoreleasedReturnValue(llvm::Value *value) { - return emitOptimizedARCReturnCall(value, false, *this); + emitAutoreleasedReturnValueMarker(*this); + llvm::CallInst::TailCallKind tailKind = + CGM.getTargetCodeGenInfo().markARCOptimizedReturnCallsAsNoTail() + ? llvm::CallInst::TCK_NoTail + : llvm::CallInst::TCK_None; + return emitARCValueOperation( + *this, value, nullptr, + CGM.getObjCEntrypoints().objc_unsafeClaimAutoreleasedReturnValue, + llvm::Intrinsic::objc_unsafeClaimAutoreleasedReturnValue, tailKind); } /// Release the given object. diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index dd77d70c21f4..8eb7adbc8fcb 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -4202,8 +4202,6 @@ class CodeGenFunction : public CodeGenTypeCache { void EmitARCIntrinsicUse(ArrayRef<llvm::Value*> values); - void EmitARCNoopIntrinsicUse(ArrayRef<llvm::Value *> values); - static Destroyer destroyARCStrongImprecise; static Destroyer destroyARCStrongPrecise; static Destroyer destroyARCWeak; diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index 4ff7deb70636..618e2f857b07 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -210,9 +210,6 @@ struct ObjCEntrypoints { /// void clang.arc.use(...); llvm::Function *clang_arc_use; - - /// void clang.arc.noop.use(...); - llvm::Function *clang_arc_noop_use; }; /// This class records statistics on instrumentation based profiling. diff --git a/clang/test/CodeGenObjC/arc-rv-attr.m b/clang/test/CodeGenObjC/arc-rv-attr.m deleted file mode 100644 index 02314463ccb2..000000000000 --- a/clang/test/CodeGenObjC/arc-rv-attr.m +++ /dev/null @@ -1,177 +0,0 @@ -// RUN: %clang_cc1 -triple arm64-apple-ios9 -fobjc-runtime=ios-9.0 -fobjc-arc -O -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK - -@class A; - -A *makeA(void); - -void test_assign() { - __unsafe_unretained id x; - x = makeA(); -} -// CHECK-LABEL: define{{.*}} void @test_assign() -// CHECK: [[X:%.*]] = alloca i8* -// CHECK: [[T0:%.*]] = call [[A:.*]]* @makeA() [ "clang.arc.rv"(i64 1) ] -// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) -// CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* -// CHECK-NEXT: store i8* [[T1]], i8** [[X]] -// CHECK-NEXT: bitcast -// CHECK-NEXT: lifetime.end -// CHECK-NEXT: ret void - -void test_assign_assign() { - __unsafe_unretained id x, y; - x = y = makeA(); -} -// CHECK-LABEL: define{{.*}} void @test_assign_assign() -// CHECK: [[X:%.*]] = alloca i8* -// CHECK: [[Y:%.*]] = alloca i8* -// CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.rv"(i64 1) ] -// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) -// CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* -// CHECK-NEXT: store i8* [[T1]], i8** [[Y]] -// CHECK-NEXT: store i8* [[T1]], i8** [[X]] -// CHECK-NEXT: bitcast -// CHECK-NEXT: lifetime.end -// CHECK-NEXT: bitcast -// CHECK-NEXT: lifetime.end -// CHECK-NEXT: ret void - -void test_strong_assign_assign() { - __strong id x; - __unsafe_unretained id y; - x = y = makeA(); -} -// CHECK-LABEL: define{{.*}} void @test_strong_assign_assign() -// CHECK: [[X:%.*]] = alloca i8* -// CHECK: [[Y:%.*]] = alloca i8* -// CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.rv"(i64 0) ] -// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) -// CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* -// CHECK-NEXT: store i8* [[T1]], i8** [[Y]] -// CHECK-NEXT: [[OLD:%.*]] = load i8*, i8** [[X]] -// CHECK-NEXT: store i8* [[T1]], i8** [[X]] -// CHECK-NEXT: call void @llvm.objc.release(i8* [[OLD]] -// CHECK-NEXT: bitcast -// CHECK-NEXT: lifetime.end -// CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[X]] -// CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) -// CHECK-NEXT: bitcast -// CHECK-NEXT: lifetime.end -// CHECK-NEXT: ret void - -void test_assign_strong_assign() { - __unsafe_unretained id x; - __strong id y; - x = y = makeA(); -} -// CHECK-LABEL: define{{.*}} void @test_assign_strong_assign() -// CHECK: [[X:%.*]] = alloca i8* -// CHECK: [[Y:%.*]] = alloca i8* -// CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.rv"(i64 0) ] -// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) -// CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* -// CHECK-NEXT: [[OLD:%.*]] = load i8*, i8** [[Y]] -// CHECK-NEXT: store i8* [[T1]], i8** [[Y]] -// CHECK-NEXT: call void @llvm.objc.release(i8* [[OLD]] -// CHECK-NEXT: store i8* [[T1]], i8** [[X]] -// CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[Y]] -// CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) -// CHECK-NEXT: bitcast -// CHECK-NEXT: lifetime.end -// CHECK-NEXT: bitcast -// CHECK-NEXT: lifetime.end -// CHECK-NEXT: ret void - -void test_init() { - __unsafe_unretained id x = makeA(); -} -// CHECK-LABEL: define{{.*}} void @test_init() -// CHECK: [[X:%.*]] = alloca i8* -// CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.rv"(i64 1) ] -// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) -// CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* -// CHECK-NEXT: store i8* [[T1]], i8** [[X]] -// CHECK-NEXT: bitcast -// CHECK-NEXT: lifetime.end -// CHECK-NEXT: ret void - -void test_init_assignment() { - __unsafe_unretained id x; - __unsafe_unretained id y = x = makeA(); -} -// CHECK-LABEL: define{{.*}} void @test_init_assignment() -// CHECK: [[X:%.*]] = alloca i8* -// CHECK: [[Y:%.*]] = alloca i8* -// CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.rv"(i64 1) ] -// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) -// CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* -// CHECK-NEXT: store i8* [[T1]], i8** [[X]] -// CHECK-NEXT: store i8* [[T1]], i8** [[Y]] -// CHECK-NEXT: bitcast -// CHECK-NEXT: lifetime.end -// CHECK-NEXT: bitcast -// CHECK-NEXT: lifetime.end -// CHECK-NEXT: ret void - -void test_strong_init_assignment() { - __unsafe_unretained id x; - __strong id y = x = makeA(); -} -// CHECK-LABEL: define{{.*}} void @test_strong_init_assignment() -// CHECK: [[X:%.*]] = alloca i8* -// CHECK: [[Y:%.*]] = alloca i8* -// CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.rv"(i64 0) ] -// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) -// CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* -// CHECK-NEXT: store i8* [[T1]], i8** [[X]] -// CHECK-NEXT: store i8* [[T1]], i8** [[Y]] -// CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[Y]] -// CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) -// CHECK-NEXT: bitcast -// CHECK-NEXT: lifetime.end -// CHECK-NEXT: bitcast -// CHECK-NEXT: lifetime.end -// CHECK-NEXT: ret void - -void test_init_strong_assignment() { - __strong id x; - __unsafe_unretained id y = x = makeA(); -} -// CHECK-LABEL: define{{.*}} void @test_init_strong_assignment() -// CHECK: [[X:%.*]] = alloca i8* -// CHECK: [[Y:%.*]] = alloca i8* -// CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.rv"(i64 0) ] -// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) -// CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* -// CHECK-NEXT: [[OLD:%.*]] = load i8*, i8** [[X]] -// CHECK-NEXT: store i8* [[T1]], i8** [[X]] -// CHECK-NEXT: call void @llvm.objc.release(i8* [[OLD]]) -// CHECK-NEXT: store i8* [[T1]], i8** [[Y]] -// CHECK-NEXT: bitcast -// CHECK-NEXT: lifetime.end -// CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[X]] -// CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) -// CHECK-NEXT: bitcast -// CHECK-NEXT: lifetime.end -// CHECK-NEXT: ret void - -void test_ignored() { - makeA(); -} -// CHECK-LABEL: define{{.*}} void @test_ignored() -// CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.rv"(i64 1) ] -// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) -// CHECK-NEXT: ret void - -void test_cast_to_void() { - (void) makeA(); -} -// CHECK-LABEL: define{{.*}} void @test_cast_to_void() -// CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.rv"(i64 1) ] -// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) -// CHECK-NEXT: ret void - -// This is always at the end of the module. - -// CHECK-OPTIMIZED: !llvm.module.flags = !{!0, -// CHECK-OPTIMIZED: !0 = !{i32 1, !"clang.arc.retainAutoreleasedReturnValueMarker", !"mov{{.*}}marker for objc_retainAutoreleaseReturnValue"} diff --git a/clang/test/CodeGenObjC/arc-unsafeclaim.m b/clang/test/CodeGenObjC/arc-unsafeclaim.m index 08ff8eca8da5..8f95d1edc96c 100644 --- a/clang/test/CodeGenObjC/arc-unsafeclaim.m +++ b/clang/test/CodeGenObjC/arc-unsafeclaim.m @@ -4,10 +4,11 @@ // Make sure it works on x86-32. // RUN: %clang_cc1 -triple i386-apple-darwin11 -fobjc-runtime=macosx-fragile-10.11 -fobjc-arc -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-UNOPTIMIZED -check-prefix=CHECK-MARKED -check-prefix=CALL -// Make sure it works on ARM64. +// Make sure it works on ARM. // RUN: %clang_cc1 -triple arm64-apple-ios9 -fobjc-runtime=ios-9.0 -fobjc-arc -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-UNOPTIMIZED -check-prefix=CHECK-MARKED -check-prefix=CALL +// RUN: %clang_cc1 -triple arm64-apple-ios9 -fobjc-runtime=ios-9.0 -fobjc-arc -O -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-OPTIMIZED -check-prefix=CALL -// Make sure it works on ARM. +// Make sure it works on ARM64. // RUN: %clang_cc1 -triple armv7-apple-ios9 -fobjc-runtime=ios-9.0 -fobjc-arc -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-UNOPTIMIZED -check-prefix=CHECK-MARKED -check-prefix=CALL // RUN: %clang_cc1 -triple armv7-apple-ios9 -fobjc-runtime=ios-9.0 -fobjc-arc -O -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-OPTIMIZED -check-prefix=CALL diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst index f7974a2c8f40..94951ae2dd3e 100644 --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -2325,18 +2325,6 @@ When lowered, any relocated value will be recorded in the corresponding :ref:`stackmap entry <statepoint-stackmap-format>`. See the intrinsic description for further details. -ObjC ARC RetainRV/ClaimRV Operand Bundles -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -A ``"clang.arc.rv"`` operand bundle on a call indicates the call is implicitly -followed by a marker instruction and a call to an ObjC runtime function that -uses the result of the call. If the argument passed to the operand bundle is 0, -``@objc_retainAutoreleasedReturnValue`` is called. If 1 is passed, -``@objc_unsafeClaimAutoreleasedReturnValue`` is called. - -The operand bundle is needed to ensure the call is immediately followed by the -marker instruction or the ObjC runtime call in the final output. - .. _moduleasm: Module-Level Inline Assembly diff --git a/llvm/include/llvm/Analysis/ObjCARCUtil.h b/llvm/include/llvm/Analysis/ObjCARCUtil.h deleted file mode 100644 index a337e6c2751b..000000000000 --- a/llvm/include/llvm/Analysis/ObjCARCUtil.h +++ /dev/null @@ -1,48 +0,0 @@ -//===- ObjCARCUtil.h - ObjC ARC Utility Functions ---------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -/// \file -/// This file defines ARC utility functions which are used by various parts of -/// the compiler. -/// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_LIB_ANALYSIS_OBJCARCUTIL_H -#define LLVM_LIB_ANALYSIS_OBJCARCUTIL_H - -#include "llvm/IR/InstrTypes.h" -#include "llvm/IR/LLVMContext.h" - -namespace llvm { -namespace objcarc { - -static inline const char *getRVMarkerModuleFlagStr() { - return "clang.arc.retainAutoreleasedReturnValueMarker"; -} - -enum RVOperandBundle : unsigned { RVOB_Retain, RVOB_Claim }; - -static RVOperandBundle getRVOperandBundleEnum(bool IsRetain) { - return IsRetain ? RVOB_Retain : RVOB_Claim; -} - -static inline bool hasRVOpBundle(const CallBase *CB, bool IsRetain) { - auto B = CB->getOperandBundle(LLVMContext::OB_clang_arc_rv); - if (!B.hasValue()) - return false; - return cast<ConstantInt>(B->Inputs[0])->getZExtValue() == - getRVOperandBundleEnum(IsRetain); -} - -static inline bool hasRVOpBundle(const CallBase *CB) { - return CB->getOperandBundle(LLVMContext::OB_clang_arc_rv).hasValue(); -} - -} // end namespace objcarc -} // end namespace llvm - -#endif diff --git a/llvm/include/llvm/IR/InstrTypes.h b/llvm/include/llvm/IR/InstrTypes.h index c4963f668827..f42ef48de6b3 100644 --- a/llvm/include/llvm/IR/InstrTypes.h +++ b/llvm/include/llvm/IR/InstrTypes.h @@ -1214,15 +1214,6 @@ class CallBase : public Instruction { static CallBase *Create(CallBase *CB, ArrayRef<OperandBundleDef> Bundles, Instruction *InsertPt = nullptr); - /// Create a clone of \p CB with operand bundle \p OB added. - static CallBase *addOperandBundle(CallBase *CB, uint32_t ID, - OperandBundleDef OB, - Instruction *InsertPt = nullptr); - - /// Create a clone of \p CB with operand bundle \p ID removed. - static CallBase *removeOperandBundle(CallBase *CB, uint32_t ID, - Instruction *InsertPt = nullptr); - static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Call || I->getOpcode() == Instruction::Invoke || diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td index 69a5701d5a8d..58f0f86cae63 100644 --- a/llvm/include/llvm/IR/Intrinsics.td +++ b/llvm/include/llvm/IR/Intrinsics.td @@ -446,9 +446,6 @@ def int_objc_storeWeak : Intrinsic<[llvm_ptr_ty], llvm_ptr_ty]>; def int_objc_clang_arc_use : Intrinsic<[], [llvm_vararg_ty]>; -def int_objc_clang_arc_noop_use : DefaultAttrsIntrinsic<[], - [llvm_vararg_ty], - [IntrInaccessibleMemOnly]>; def int_objc_unsafeClaimAutoreleasedReturnValue : Intrinsic<[llvm_ptr_ty], [llvm_ptr_ty]>; def int_objc_retainedObject : Intrinsic<[llvm_ptr_ty], diff --git a/llvm/include/llvm/IR/LLVMContext.h b/llvm/include/llvm/IR/LLVMContext.h index 23a01b8e0471..8f8a35d07c64 100644 --- a/llvm/include/llvm/IR/LLVMContext.h +++ b/llvm/include/llvm/IR/LLVMContext.h @@ -93,7 +93,6 @@ class LLVMContext { OB_cfguardtarget = 3, // "cfguardtarget" OB_preallocated = 4, // "preallocated" OB_gc_live = 5, // "gc-live" - OB_clang_arc_rv = 6, // "clang.arc.rv" }; /// getMDKindID - Return a unique non-zero ID for the specified metadata kind. diff --git a/llvm/lib/Analysis/ObjCARCInstKind.cpp b/llvm/lib/Analysis/ObjCARCInstKind.cpp index 704d15f3280d..951907804227 100644 --- a/llvm/lib/Analysis/ObjCARCInstKind.cpp +++ b/llvm/lib/Analysis/ObjCARCInstKind.cpp @@ -140,7 +140,6 @@ ARCInstKind llvm::objcarc::GetFunctionClass(const Function *F) { return ARCInstKind::User; case Intrinsic::objc_sync_exit: return ARCInstKind::User; - case Intrinsic::objc_clang_arc_noop_use: case Intrinsic::objc_arc_annotation_topdown_bbstart: case Intrinsic::objc_arc_annotation_topdown_bbend: case Intrinsic::objc_arc_annotation_bottomup_bbstart: diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 936b56dad485..5c94a83f719c 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -2782,10 +2782,11 @@ void SelectionDAGBuilder::visitInvoke(const InvokeInst &I) { // Deopt bundles are lowered in LowerCallSiteWithDeoptBundle, and we don't // have to do anything here to lower funclet bundles. - assert(!I.hasOperandBundlesOtherThan( - {LLVMContext::OB_deopt, LLVMContext::OB_gc_transition, - LLVMContext::OB_gc_live, LLVMContext::OB_funclet, - LLVMContext::OB_cfguardtarget, LLVMContext::OB_clang_arc_rv}) && + assert(!I.hasOperandBundlesOtherThan({LLVMContext::OB_deopt, + LLVMContext::OB_gc_transition, + LLVMContext::OB_gc_live, + LLVMContext::OB_funclet, + LLVMContext::OB_cfguardtarget}) && "Cannot lower invokes with arbitrary operand bundles yet!"); const Value *Callee(I.getCalledOperand()); @@ -7872,8 +7873,7 @@ void SelectionDAGBuilder::visitCall(const CallInst &I) { // CFGuardTarget bundles are lowered in LowerCallTo. assert(!I.hasOperandBundlesOtherThan( {LLVMContext::OB_deopt, LLVMContext::OB_funclet, - LLVMContext::OB_cfguardtarget, LLVMContext::OB_preallocated, - LLVMContext::OB_clang_arc_rv}) && + LLVMContext::OB_cfguardtarget, LLVMContext::OB_preallocated}) && "Cannot lower calls with arbitrary operand bundles!"); SDValue Callee = getValue(I.getCalledOperand()); diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp index 3134f7b15103..23e7af6287b6 100644 --- a/llvm/lib/IR/AutoUpgrade.cpp +++ b/llvm/lib/IR/AutoUpgrade.cpp @@ -14,15 +14,14 @@ #include "llvm/IR/AutoUpgrade.h" #include "llvm/ADT/StringSwitch.h" -#include "llvm/Analysis/ObjCARCUtil.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DIBuilder.h" #include "llvm/IR/DebugInfo.h" #include "llvm/IR/DiagnosticInfo.h" #include "llvm/IR/Function.h" #include "llvm/IR/IRBuilder.h" -#include "llvm/IR/InstVisitor.h" #include "llvm/IR/Instruction.h" +#include "llvm/IR/InstVisitor.h" #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/Intrinsics.h" #include "llvm/IR/IntrinsicsAArch64.h" @@ -3997,7 +3996,7 @@ bool llvm::UpgradeDebugInfo(Module &M) { /// returns true if module is modified. static bool UpgradeRetainReleaseMarker(Module &M) { bool Changed = false; - const char *MarkerKey = objcarc::getRVMarkerModuleFlagStr(); + const char *MarkerKey = "clang.arc.retainAutoreleasedReturnValueMarker"; NamedMDNode *ModRetainReleaseMarker = M.getNamedMetadata(MarkerKey); if (ModRetainReleaseMarker) { MDNode *Op = ModRetainReleaseMarker->getOperand(0); diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp index b73528d89752..d6b4a4f5030f 100644 --- a/llvm/lib/IR/Instructions.cpp +++ b/llvm/lib/IR/Instructions.cpp @@ -424,35 +424,6 @@ CallBase::BundleOpInfo &CallBase::getBundleOpInfoForOperand(unsigned OpIdx) { return *Current; } -CallBase *CallBase::addOperandBundle(CallBase *CB, uint32_t ID, - OperandBundleDef OB, - Instruction *InsertPt) { - if (CB->getOperandBundle(ID)) - return CB; - - SmallVector<OperandBundleDef, 1> Bundles; - CB->getOperandBundlesAsDefs(Bundles); - Bundles.push_back(OB); - return Create(CB, Bundles, InsertPt); -} - -CallBase *CallBase::removeOperandBundle(CallBase *CB, uint32_t ID, - Instruction *InsertPt) { - SmallVector<OperandBundleDef, 1> Bundles; - bool CreateNew = false; - - for (unsigned I = 0, E = CB->getNumOperandBundles(); I != E; ++I) { - auto Bundle = CB->getOperandBundleAt(I); - if (Bundle.getTagID() == ID) { - CreateNew = true; - continue; - } - Bundles.emplace_back(Bundle); - } - - return CreateNew ? Create(CB, Bundles, InsertPt) : CB; -} - //===----------------------------------------------------------------------===// // CallInst Implementation //===----------------------------------------------------------------------===// diff --git a/llvm/lib/IR/LLVMContext.cpp b/llvm/lib/IR/LLVMContext.cpp index 9f9a30de23e3..4f292101256d 100644 --- a/llvm/lib/IR/LLVMContext.cpp +++ b/llvm/lib/IR/LLVMContext.cpp @@ -78,11 +78,6 @@ LLVMContext::LLVMContext() : pImpl(new LLVMContextImpl(*this)) { "gc-transition operand bundle id drifted!"); (void)GCLiveEntry; - auto *ClangARCRVEntry = pImpl->getOrInsertBundleTag("clang.arc.rv"); - assert(ClangARCRVEntry->second == LLVMContext::OB_clang_arc_rv && - "clang.arc.rv operand bundle id drifted!"); - (void)ClangARCRVEntry; - SyncScope::ID SingleThreadSSID = pImpl->getOrInsertSyncScopeID("singlethread"); assert(SingleThreadSSID == SyncScope::SingleThread && diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp index 55b6cf177d0a..c87478afe65c 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -29,7 +29,6 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Triple.h" #include "llvm/ADT/Twine.h" -#include "llvm/Analysis/ObjCARCUtil.h" #include "llvm/Analysis/VectorUtils.h" #include "llvm/CodeGen/CallingConvLower.h" #include "llvm/CodeGen/MachineBasicBlock.h" @@ -5654,11 +5653,11 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI, } unsigned CallOpc = AArch64ISD::CALL; - // Calls with operand bundle "clang.arc.rv" are special. They should be - // expanded to the call, directly followed by a special marker sequence. Use - // the CALL_RVMARKER to do that. - if (CLI.CB && objcarc::hasRVOpBundle(CLI.CB)) { - assert(!IsTailCall && "tail calls cannot be marked with clang.arc.rv"); + // Calls marked with "rv_marker" are special. They should be expanded to the + // call, directly followed by a special marker sequence. Use the CALL_RVMARKER + // to do that. + if (CLI.CB && CLI.CB->hasRetAttr("rv_marker")) { + assert(!IsTailCall && "tail calls cannot be marked with rv_marker"); CallOpc = AArch64ISD::CALL_RVMARKER; } diff --git a/llvm/lib/Transforms/ObjCARC/ARCRuntimeEntryPoints.h b/llvm/lib/Transforms/ObjCARC/ARCRuntimeEntryPoints.h index 764dc5f92707..258dc9240815 100644 --- a/llvm/lib/Transforms/ObjCARC/ARCRuntimeEntryPoints.h +++ b/llvm/lib/Transforms/ObjCARC/ARCRuntimeEntryPoints.h @@ -42,7 +42,6 @@ enum class ARCRuntimeEntryPointKind { Autorelease, StoreStrong, RetainRV, - ClaimRV, RetainAutorelease, RetainAutoreleaseRV, }; @@ -62,7 +61,6 @@ class ARCRuntimeEntryPoints { Autorelease = nullptr; StoreStrong = nullptr; RetainRV = nullptr; - ClaimRV = nullptr; RetainAutorelease = nullptr; RetainAutoreleaseRV = nullptr; } @@ -87,9 +85,6 @@ class ARCRuntimeEntryPoints { case ARCRuntimeEntryPointKind::RetainRV: return getIntrinsicEntryPoint(RetainRV, Intrinsic::objc_retainAutoreleasedReturnValue); - case ARCRuntimeEntryPointKind::ClaimRV: - return getIntrinsicEntryPoint( - ClaimRV, Intrinsic::objc_unsafeClaimAutoreleasedReturnValue); case ARCRuntimeEntryPointKind::RetainAutorelease: return getIntrinsicEntryPoint(RetainAutorelease, Intrinsic::objc_retainAutorelease); @@ -126,9 +121,6 @@ class ARCRuntimeEntryPoints { /// Declaration for objc_retainAutoreleasedReturnValue(). Function *RetainRV = nullptr; - /// Declaration for objc_unsafeClaimAutoreleasedReturnValue(). - Function *ClaimRV = nullptr; - /// Declaration for objc_retainAutorelease(). Function *RetainAutorelease = nullptr; diff --git a/llvm/lib/Transforms/ObjCARC/ObjCARC.cpp b/llvm/lib/Transforms/ObjCARC/ObjCARC.cpp index c4b6d60cad36..970136392fdd 100644 --- a/llvm/lib/Transforms/ObjCARC/ObjCARC.cpp +++ b/llvm/lib/Transforms/ObjCARC/ObjCARC.cpp @@ -14,12 +14,7 @@ #include "ObjCARC.h" #include "llvm-c/Initialization.h" -#include "llvm/Analysis/ObjCARCUtil.h" -#include "llvm/IR/IRBuilder.h" -#include "llvm/IR/InlineAsm.h" -#include "llvm/IR/Instructions.h" #include "llvm/InitializePasses.h" -#include "llvm/Transforms/Utils/BasicBlockUtils.h" namespace llvm { class PassRegistry; @@ -42,91 +37,3 @@ void llvm::initializeObjCARCOpts(PassRegistry &Registry) { void LLVMInitializeObjCARCOpts(LLVMPassRegistryRef R) { initializeObjCARCOpts(*unwrap(R)); } - -CallInst *objcarc::createCallInstWithColors( - FunctionCallee Func, ArrayRef<Value *> Args, const Twine &NameStr, - Instruction *InsertBefore, - const DenseMap<BasicBlock *, ColorVector> &BlockColors) { - FunctionType *FTy = Func.getFunctionType(); - Value *Callee = Func.getCallee(); - SmallVector<OperandBundleDef, 1> OpBundles; - - if (!BlockColors.empty()) { - const ColorVector &CV = BlockColors.find(InsertBefore->getParent())->second; - assert(CV.size() == 1 && "non-unique color for block!"); - Instruction *EHPad = CV.front()->getFirstNonPHI(); - if (EHPad->isEHPad()) - OpBundles.emplace_back("funclet", EHPad); - } - - return CallInst::Create(FTy, Callee, Args, OpBundles, NameStr, InsertBefore); -} - -std::pair<bool, bool> -BundledRetainClaimRVs::insertAfterInvokes(Function &F, DominatorTree *DT) { - bool Changed = false, CFGChanged = false; - - for (BasicBlock &BB : F) { - auto *I = dyn_cast<InvokeInst>(BB.getTerminator()); - - if (!I) - continue; - - if (!objcarc::hasRVOpBundle(I)) - continue; - - BasicBlock *DestBB = I->getNormalDest(); - - if (!DestBB->getSinglePredecessor()) { - assert(I->getSuccessor(0) == DestBB && - "the normal dest is expected to be the first successor"); - DestBB = SplitCriticalEdge(I, 0, CriticalEdgeSplittingOptions(DT)); - CFGChanged = true; - } - - // We don't have to call insertRVCallWithColors since DestBB is the normal - // destination of the invoke. - insertRVCall(&*DestBB->getFirstInsertionPt(), I); - Changed = true; - } - - return std::make_pair(Changed, CFGChanged); -} - -CallInst *BundledRetainClaimRVs::insertRVCall(Instruction *InsertPt, - CallBase *AnnotatedCall) { - DenseMap<BasicBlock *, ColorVector> BlockColors; - return insertRVCallWithColors(InsertPt, AnnotatedCall, BlockColors); -} - -CallInst *BundledRetainClaimRVs::insertRVCallWithColors( - Instruction *InsertPt, CallBase *AnnotatedCall, - const DenseMap<BasicBlock *, ColorVector> &BlockColors) { - IRBuilder<> Builder(InsertPt); - bool IsRetainRV = objcarc::hasRVOpBundle(AnnotatedCall, true); - Function *Func = EP.get(IsRetainRV ? ARCRuntimeEntryPointKind::RetainRV - : ARCRuntimeEntryPointKind::ClaimRV); - Type *ParamTy = Func->getArg(0)->getType(); - Value *CallArg = Builder.CreateBitCast(AnnotatedCall, ParamTy); - auto *Call = - createCallInstWithColors(Func, CallArg, "", InsertPt, BlockColors); - RVCalls[Call] = AnnotatedCall; - return Call; -} - -BundledRetainClaimRVs::~BundledRetainClaimRVs() { - if (ContractPass) { - // At this point, we know that the annotated calls can't be tail calls as - // they are followed by marker instructions and retainRV/claimRV calls. Mark - // them as notail, so that the backend knows these calls can't be tail - // calls. - for (auto P : RVCalls) - if (auto *CI = dyn_cast<CallInst>(P.second)) - CI->setTailCallKind(CallInst::TCK_NoTail); - } else { - for (auto P : RVCalls) - EraseInstruction(P.first); - } - - RVCalls.clear(); -} diff --git a/llvm/lib/Transforms/ObjCARC/ObjCARC.h b/llvm/lib/Transforms/ObjCARC/ObjCARC.h index d4d88569694d..8227a8c6f75f 100644 --- a/llvm/lib/Transforms/ObjCARC/ObjCARC.h +++ b/llvm/lib/Transforms/ObjCARC/ObjCARC.h @@ -22,10 +22,7 @@ #ifndef LLVM_LIB_TRANSFORMS_OBJCARC_OBJCARC_H #define LLVM_LIB_TRANSFORMS_OBJCARC_OBJCARC_H -#include "ARCRuntimeEntryPoints.h" -#include "llvm/Analysis/EHPersonalities.h" #include "llvm/Analysis/ObjCARCAnalysisUtils.h" -#include "llvm/Analysis/ObjCARCUtil.h" #include "llvm/Transforms/Utils/Local.h" namespace llvm { @@ -90,67 +87,6 @@ void getEquivalentPHIs(PHINodeTy &PN, VectorTy &PHIList) { } } -static inline MDString *getRVInstMarker(Module &M) { - const char *MarkerKey = getRVMarkerModuleFlagStr(); - return dyn_cast_or_null<MDString>(M.getModuleFlag(MarkerKey)); -} - -/// Create a call instruction with the correct funclet token. This should be -/// called instead of calling CallInst::Create directly unless the call is -/// going to be removed from the IR before WinEHPrepare. -CallInst *createCallInstWithColors( - FunctionCallee Func, ArrayRef<Value *> Args, const Twine &NameStr, - Instruction *InsertBefore, - const DenseMap<BasicBlock *, ColorVector> &BlockColors); - -class BundledRetainClaimRVs { -public: - BundledRetainClaimRVs(ARCRuntimeEntryPoints &P, bool ContractPass) - : EP(P), ContractPass(ContractPass) {} - ~BundledRetainClaimRVs(); - - /// Insert a retainRV/claimRV call to the normal destination blocks of invokes - /// with operand bundle "clang.arc.rv". If the edge to the normal destination - /// block is a critical edge, split it. - std::pair<bool, bool> insertAfterInvokes(Function &F, DominatorTree *DT); - - /// Insert a retainRV/claimRV call. - CallInst *insertRVCall(Instruction *InsertPt, CallBase *AnnotatedCall); - - /// Insert a retainRV/claimRV call with colors. - CallInst *insertRVCallWithColors( - Instruction *InsertPt, CallBase *AnnotatedCall, - const DenseMap<BasicBlock *, ColorVector> &BlockColors); - - /// See if an instruction is a bundled retainRV/claimRV call. - bool contains(const Instruction *I) const { - if (auto *CI = dyn_cast<CallInst>(I)) - return RVCalls.count(CI); - return false; - } - - /// Remove a retainRV/claimRV call entirely. - void eraseInst(CallInst *CI) { - auto It = RVCalls.find(CI); - if (It != RVCalls.end()) { - auto *NewCall = CallBase::removeOperandBundle( - It->second, LLVMContext::OB_clang_arc_rv, It->second); - NewCall->copyMetadata(*It->second); - It->second->replaceAllUsesWith(NewCall); - It->second->eraseFromParent(); - RVCalls.erase(It); - } - EraseInstruction(CI); - } - -private: - /// A map of inserted retainRV/claimRV calls to annotated calls/invokes. - DenseMap<CallInst *, CallBase *> RVCalls; - - ARCRuntimeEntryPoints &EP; - bool ContractPass; -}; - } // end namespace objcarc } // end namespace llvm diff --git a/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp b/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp index 5146e41aa617..86d161116e8c 100644 --- a/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp +++ b/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp @@ -32,7 +32,6 @@ #include "llvm/ADT/Statistic.h" #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/EHPersonalities.h" -#include "llvm/Analysis/ObjCARCUtil.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/InlineAsm.h" #include "llvm/IR/InstIterator.h" @@ -64,12 +63,13 @@ namespace { class ObjCARCContract { bool Changed; - bool CFGChanged; AAResults *AA; DominatorTree *DT; ProvenanceAnalysis PA; ARCRuntimeEntryPoints EP; - BundledRetainClaimRVs *BundledInsts = nullptr; + + /// A flag indicating whether this optimization pass should run. + bool Run; /// The inline asm string to insert between calls and RetainRV calls to make /// the optimization work on targets which need it. @@ -98,7 +98,6 @@ class ObjCARCContract { public: bool init(Module &M); bool run(Function &F, AAResults *AA, DominatorTree *DT); - bool hasCFGChanged() const { return CFGChanged; } }; class ObjCARCContractLegacyPass : public FunctionPass { @@ -305,6 +304,32 @@ findRetainForStoreStrongContraction(Value *New, StoreInst *Store, return Retain; } +/// Create a call instruction with the correct funclet token. Should be used +/// instead of calling CallInst::Create directly. +static CallInst * +createCallInst(FunctionType *FTy, Value *Func, ArrayRef<Value *> Args, + const Twine &NameStr, Instruction *InsertBefore, + const DenseMap<BasicBlock *, ColorVector> &BlockColors) { + SmallVector<OperandBundleDef, 1> OpBundles; + if (!BlockColors.empty()) { + const ColorVector &CV = BlockColors.find(InsertBefore->getParent())->second; + assert(CV.size() == 1 && "non-unique color for block!"); + Instruction *EHPad = CV.front()->getFirstNonPHI(); + if (EHPad->isEHPad()) + OpBundles.emplace_back("funclet", EHPad); + } + + return CallInst::Create(FTy, Func, Args, OpBundles, NameStr, InsertBefore); +} + +static CallInst * +createCallInst(FunctionCallee Func, ArrayRef<Value *> Args, const Twine &NameStr, + Instruction *InsertBefore, + const DenseMap<BasicBlock *, ColorVector> &BlockColors) { + return createCallInst(Func.getFunctionType(), Func.getCallee(), Args, NameStr, + InsertBefore, BlockColors); +} + /// Attempt to merge an objc_release with a store, load, and objc_retain to form /// an objc_storeStrong. An objc_storeStrong: /// @@ -386,8 +411,7 @@ void ObjCARCContract::tryToContractReleaseIntoStoreStrong( if (Args[1]->getType() != I8X) Args[1] = new BitCastInst(Args[1], I8X, "", Store); Function *Decl = EP.get(ARCRuntimeEntryPointKind::StoreStrong); - CallInst *StoreStrong = - objcarc::createCallInstWithColors(Decl, Args, "", Store, BlockColors); + CallInst *StoreStrong = createCallInst(Decl, Args, "", Store, BlockColors); StoreStrong->setDoesNotThrow(); StoreStrong->setDebugLoc(Store->getDebugLoc()); @@ -432,14 +456,9 @@ bool ObjCARCContract::tryToPeepholeInstruction( case ARCInstKind::RetainRV: case ARCInstKind::ClaimRV: { // If we're compiling for a target which needs a special inline-asm - // marker to do the return value optimization and the retainRV/claimRV call - // wasn't bundled with a call, insert the marker now. + // marker to do the return value optimization, insert it now. if (!RVInstMarker) return false; - - if (BundledInsts->contains(Inst)) - return false; - BasicBlock::iterator BBI = Inst->getIterator(); BasicBlock *InstParent = Inst->getParent(); @@ -467,7 +486,7 @@ bool ObjCARCContract::tryToPeepholeInstruction( RVInstMarker->getString(), /*Constraints=*/"", /*hasSideEffects=*/true); - objcarc::createCallInstWithColors(IA, None, "", Inst, BlockColors); + createCallInst(IA, None, "", Inst, BlockColors); } decline_rv_optimization: return false; @@ -506,12 +525,6 @@ bool ObjCARCContract::tryToPeepholeInstruction( Inst->eraseFromParent(); return true; default: - if (auto *CI = dyn_cast<CallInst>(Inst)) - if (CI->getIntrinsicID() == Intrinsic::objc_clang_arc_noop_use) { - // Remove calls to @llvm.objc.clang.arc.noop.use(...). - Changed = true; - CI->eraseFromParent(); - } return true; } } @@ -521,10 +534,16 @@ bool ObjCARCContract::tryToPeepholeInstruction( //===----------------------------------------------------------------------===// bool ObjCARCContract::init(Module &M) { + // If nothing in the Module uses ARC, don't do anything. + Run = ModuleHasARC(M); + if (!Run) + return false; + EP.init(&M); // Initialize RVInstMarker. - RVInstMarker = getRVInstMarker(M); + const char *MarkerKey = "clang.arc.retainAutoreleasedReturnValueMarker"; + RVInstMarker = dyn_cast_or_null<MDString>(M.getModuleFlag(MarkerKey)); return false; } @@ -533,16 +552,14 @@ bool ObjCARCContract::run(Function &F, AAResults *A, DominatorTree *D) { if (!EnableARCOpts) return false; - Changed = CFGChanged = false; + // If nothing in the Module uses ARC, don't do anything. + if (!Run) + return false; + + Changed = false; AA = A; DT = D; PA.setAA(A); - BundledRetainClaimRVs BRV(EP, true); - BundledInsts = &BRV; - - std::pair<bool, bool> R = BundledInsts->insertAfterInvokes(F, DT); - Changed |= R.first; - CFGChanged |= R.second; DenseMap<BasicBlock *, ColorVector> BlockColors; if (F.hasPersonalityFn() && @@ -567,13 +584,6 @@ bool ObjCARCContract::run(Function &F, AAResults *A, DominatorTree *D) { LLVM_DEBUG(dbgs() << "Visiting: " << *Inst << "\n"); - if (auto *CI = dyn_cast<CallInst>(Inst)) - if (objcarc::hasRVOpBundle(CI)) { - BundledInsts->insertRVCallWithColors(&*I, CI, BlockColors); - --I; - Changed = true; - } - // First try to peephole Inst. If there is nothing further we can do in // terms of undoing objc-arc-expand, process the next inst. if (tryToPeepholeInstruction(F, Inst, I, TailOkForStoreStrongs, @@ -723,6 +733,7 @@ INITIALIZE_PASS_END(ObjCARCContractLegacyPass, "objc-arc-contract", void ObjCARCContractLegacyPass::getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired<AAResultsWrapperPass>(); AU.addRequired<DominatorTreeWrapperPass>(); + AU.setPreservesCFG(); } Pass *llvm::createObjCARCContractPass() { @@ -746,11 +757,9 @@ PreservedAnalyses ObjCARCContractPass::run(Function &F, bool Changed = OCAC.run(F, &AM.getResult<AAManager>(F), &AM.getResult<DominatorTreeAnalysis>(F)); - bool CFGChanged = OCAC.hasCFGChanged(); if (Changed) { PreservedAnalyses PA; - if (!CFGChanged) - PA.preserveSet<CFGAnalyses>(); + PA.preserveSet<CFGAnalyses>(); return PA; } return PreservedAnalyses::all(); diff --git a/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp b/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp index d97d58f518e3..1c447499519c 100644 --- a/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp +++ b/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp @@ -41,7 +41,6 @@ #include "llvm/Analysis/ObjCARCAliasAnalysis.h" #include "llvm/Analysis/ObjCARCAnalysisUtils.h" #include "llvm/Analysis/ObjCARCInstKind.h" -#include "llvm/Analysis/ObjCARCUtil.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/CFG.h" #include "llvm/IR/Constant.h" @@ -484,7 +483,6 @@ namespace { /// The main ARC optimization pass. class ObjCARCOpt { bool Changed; - bool CFGChanged; ProvenanceAnalysis PA; /// A cache of references to runtime entry point constants. @@ -494,7 +492,8 @@ class ObjCARCOpt { /// MDKind identifiers. ARCMDKindCache MDKindCache; - BundledRetainClaimRVs *BundledInsts = nullptr; + /// A flag indicating whether this optimization pass should run. + bool Run; /// A flag indicating whether the optimization that removes or moves /// retain/release pairs should be performed. @@ -574,7 +573,6 @@ class ObjCARCOpt { void init(Module &M); bool run(Function &F, AAResults &AA); void releaseMemory(); - bool hasCFGChanged() const { return CFGChanged; } }; /// The main ARC optimization pass. @@ -612,6 +610,8 @@ Pass *llvm::createObjCARCOptPass() { return new ObjCARCOptLegacyPass(); } void ObjCARCOptLegacyPass::getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired<ObjCARCAAWrapperPass>(); AU.addRequired<AAResultsWrapperPass>(); + // ARC optimization doesn't currently split critical edges. + AU.setPreservesCFG(); } /// Turn objc_retainAutoreleasedReturnValue into objc_retain if the operand is @@ -640,9 +640,6 @@ ObjCARCOpt::OptimizeRetainRVCall(Function &F, Instruction *RetainRV) { } } - assert(!BundledInsts->contains(RetainRV) && - "a bundled retainRV's argument should be a call"); - // Turn it to a plain objc_retain. Changed = true; ++NumPeeps; @@ -664,9 +661,6 @@ bool ObjCARCOpt::OptimizeInlinedAutoreleaseRVCall( Function &F, DenseMap<BasicBlock *, ColorVector> &BlockColors, Instruction *Inst, const Value *&Arg, ARCInstKind Class, Instruction *AutoreleaseRV, const Value *&AutoreleaseRVArg) { - if (BundledInsts->contains(Inst)) - return false; - // Must be in the same basic block. assert(Inst->getParent() == AutoreleaseRV->getParent()); @@ -850,12 +844,6 @@ void ObjCARCOpt::OptimizeIndividualCalls(Function &F) { for (inst_iterator I = inst_begin(&F), E = inst_end(&F); I != E; ) { Instruction *Inst = &*I++; - if (auto *CI = dyn_cast<CallInst>(Inst)) - if (objcarc::hasRVOpBundle(CI)) { - BundledInsts->insertRVCall(&*I, CI); - Changed = true; - } - ARCInstKind Class = GetBasicARCInstKind(Inst); // Skip this loop if this instruction isn't itself an ARC intrinsic. @@ -934,11 +922,6 @@ void ObjCARCOpt::OptimizeIndividualCallImpl( // We can delete this call if it takes an inert value. SmallPtrSet<Value *, 1> VisitedPhis; - if (BundledInsts->contains(Inst)) { - UsedInThisFunction |= 1 << unsigned(Class); - return; - } - if (IsNoopOnGlobal(Class)) if (isInertARCValue(Inst->getOperand(0), VisitedPhis)) { if (!Inst->getType()->isVoidTy()) @@ -1559,7 +1542,7 @@ ObjCARCOpt::VisitInstructionTopDown(Instruction *Inst, if (Ptr == Arg) continue; // Handled above. TopDownPtrState &S = MI->second; - if (S.HandlePotentialAlterRefCount(Inst, Ptr, PA, Class, *BundledInsts)) + if (S.HandlePotentialAlterRefCount(Inst, Ptr, PA, Class)) continue; S.HandlePotentialUse(Inst, Ptr, PA, Class); @@ -2360,7 +2343,7 @@ void ObjCARCOpt::OptimizeReturns(Function &F) { ++NumRets; LLVM_DEBUG(dbgs() << "Erasing: " << *Retain << "\nErasing: " << *Autorelease << "\n"); - BundledInsts->eraseInst(Retain); + EraseInstruction(Retain); EraseInstruction(Autorelease); } } @@ -2393,6 +2376,11 @@ void ObjCARCOpt::init(Module &M) { if (!EnableARCOpts) return; + // If nothing in the Module uses ARC, don't do anything. + Run = ModuleHasARC(M); + if (!Run) + return; + // Intuitively, objc_retain and others are nocapture, however in practice // they are not, because they return their argument value. And objc_release // calls finalizers which can have arbitrary side effects. @@ -2406,18 +2394,16 @@ bool ObjCARCOpt::run(Function &F, AAResults &AA) { if (!EnableARCOpts) return false; - Changed = CFGChanged = false; - BundledRetainClaimRVs BRV(EP, false); - BundledInsts = &BRV; + // If nothing in the Module uses ARC, don't do anything. + if (!Run) + return false; + + Changed = false; LLVM_DEBUG(dbgs() << "<<< ObjCARCOpt: Visiting Function: " << F.getName() << " >>>" "\n"); - std::pair<bool, bool> R = BundledInsts->insertAfterInvokes(F, nullptr); - Changed |= R.first; - CFGChanged |= R.second; - PA.setAA(&AA); #ifndef NDEBUG @@ -2482,11 +2468,9 @@ PreservedAnalyses ObjCARCOptPass::run(Function &F, OCAO.init(*F.getParent()); bool Changed = OCAO.run(F, AM.getResult<AAManager>(F)); - bool CFGChanged = OCAO.hasCFGChanged(); if (Changed) { PreservedAnalyses PA; - if (!CFGChanged) - PA.preserveSet<CFGAnalyses>(); + PA.preserveSet<CFGAnalyses>(); return PA; } return PreservedAnalyses::all(); diff --git a/llvm/lib/Transforms/ObjCARC/PtrState.cpp b/llvm/lib/Transforms/ObjCARC/PtrState.cpp index cf4d029d37ac..6071ec3e4d91 100644 --- a/llvm/lib/Transforms/ObjCARC/PtrState.cpp +++ b/llvm/lib/Transforms/ObjCARC/PtrState.cpp @@ -11,7 +11,6 @@ #include "ObjCARC.h" #include "llvm/Analysis/ObjCARCAnalysisUtils.h" #include "llvm/Analysis/ObjCARCInstKind.h" -#include "llvm/Analysis/ObjCARCUtil.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/Instruction.h" #include "llvm/IR/Instructions.h" @@ -281,12 +280,6 @@ void BottomUpPtrState::HandlePotentialUse(BasicBlock *BB, Instruction *Inst, InsertAfter = skipDebugIntrinsics(InsertAfter); InsertReverseInsertPt(&*InsertAfter); - - // Don't insert anything between a call/invoke with operand bundle - // "clang.arc.rv" and the retainRV/claimRV call that uses the call result. - if (auto *CB = dyn_cast<CallBase>(Inst)) - if (objcarc::hasRVOpBundle(CB)) - SetCFGHazardAfflicted(true); }; // Check for possible direct uses. @@ -384,9 +377,10 @@ bool TopDownPtrState::MatchWithRelease(ARCMDKindCache &Cache, llvm_unreachable("Sequence unknown enum value"); } -bool TopDownPtrState::HandlePotentialAlterRefCount( - Instruction *Inst, const Value *Ptr, ProvenanceAnalysis &PA, - ARCInstKind Class, const BundledRetainClaimRVs &BundledRVs) { +bool TopDownPtrState::HandlePotentialAlterRefCount(Instruction *Inst, + const Value *Ptr, + ProvenanceAnalysis &PA, + ARCInstKind Class) { // Check for possible releases. Treat clang.arc.use as a releasing instruction // to prevent sinking a retain past it. if (!CanDecrementRefCount(Inst, Ptr, PA, Class) && @@ -402,11 +396,6 @@ bool TopDownPtrState::HandlePotentialAlterRefCount( assert(!HasReverseInsertPts()); InsertReverseInsertPt(Inst); - // Don't insert anything between a call/invoke with operand bundle - // "clang.arc.rv" and the retainRV/claimRV call that uses the call result. - if (BundledRVs.contains(Inst)) - SetCFGHazardAfflicted(true); - // One call can't cause a transition from S_Retain to S_CanRelease // and S_CanRelease to S_Use. If we've made the first transition, // we're done. diff --git a/llvm/lib/Transforms/ObjCARC/PtrState.h b/llvm/lib/Transforms/ObjCARC/PtrState.h index f143120ad6a4..66614c06cb79 100644 --- a/llvm/lib/Transforms/ObjCARC/PtrState.h +++ b/llvm/lib/Transforms/ObjCARC/PtrState.h @@ -31,7 +31,6 @@ class Value; namespace objcarc { class ARCMDKindCache; -class BundledRetainClaimRVs; class ProvenanceAnalysis; /// \enum Sequence @@ -203,8 +202,7 @@ struct TopDownPtrState : PtrState { ProvenanceAnalysis &PA, ARCInstKind Class); bool HandlePotentialAlterRefCount(Instruction *Inst, const Value *Ptr, - ProvenanceAnalysis &PA, ARCInstKind Class, - const BundledRetainClaimRVs &BundledRVs); + ProvenanceAnalysis &PA, ARCInstKind Class); }; } // end namespace objcarc diff --git a/llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp b/llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp index a2b80806f662..9e7cccc88412 100644 --- a/llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp +++ b/llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp @@ -247,9 +247,7 @@ static bool markTails(Function &F, bool &AllCallsAreTailCalls, isa<PseudoProbeInst>(&I)) continue; - // Special-case operand bundle "clang.arc.rv". - bool IsNoTail = CI->isNoTailCall() || CI->hasOperandBundlesOtherThan( - LLVMContext::OB_clang_arc_rv); + bool IsNoTail = CI->isNoTailCall() || CI->hasOperandBundles(); if (!IsNoTail && CI->doesNotAccessMemory()) { // A call to a readnone function whose arguments are all things computed diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp index 434b11fb613d..3026342cc4a6 100644 --- a/llvm/lib/Transforms/Utils/InlineFunction.cpp +++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp @@ -27,9 +27,8 @@ #include "llvm/Analysis/CaptureTracking.h" #include "llvm/Analysis/EHPersonalities.h" #include "llvm/Analysis/InstructionSimplify.h" -#include "llvm/Analysis/ObjCARCAnalysisUtils.h" -#include "llvm/Analysis/ObjCARCUtil.h" #include "llvm/Analysis/ProfileSummaryInfo.h" +#include "llvm/Transforms/Utils/Local.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/Analysis/VectorUtils.h" #include "llvm/IR/Argument.h" @@ -62,7 +61,6 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Transforms/Utils/AssumeBundleBuilder.h" #include "llvm/Transforms/Utils/Cloning.h" -#include "llvm/Transforms/Utils/Local.h" #include "llvm/Transforms/Utils/ValueMapper.h" #include <algorithm> #include <cassert> @@ -1652,98 +1650,6 @@ void llvm::updateProfileCallee( } } -/// An operand bundle "clang.arc.rv" on a call indicates the call result is -/// implicitly consumed by a call to retainRV or claimRV immediately after the -/// call. This function inlines the retainRV/claimRV calls. -/// -/// There are three cases to consider: -/// -/// 1. If there is a call to autoreleaseRV that takes a pointer to the returned -/// object in the callee return block, the autoreleaseRV call and the -/// retainRV/claimRV call in the caller cancel out. If the call in the caller -/// is a claimRV call, a call to objc_release is emitted. -/// -/// 2. If there is a call in the callee return block that doesn't have operand -/// bundle "clang.arc.rv", the operand bundle on the original call is -/// transferred to the call in the callee. -/// -/// 3. Otherwise, a call to objc_retain is inserted if the call in the caller is -/// a retainRV call. -static void -inlineRetainOrClaimRVCalls(CallBase &CB, - const SmallVectorImpl<ReturnInst *> &Returns) { - Module *Mod = CB.getModule(); - bool IsRetainRV = objcarc::hasRVOpBundle(&CB, true), IsClaimRV = !IsRetainRV; - - for (auto *RI : Returns) { - Value *RetOpnd = objcarc::GetRCIdentityRoot(RI->getOperand(0)); - BasicBlock::reverse_iterator I = ++(RI->getIterator().getReverse()); - BasicBlock::reverse_iterator EI = RI->getParent()->rend(); - bool InsertRetainCall = IsRetainRV; - IRBuilder<> Builder(RI->getContext()); - - // Walk backwards through the basic block looking for either a matching - // autoreleaseRV call or an unannotated call. - for (; I != EI;) { - auto CurI = I++; - - // Ignore casts. - if (isa<CastInst>(*CurI)) - continue; - - if (auto *II = dyn_cast<IntrinsicInst>(&*CurI)) { - if (II->getIntrinsicID() == Intrinsic::objc_autoreleaseReturnValue && - II->hasNUses(0) && - objcarc::GetRCIdentityRoot(II->getOperand(0)) == RetOpnd) { - // If we've found a matching authoreleaseRV call: - // - If the call is annotated with claimRV, insert a call to - // objc_release and erase the autoreleaseRV call. - // - If the call is annotated with retainRV, just erase the - // autoreleaseRV call. - if (IsClaimRV) { - Builder.SetInsertPoint(II); - Function *IFn = - Intrinsic::getDeclaration(Mod, Intrinsic::objc_release); - Value *BC = - Builder.CreateBitCast(RetOpnd, IFn->getArg(0)->getType()); - Builder.CreateCall(IFn, BC, ""); - } - II->eraseFromParent(); - InsertRetainCall = false; - } - } else if (auto *CI = dyn_cast<CallInst>(&*CurI)) { - if (objcarc::GetRCIdentityRoot(CI) == RetOpnd && - !objcarc::hasRVOpBundle(CI)) { - // If we've found an unannotated call that defines RetOpnd, add a - // "clang.arc.rv" operand bundle. - Value *BundleArgs[] = { - ConstantInt::get(Builder.getInt64Ty(), - objcarc::getRVOperandBundleEnum(IsRetainRV))}; - OperandBundleDef OB("clang.arc.rv", BundleArgs); - auto *NewCall = CallBase::addOperandBundle( - CI, LLVMContext::OB_clang_arc_rv, OB, CI); - NewCall->copyMetadata(*CI); - CI->replaceAllUsesWith(NewCall); - CI->eraseFromParent(); - InsertRetainCall = false; - } - } - - break; - } - - if (InsertRetainCall) { - // The call has operand bundle "clang.arc.rv"="retain" and we've failed to - // find a matching autoreleaseRV or an annotated call in the callee. Emit - // a call to objc_retain. - Builder.SetInsertPoint(RI); - Function *IFn = Intrinsic::getDeclaration(Mod, Intrinsic::objc_retain); - Value *BC = Builder.CreateBitCast(RetOpnd, IFn->getArg(0)->getType()); - Builder.CreateCall(IFn, BC, ""); - } - } -} - /// This function inlines the called function into the basic block of the /// caller. This returns false if it is not possible to inline this call. /// The program is still in a well defined state if this occurs though. @@ -1781,8 +1687,6 @@ llvm::InlineResult llvm::InlineFunction(CallBase &CB, InlineFunctionInfo &IFI, // ... and "funclet" operand bundles. if (Tag == LLVMContext::OB_funclet) continue; - if (Tag == LLVMContext::OB_clang_arc_rv) - continue; return InlineResult::failure("unsupported operand bundle"); } @@ -1949,10 +1853,6 @@ llvm::InlineResult llvm::InlineFunction(CallBase &CB, InlineFunctionInfo &IFI, // Remember the first block that is newly cloned over. FirstNewBlock = LastBlock; ++FirstNewBlock; - // Insert retainRV/clainRV runtime calls. - if (objcarc::hasRVOpBundle(&CB)) - inlineRetainOrClaimRVCalls(CB, Returns); - if (IFI.CallerBFI != nullptr && IFI.CalleeBFI != nullptr) // Update the BFI of blocks cloned into the caller. updateCallerBFI(OrigBB, VMap, IFI.CallerBFI, IFI.CalleeBFI, diff --git a/llvm/test/Bitcode/operand-bundles-bc-analyzer.ll b/llvm/test/Bitcode/operand-bundles-bc-analyzer.ll index cb7a3ee7eb71..f22fcbeb271e 100644 --- a/llvm/test/Bitcode/operand-bundles-bc-analyzer.ll +++ b/llvm/test/Bitcode/operand-bundles-bc-analyzer.ll @@ -9,7 +9,6 @@ ; CHECK-NEXT: <OPERAND_BUNDLE_TAG ; CHECK-NEXT: <OPERAND_BUNDLE_TAG ; CHECK-NEXT: <OPERAND_BUNDLE_TAG -; CHECK-NEXT: <OPERAND_BUNDLE_TAG ; CHECK-NEXT: </OPERAND_BUNDLE_TAGS_BLOCK ; CHECK: <FUNCTION_BLOCK diff --git a/llvm/test/CodeGen/AArch64/call-rv-marker.ll b/llvm/test/CodeGen/AArch64/call-rv-marker.ll index 7360c185bbbd..245d2c854c34 100644 --- a/llvm/test/CodeGen/AArch64/call-rv-marker.ll +++ b/llvm/test/CodeGen/AArch64/call-rv-marker.ll @@ -33,7 +33,7 @@ define dso_local i8* @rv_marker_1() { ; GISEL-NOT: mov x29, x29 ; entry: - %call = call i8* @foo1() [ "clang.arc.rv"(i64 0) ] + %call = call "rv_marker" i8* @foo1() ret i8* %call } @@ -49,7 +49,7 @@ define dso_local void @rv_marker_2_select(i32 %c) { entry: %tobool.not = icmp eq i32 %c, 0 %.sink = select i1 %tobool.not, i32 2, i32 1 - %call1 = call i8* @foo0(i32 %.sink) [ "clang.arc.rv"(i64 0) ] + %call1 = call "rv_marker" i8* @foo0(i32 %.sink) tail call void @foo2(i8* %call1) ret void } @@ -61,7 +61,7 @@ define dso_local void @rv_marker_3() personality i8* bitcast (i32 (...)* @__gxx_ ; SELDAG-NEXT: mov x29, x29 ; entry: - %call = call i8* @foo1() [ "clang.arc.rv"(i64 0) ] + %call = call "rv_marker" i8* @foo1() invoke void @objc_object(i8* %call) #5 to label %invoke.cont unwind label %lpad @@ -87,7 +87,7 @@ entry: %s = alloca %struct.S, align 1 %0 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 0 call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull %0) #2 - %call = invoke i8* @foo1() [ "clang.arc.rv"(i64 0) ] + %call = invoke "rv_marker" i8* @foo1() to label %invoke.cont unwind label %lpad invoke.cont: ; preds = %entry @@ -127,7 +127,7 @@ define dso_local i8* @rv_marker_5_indirect_call() { ; entry: %0 = load i8* ()*, i8* ()** @fptr, align 8 - %call = call i8* %0() [ "clang.arc.rv"(i64 0) ] + %call = call "rv_marker" i8* %0() tail call void @foo2(i8* %call) ret i8* %call } @@ -142,7 +142,7 @@ define dso_local void @rv_marker_multiarg(i64 %a, i64 %b, i64 %c) { ; CHECK-NEXT: bl foo ; SELDAG-NEXT: mov x29, x29 ; GISEL-NOT: mov x29, x29 - call void @foo(i64 %c, i64 %b, i64 %a) [ "clang.arc.rv"(i64 0) ] + call "rv_marker" void @foo(i64 %c, i64 %b, i64 %a) ret void } diff --git a/llvm/test/Transforms/DeadArgElim/deadretval.ll b/llvm/test/Transforms/DeadArgElim/deadretval.ll index 1eb0e6ecc186..5f3817c6728d 100644 --- a/llvm/test/Transforms/DeadArgElim/deadretval.ll +++ b/llvm/test/Transforms/DeadArgElim/deadretval.ll @@ -1,8 +1,4 @@ -; RUN: opt < %s -deadargelim -S | FileCheck %s - -@g0 = global i8 0, align 8 - -; CHECK-NOT: DEAD +; RUN: opt < %s -deadargelim -S | not grep DEAD ; Dead arg only used by dead retval define internal i32 @test(i32 %DEADARG) { @@ -20,22 +16,3 @@ define i32 @test3() { ret i32 %Y } -; The callee function's return type shouldn't be changed if the call result is -; used. - -; CHECK-LABEL: define internal i8* @callee4() - -define internal i8* @callee4(i8* %a0) { - ret i8* @g0; -} - -declare void @llvm.objc.clang.arc.noop.use(...) - -; CHECK-LABEL: define i8* @test4( -; CHECK: tail call i8* @callee4() [ "clang.arc.rv"(i64 0) ] - -define i8* @test4() { - %call = tail call i8* @callee4(i8* @g0) [ "clang.arc.rv"(i64 0) ] - call void (...) @llvm.objc.clang.arc.noop.use(i8* %call) - ret i8* @g0 -} diff --git a/llvm/test/Transforms/Inline/inline-retainRV-call.ll b/llvm/test/Transforms/Inline/inline-retainRV-call.ll deleted file mode 100644 index 243cf5453271..000000000000 --- a/llvm/test/Transforms/Inline/inline-retainRV-call.ll +++ /dev/null @@ -1,175 +0,0 @@ -; RUN: opt < %s -inline -S | FileCheck %s - -@g0 = global i8* null, align 8 -declare i8* @foo0() - -define i8* @callee0_autoreleaseRV() { - %call = call i8* @foo0() [ "clang.arc.rv"(i64 0) ] - %1 = tail call i8* @llvm.objc.autoreleaseReturnValue(i8* %call) - ret i8* %call -} - -; CHECK-LABEL: define void @test0_autoreleaseRV( -; CHECK: call i8* @foo0() [ "clang.arc.rv"(i64 0) ] - -define void @test0_autoreleaseRV() { - %call = call i8* @callee0_autoreleaseRV() [ "clang.arc.rv"(i64 0) ] - ret void -} - -; CHECK-LABEL: define void @test0_claimRV_autoreleaseRV( -; CHECK: %[[CALL:.*]] = call i8* @foo0() [ "clang.arc.rv"(i64 0) ] -; CHECK: call void @llvm.objc.release(i8* %[[CALL]]) -; CHECK-NEXT: ret void - -define void @test0_claimRV_autoreleaseRV() { - %call = call i8* @callee0_autoreleaseRV() [ "clang.arc.rv"(i64 1) ] - ret void -} - -; CHECK-LABEL: define void @test1_autoreleaseRV( -; CHECK: invoke i8* @foo0() [ "clang.arc.rv"(i64 0) ] - -define void @test1_autoreleaseRV() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { -entry: - %call = invoke i8* @callee0_autoreleaseRV() [ "clang.arc.rv"(i64 0) ] - to label %invoke.cont unwind label %lpad - -invoke.cont: - ret void - -lpad: - %0 = landingpad { i8*, i32 } - cleanup - resume { i8*, i32 } undef -} - -; CHECK-LABEL: define void @test1_claimRV_autoreleaseRV( -; CHECK: %[[INVOKE:.*]] = invoke i8* @foo0() [ "clang.arc.rv"(i64 0) ] -; CHECK: call void @llvm.objc.release(i8* %[[INVOKE]]) -; CHECK-NEXT: br - -define void @test1_claimRV_autoreleaseRV() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { -entry: - %call = invoke i8* @callee0_autoreleaseRV() [ "clang.arc.rv"(i64 1) ] - to label %invoke.cont unwind label %lpad - -invoke.cont: - ret void - -lpad: - %0 = landingpad { i8*, i32 } - cleanup - resume { i8*, i32 } undef -} - -define i8* @callee1_no_autoreleaseRV() { - %call = call i8* @foo0() - ret i8* %call -} - -; CHECK-LABEL: define void @test2_no_autoreleaseRV( -; CHECK: call i8* @foo0() [ "clang.arc.rv"(i64 0) ] -; CHECK-NEXT: ret void - -define void @test2_no_autoreleaseRV() { - %call = call i8* @callee1_no_autoreleaseRV() [ "clang.arc.rv"(i64 0) ] - ret void -} - -; CHECK-LABEL: define void @test2_claimRV_no_autoreleaseRV( -; CHECK: call i8* @foo0() [ "clang.arc.rv"(i64 1) ] -; CHECK-NEXT: ret void - -define void @test2_claimRV_no_autoreleaseRV() { - %call = call i8* @callee1_no_autoreleaseRV() [ "clang.arc.rv"(i64 1) ] - ret void -} - -; CHECK-LABEL: define void @test3_no_autoreleaseRV( -; CHECK: invoke i8* @foo0() [ "clang.arc.rv"(i64 0) ] - -define void @test3_no_autoreleaseRV() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { -entry: - %call = invoke i8* @callee1_no_autoreleaseRV() [ "clang.arc.rv"(i64 0) ] - to label %invoke.cont unwind label %lpad - -invoke.cont: - ret void - -lpad: - %0 = landingpad { i8*, i32 } - cleanup - resume { i8*, i32 } undef -} - -define i8* @callee2_nocall() { - %1 = load i8*, i8** @g0, align 8 - ret i8* %1 -} - -; Check that a call to @llvm.objc.retain is inserted if there is no matching -; autoreleaseRV call or a call. - -; CHECK-LABEL: define void @test4_nocall( -; CHECK: %[[V0:.*]] = load i8*, i8** @g0, -; CHECK-NEXT: call i8* @llvm.objc.retain(i8* %[[V0]]) -; CHECK-NEXT: ret void - -define void @test4_nocall() { - %call = call i8* @callee2_nocall() [ "clang.arc.rv"(i64 0) ] - ret void -} - -; CHECK-LABEL: define void @test4_claimRV_nocall( -; CHECK: %[[V0:.*]] = load i8*, i8** @g0, -; CHECK-NEXT: ret void - -define void @test4_claimRV_nocall() { - %call = call i8* @callee2_nocall() [ "clang.arc.rv"(i64 1) ] - ret void -} - -; Check that a call to @llvm.objc.retain is inserted if call to @foo already has -; the attribute. I'm not sure this will happen in practice. - -define i8* @callee3_marker() { - %1 = call i8* @foo0() [ "clang.arc.rv"(i64 0) ] - ret i8* %1 -} - -; CHECK-LABEL: define void @test5( -; CHECK: %[[V0:.*]] = call i8* @foo0() [ "clang.arc.rv"(i64 0) ] -; CHECK-NEXT: call i8* @llvm.objc.retain(i8* %[[V0]]) -; CHECK-NEXT: ret void - -define void @test5() { - %call = call i8* @callee3_marker() [ "clang.arc.rv"(i64 0) ] - ret void -} - -; Don't pair up an autoreleaseRV in the callee and an retainRV in the caller -; if there is an instruction between the ret instruction and the call to -; autoreleaseRV that isn't a cast instruction. - -define i8* @callee0_autoreleaseRV2() { - %call = call i8* @foo0() [ "clang.arc.rv"(i64 0) ] - %1 = tail call i8* @llvm.objc.autoreleaseReturnValue(i8* %call) - store i8* null, i8** @g0 - ret i8* %call -} - -; CHECK-LABEL: define void @test6( -; CHECK: %[[V0:.*]] = call i8* @foo0() [ "clang.arc.rv"(i64 0) ] -; CHECK: call i8* @llvm.objc.autoreleaseReturnValue(i8* %[[V0]]) -; CHECK: store i8* null, i8** @g0, align 8 -; CHECK: call i8* @llvm.objc.retain(i8* %[[V0]]) -; CHECK-NEXT: ret void - -define void @test6() { - %call = call i8* @callee0_autoreleaseRV2() [ "clang.arc.rv"(i64 0) ] - ret void -} - -declare i8* @llvm.objc.autoreleaseReturnValue(i8*) -declare i32 @__gxx_personality_v0(...) diff --git a/llvm/test/Transforms/ObjCARC/contract-marker-funclet.ll b/llvm/test/Transforms/ObjCARC/contract-marker-funclet.ll index 799548646d54..c0d6e0033dda 100644 --- a/llvm/test/Transforms/ObjCARC/contract-marker-funclet.ll +++ b/llvm/test/Transforms/ObjCARC/contract-marker-funclet.ll @@ -10,16 +10,6 @@ ; } ; } -; CHECK-LABEL: define void @"\01?g@@YAXXZ"() -; CHECK-LABEL: catch -; CHECK: call void asm sideeffect "movl{{.*}}%ebp, %ebp{{.*}}", ""() [ "funclet"(token %1) ] - -; CHECK-LABEL: catch.1 -; CHECK: call void asm sideeffect "movl{{.*}}%ebp, %ebp{{.*}}", ""() [ "funclet"(token %1) ] - -; CHECK-LABEL: invoke.cont -; CHECK: call void asm sideeffect "movl{{.*}}%ebp, %ebp{{.*}}", ""(){{$}} - define void @"\01?g@@YAXXZ"() personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) { entry: %call = invoke i8* @"\01?f@@YAPAUobjc_object@@XZ"() @@ -50,41 +40,23 @@ invoke.cont: ; preds = %entry ret void } -; CHECK-LABEL: define dso_local void @"?test_attr_claimRV@@YAXXZ"() -; CHECK: %[[CALL4:.*]] = notail call i8* @"?noexcept_func@@YAPAUobjc_object@@XZ"() [ "clang.arc.rv"(i64 1) ] -; CHECK: call i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8* %[[CALL4]]) - -; CHECK: %[[V1:.*]] = cleanuppad -; CHECK: %[[CALL:.*]] = notail call i8* @"?noexcept_func@@YAPAUobjc_object@@XZ"() [ "funclet"(token %[[V1]]), "clang.arc.rv"(i64 1) ] -; CHECK: call i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8* %[[CALL]]) [ "funclet"(token %[[V1]]) ] - -define dso_local void @"?test_attr_claimRV@@YAXXZ"() local_unnamed_addr #0 personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) { -entry: - invoke void @"?foo@@YAXXZ"() - to label %invoke.cont unwind label %ehcleanup - -invoke.cont: ; preds = %entry - %call.i4 = tail call i8* @"?noexcept_func@@YAPAUobjc_object@@XZ"() #2 [ "clang.arc.rv"(i64 1) ] - ret void - -ehcleanup: ; preds = %entry - %0 = cleanuppad within none [] - %call.i = call i8* @"?noexcept_func@@YAPAUobjc_object@@XZ"() #2 [ "funclet"(token %0), "clang.arc.rv"(i64 1) ] - cleanupret from %0 unwind to caller -} - declare i8* @"\01?f@@YAPAUobjc_object@@XZ"() declare i32 @__CxxFrameHandler3(...) -declare void @"?foo@@YAXXZ"() -declare i8* @"?noexcept_func@@YAPAUobjc_object@@XZ"() - declare dllimport i8* @llvm.objc.retainAutoreleasedReturnValue(i8*) -declare i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8*) declare dllimport void @llvm.objc.release(i8*) !llvm.module.flags = !{!0} !0 = !{i32 1, !"clang.arc.retainAutoreleasedReturnValueMarker", !"movl\09%ebp, %ebp\09\09// marker for objc_retainAutoreleaseReturnValue"} + +; CHECK-LABEL: catch +; CHECK: call void asm sideeffect "movl{{.*}}%ebp, %ebp{{.*}}", ""() [ "funclet"(token %1) ] + +; CHECK-LABEL: catch.1 +; CHECK: call void asm sideeffect "movl{{.*}}%ebp, %ebp{{.*}}", ""() [ "funclet"(token %1) ] + +; CHECK-LABEL: invoke.cont +; CHECK: call void asm sideeffect "movl{{.*}}%ebp, %ebp{{.*}}", ""(){{$}} diff --git a/llvm/test/Transforms/ObjCARC/contract-rv-attr.ll b/llvm/test/Transforms/ObjCARC/contract-rv-attr.ll deleted file mode 100644 index e460fb9c7e72..000000000000 --- a/llvm/test/Transforms/ObjCARC/contract-rv-attr.ll +++ /dev/null @@ -1,63 +0,0 @@ -; RUN: opt -objc-arc-contract -S < %s | FileCheck %s -; RUN: opt -passes=objc-arc-contract -S < %s | FileCheck %s - -; CHECK-LABEL: define void @test0() { -; CHECK: %[[CALL:.*]] = notail call i8* @foo() [ "clang.arc.rv"(i64 0) ] -; CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %[[CALL]]) - -define void @test0() { - %call1 = call i8* @foo() [ "clang.arc.rv"(i64 0) ] - ret void -} - -; CHECK-LABEL: define void @test1() { -; CHECK: %[[CALL:.*]] = notail call i8* @foo() [ "clang.arc.rv"(i64 1) ] -; CHECK: call i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8* %[[CALL]]) - -define void @test1() { - %call1 = call i8* @foo() [ "clang.arc.rv"(i64 1) ] - ret void -} - -; CHECK-LABEL:define i8* @test2( -; CHECK: %[[CALL1:.*]] = invoke i8* @foo() [ "clang.arc.rv"(i64 0) ] - -; CHECK: %[[V0:.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %[[CALL1]]) -; CHECK-NEXT: br - -; CHECK: %[[CALL3:.*]] = invoke i8* @foo() [ "clang.arc.rv"(i64 0) ] - -; CHECK: %[[V2:.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %[[CALL3]]) -; CHECK-NEXT: br - -; CHECK: %[[RETVAL:.*]] = phi i8* [ %[[V0]], {{.*}} ], [ %[[V2]], {{.*}} ] -; CHECK: ret i8* %[[RETVAL]] - -define i8* @test2(i1 zeroext %b) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { -entry: - br i1 %b, label %if.then, label %if.end - -if.then: - %call1 = invoke i8* @foo() [ "clang.arc.rv"(i64 0) ] - to label %cleanup unwind label %lpad - -lpad: - %0 = landingpad { i8*, i32 } - cleanup - resume { i8*, i32 } undef - -if.end: - %call3 = invoke i8* @foo() [ "clang.arc.rv"(i64 0) ] - to label %cleanup unwind label %lpad - -cleanup: - %retval.0 = phi i8* [ %call1, %if.then ], [ %call3, %if.end ] - ret i8* %retval.0 -} - -declare i8* @foo() -declare i32 @__gxx_personality_v0(...) - -!llvm.module.flags = !{!0} - -!0 = !{i32 1, !"clang.arc.retainAutoreleasedReturnValueMarker", !"mov\09fp, fp\09\09// marker for objc_retainAutoreleaseReturnValue"} diff --git a/llvm/test/Transforms/ObjCARC/contract.ll b/llvm/test/Transforms/ObjCARC/contract.ll index 36f0a842d0e6..d62fe221529e 100644 --- a/llvm/test/Transforms/ObjCARC/contract.ll +++ b/llvm/test/Transforms/ObjCARC/contract.ll @@ -227,15 +227,7 @@ define void @test13() { ret void } -; CHECK-LABEL: define void @test14( -; CHECK-NOT: clang.arc.noop.use -; CHECK: ret void -define void @test14(i8* %a, i8* %b) { - call void (...) @llvm.objc.clang.arc.noop.use(i8* %a, i8* %b) nounwind - ret void -} declare void @llvm.objc.clang.arc.use(...) nounwind -declare void @llvm.objc.clang.arc.noop.use(...) nounwind ; CHECK: attributes [[NUW]] = { nounwind } diff --git a/llvm/test/Transforms/ObjCARC/intrinsic-use.ll b/llvm/test/Transforms/ObjCARC/intrinsic-use.ll index bd4ac2965fb3..6f3815113d69 100644 --- a/llvm/test/Transforms/ObjCARC/intrinsic-use.ll +++ b/llvm/test/Transforms/ObjCARC/intrinsic-use.ll @@ -8,10 +8,8 @@ declare void @llvm.objc.release(i8*) declare i8* @llvm.objc.autorelease(i8*) declare void @llvm.objc.clang.arc.use(...) -declare void @llvm.objc.clang.arc.noop.use(...) declare void @test0_helper(i8*, i8**) -declare void @can_release(i8*) ; Ensure that we honor clang.arc.use as a use and don't miscompile ; the reduced test case from <rdar://13195034>. @@ -110,21 +108,6 @@ entry: ret void } -; ARC optimizer should be able to safely remove the retain/release pair as the -; call to @llvm.objc.clang.arc.noop.use is a no-op. - -; CHECK-LABEL: define void @test_arc_noop_use( -; CHECK-NEXT: call void @can_release(i8* %x) -; CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use( -; CHECK-NEXT: ret void - -define void @test_arc_noop_use(i8** %out, i8* %x) { - call i8* @llvm.objc.retain(i8* %x) - call void @can_release(i8* %x) - call void (...) @llvm.objc.clang.arc.noop.use(i8* %x) - call void @llvm.objc.release(i8* %x), !clang.imprecise_release !0 - ret void -} !0 = !{} diff --git a/llvm/test/Transforms/ObjCARC/rv.ll b/llvm/test/Transforms/ObjCARC/rv.ll index 07b6f73b2ab0..f89e9f7e39d9 100644 --- a/llvm/test/Transforms/ObjCARC/rv.ll +++ b/llvm/test/Transforms/ObjCARC/rv.ll @@ -452,29 +452,6 @@ bb1: ret i8* %v3 } -; Remove operand bundle "clang.arc.rv" and the autoreleaseRV call if the call -; is a tail call. - -; CHECK-LABEL: define i8* @test31( -; CHECK: %[[CALL:.*]] = tail call i8* @returner() -; CHECK: ret i8* %[[CALL]] - -define i8* @test31() { - %call = tail call i8* @returner() [ "clang.arc.rv"(i64 0) ] - %1 = call i8* @llvm.objc.autoreleaseReturnValue(i8* %call) - ret i8* %1 -} - -; CHECK-LABEL: define i8* @test32( -; CHECK: %[[CALL:.*]] = call i8* @returner() [ "clang.arc.rv"(i64 0) ] -; CHECK: call i8* @llvm.objc.autoreleaseReturnValue(i8* %[[CALL]]) - -define i8* @test32() { - %call = call i8* @returner() [ "clang.arc.rv"(i64 0) ] - %1 = call i8* @llvm.objc.autoreleaseReturnValue(i8* %call) - ret i8* %1 -} - !0 = !{} ; CHECK: attributes [[NUW]] = { nounwind } diff --git a/llvm/test/Transforms/TailCallElim/operand-bundles.ll b/llvm/test/Transforms/TailCallElim/deopt-bundle.ll similarity index 84% rename from llvm/test/Transforms/TailCallElim/operand-bundles.ll rename to llvm/test/Transforms/TailCallElim/deopt-bundle.ll index ad168bc7251e..f651e462c1f5 100644 --- a/llvm/test/Transforms/TailCallElim/operand-bundles.ll +++ b/llvm/test/Transforms/TailCallElim/deopt-bundle.ll @@ -55,13 +55,3 @@ catch: exit: ret void } - -; CHECK-LABEL: @test_clang_arc_rv( -; CHECK: tail call i8* @getObj( - -declare i8* @getObj() - -define i8* @test_clang_arc_rv() { - %r = call i8* @getObj() [ "clang.arc.rv"(i64 0) ] - ret i8* %r -} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits