// REQUIRES: x86-registered-target
-// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm-bc -o /dev/null -fexperimental-new-pass-manager -fdebug-pass-manager -flto=full -O0 %s 2>&1 | FileCheck %s \
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm-bc -o /dev/null -mllvm -verify-cfg-preserved=0 -fexperimental-new-pass-manager -fdebug-pass-manager -flto=full -O0 %s 2>&1 | FileCheck %s \
// RUN: -check-prefix=CHECK-FULL-O0
-// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm-bc -o /dev/null -fexperimental-new-pass-manager -fdebug-pass-manager -flto=thin -O0 %s 2>&1 | FileCheck %s \
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm-bc -o /dev/null -mllvm -verify-cfg-preserved=0 -fexperimental-new-pass-manager -fdebug-pass-manager -flto=thin -O0 %s 2>&1 | FileCheck %s \
// RUN: -check-prefix=CHECK-THIN-O0
-// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm-bc -o /dev/null -fexperimental-new-pass-manager -fdebug-pass-manager -flto=full -O1 %s 2>&1 | FileCheck %s \
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm-bc -o /dev/null -mllvm -verify-cfg-preserved=0 -fexperimental-new-pass-manager -fdebug-pass-manager -flto=full -O1 %s 2>&1 | FileCheck %s \
// RUN: -check-prefix=CHECK-FULL-OPTIMIZED
-// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm-bc -o /dev/null -fexperimental-new-pass-manager -fdebug-pass-manager -flto=thin -O1 %s 2>&1 | FileCheck %s \
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm-bc -o /dev/null -mllvm -verify-cfg-preserved=0 -fexperimental-new-pass-manager -fdebug-pass-manager -flto=thin -O1 %s 2>&1 | FileCheck %s \
// RUN: -check-prefix=CHECK-THIN-OPTIMIZED
-// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm-bc -o /dev/null -fexperimental-new-pass-manager -fdebug-pass-manager -flto=full -O2 %s 2>&1 | FileCheck %s \
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm-bc -o /dev/null -mllvm -verify-cfg-preserved=0 -fexperimental-new-pass-manager -fdebug-pass-manager -flto=full -O2 %s 2>&1 | FileCheck %s \
// RUN: -check-prefix=CHECK-FULL-OPTIMIZED
-// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm-bc -o /dev/null -fexperimental-new-pass-manager -fdebug-pass-manager -flto=thin -O2 %s 2>&1 | FileCheck %s \
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm-bc -o /dev/null -mllvm -verify-cfg-preserved=0 -fexperimental-new-pass-manager -fdebug-pass-manager -flto=thin -O2 %s 2>&1 | FileCheck %s \
// RUN: -check-prefix=CHECK-THIN-OPTIMIZED
-// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm-bc -o /dev/null -fexperimental-new-pass-manager -fdebug-pass-manager -flto=full -O3 %s 2>&1 | FileCheck %s \
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm-bc -o /dev/null -mllvm -verify-cfg-preserved=0 -fexperimental-new-pass-manager -fdebug-pass-manager -flto=full -O3 %s 2>&1 | FileCheck %s \
// RUN: -check-prefix=CHECK-FULL-OPTIMIZED
-// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm-bc -o /dev/null -fexperimental-new-pass-manager -fdebug-pass-manager -flto=thin -O3 %s 2>&1 | FileCheck %s \
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm-bc -o /dev/null -mllvm -verify-cfg-preserved=0 -fexperimental-new-pass-manager -fdebug-pass-manager -flto=thin -O3 %s 2>&1 | FileCheck %s \
// RUN: -check-prefix=CHECK-THIN-OPTIMIZED
-// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm-bc -o /dev/null -fexperimental-new-pass-manager -fdebug-pass-manager -flto=full -Os %s 2>&1 | FileCheck %s \
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm-bc -o /dev/null -mllvm -verify-cfg-preserved=0 -fexperimental-new-pass-manager -fdebug-pass-manager -flto=full -Os %s 2>&1 | FileCheck %s \
// RUN: -check-prefix=CHECK-FULL-OPTIMIZED
-// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm-bc -o /dev/null -fexperimental-new-pass-manager -fdebug-pass-manager -flto=thin -Os %s 2>&1 | FileCheck %s \
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm-bc -o /dev/null -mllvm -verify-cfg-preserved=0 -fexperimental-new-pass-manager -fdebug-pass-manager -flto=thin -Os %s 2>&1 | FileCheck %s \
// RUN: -check-prefix=CHECK-THIN-OPTIMIZED
-// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm-bc -o /dev/null -fexperimental-new-pass-manager -fdebug-pass-manager -flto=full -Oz %s 2>&1 | FileCheck %s \
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm-bc -o /dev/null -mllvm -verify-cfg-preserved=0 -fexperimental-new-pass-manager -fdebug-pass-manager -flto=full -Oz %s 2>&1 | FileCheck %s \
// RUN: -check-prefix=CHECK-FULL-OPTIMIZED
-// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm-bc -o /dev/null -fexperimental-new-pass-manager -fdebug-pass-manager -flto=thin -Oz %s 2>&1 | FileCheck %s \
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm-bc -o /dev/null -mllvm -verify-cfg-preserved=0 -fexperimental-new-pass-manager -fdebug-pass-manager -flto=thin -Oz %s 2>&1 | FileCheck %s \
// RUN: -check-prefix=CHECK-THIN-OPTIMIZED
// CHECK-FULL-O0: Running pass: AlwaysInlinerPass
// CHECK-FULL-O0-NEXT: Running analysis: InnerAnalysisManagerProxy
// CHECK-FULL-O0-NEXT: Running analysis: ProfileSummaryAnalysis
-// CHECK-FULL-O0: Running pass: CoroSplitPass
-// CHECK-FULL-O0-NEXT: Running pass: CoroCleanupPass
+// CHECK-FULL-O0-NEXT: Running pass: CoroConditionalWrapper
// CHECK-FULL-O0-NEXT: Running pass: CanonicalizeAliasesPass
// CHECK-FULL-O0-NEXT: Running pass: NameAnonGlobalPass
// CHECK-FULL-O0-NEXT: Running pass: AnnotationRemarksPass
+// CHECK-FULL-O0-NEXT: Running analysis: TargetLibraryAnalysis
// CHECK-FULL-O0-NEXT: Running pass: VerifierPass
// CHECK-FULL-O0-NEXT: Running analysis: VerifierAnalysis
// CHECK-FULL-O0-NEXT: Running pass: BitcodeWriterPass
// CHECK-THIN-O0: Running pass: AlwaysInlinerPass
// CHECK-THIN-O0-NEXT: Running analysis: InnerAnalysisManagerProxy
// CHECK-THIN-O0-NEXT: Running analysis: ProfileSummaryAnalysis
-// CHECK-THIN-O0: Running pass: CoroCleanupPass
+// CHECK-THIN-O0-NEXT: Running pass: CoroConditionalWrapper
// CHECK-THIN-O0-NEXT: Running pass: CanonicalizeAliasesPass
// CHECK-THIN-O0-NEXT: Running pass: NameAnonGlobalPass
// CHECK-THIN-O0-NEXT: Running pass: AnnotationRemarksPass
+// CHECK-THIN-O0-NEXT: Running analysis: TargetLibraryAnalysis
// CHECK-THIN-O0-NEXT: Running pass: VerifierPass
// CHECK-THIN-O0-NEXT: Running analysis: VerifierAnalysis
// CHECK-THIN-O0-NEXT: Running pass: ThinLTOBitcodeWriterPass
--- /dev/null
+//===---- CoroConditionalWrapper.h ------------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_COROUTINES_COROCONDITIONALWRAPPER_H
+#define LLVM_TRANSFORMS_COROUTINES_COROCONDITIONALWRAPPER_H
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+class Module;
+
+// Only runs passes in the contained pass manager if the module contains any
+// coroutine intrinsic declarations.
+struct CoroConditionalWrapper : PassInfoMixin<CoroConditionalWrapper> {
+ CoroConditionalWrapper(ModulePassManager &&);
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
+ static bool isRequired() { return true; }
+
+private:
+ ModulePassManager PM;
+};
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_COROUTINES_COROCONDITIONALWRAPPER_H
#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/AggressiveInstCombine/AggressiveInstCombine.h"
#include "llvm/Transforms/Coroutines/CoroCleanup.h"
+#include "llvm/Transforms/Coroutines/CoroConditionalWrapper.h"
#include "llvm/Transforms/Coroutines/CoroEarly.h"
#include "llvm/Transforms/Coroutines/CoroElide.h"
#include "llvm/Transforms/Coroutines/CoroSplit.h"
MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
}
- MPM.addPass(createModuleToFunctionPassAdaptor(CoroEarlyPass()));
+ ModulePassManager CoroPM;
+ CoroPM.addPass(createModuleToFunctionPassAdaptor(CoroEarlyPass()));
CGSCCPassManager CGPM;
CGPM.addPass(CoroSplitPass());
- MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
- MPM.addPass(createModuleToFunctionPassAdaptor(CoroCleanupPass()));
+ CoroPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
+ CoroPM.addPass(createModuleToFunctionPassAdaptor(CoroCleanupPass()));
+ CoroPM.addPass(GlobalDCEPass());
+ MPM.addPass(CoroConditionalWrapper(std::move(CoroPM)));
for (auto &C : OptimizerLastEPCallbacks)
C(MPM, Level);
add_llvm_component_library(LLVMCoroutines
Coroutines.cpp
CoroCleanup.cpp
+ CoroConditionalWrapper.cpp
CoroEarly.cpp
CoroElide.cpp
CoroFrame.cpp
--- /dev/null
+//===- CoroConditionalWrapper.cpp -----------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Transforms/Coroutines/CoroConditionalWrapper.h"
+#include "CoroInternal.h"
+#include "llvm/IR/Module.h"
+
+using namespace llvm;
+
+CoroConditionalWrapper::CoroConditionalWrapper(ModulePassManager &&PM)
+ : PM(std::move(PM)) {}
+
+PreservedAnalyses CoroConditionalWrapper::run(Module &M,
+ ModuleAnalysisManager &AM) {
+ if (!coro::declaresAnyIntrinsic(M))
+ return PreservedAnalyses::all();
+
+ return PM.run(M, AM);
+}
namespace coro {
+bool declaresAnyIntrinsic(const Module &M);
bool declaresIntrinsics(const Module &M,
const std::initializer_list<StringRef>);
void replaceCoroFree(CoroIdInst *CoroId, bool Elide);
return Bitcast;
}
+// NOTE: Must be sorted!
+static const char *const CoroIntrinsics[] = {
+ "llvm.coro.align",
+ "llvm.coro.alloc",
+ "llvm.coro.async.context.alloc",
+ "llvm.coro.async.context.dealloc",
+ "llvm.coro.async.resume",
+ "llvm.coro.async.size.replace",
+ "llvm.coro.async.store_resume",
+ "llvm.coro.begin",
+ "llvm.coro.destroy",
+ "llvm.coro.done",
+ "llvm.coro.end",
+ "llvm.coro.end.async",
+ "llvm.coro.frame",
+ "llvm.coro.free",
+ "llvm.coro.id",
+ "llvm.coro.id.async",
+ "llvm.coro.id.retcon",
+ "llvm.coro.id.retcon.once",
+ "llvm.coro.noop",
+ "llvm.coro.prepare.async",
+ "llvm.coro.prepare.retcon",
+ "llvm.coro.promise",
+ "llvm.coro.resume",
+ "llvm.coro.save",
+ "llvm.coro.size",
+ "llvm.coro.subfn.addr",
+ "llvm.coro.suspend",
+ "llvm.coro.suspend.async",
+ "llvm.coro.suspend.retcon",
+};
+
#ifndef NDEBUG
static bool isCoroutineIntrinsicName(StringRef Name) {
- // NOTE: Must be sorted!
- static const char *const CoroIntrinsics[] = {
- "llvm.coro.align",
- "llvm.coro.alloc",
- "llvm.coro.async.context.alloc",
- "llvm.coro.async.context.dealloc",
- "llvm.coro.async.resume",
- "llvm.coro.async.size.replace",
- "llvm.coro.async.store_resume",
- "llvm.coro.begin",
- "llvm.coro.destroy",
- "llvm.coro.done",
- "llvm.coro.end",
- "llvm.coro.end.async",
- "llvm.coro.frame",
- "llvm.coro.free",
- "llvm.coro.id",
- "llvm.coro.id.async",
- "llvm.coro.id.retcon",
- "llvm.coro.id.retcon.once",
- "llvm.coro.noop",
- "llvm.coro.prepare.async",
- "llvm.coro.prepare.retcon",
- "llvm.coro.promise",
- "llvm.coro.resume",
- "llvm.coro.save",
- "llvm.coro.size",
- "llvm.coro.subfn.addr",
- "llvm.coro.suspend",
- "llvm.coro.suspend.async",
- "llvm.coro.suspend.retcon",
- };
return Intrinsic::lookupLLVMIntrinsicByName(CoroIntrinsics, Name) != -1;
}
#endif
+bool coro::declaresAnyIntrinsic(const Module &M) {
+ for (StringRef Name : CoroIntrinsics) {
+ assert(isCoroutineIntrinsicName(Name) && "not a coroutine intrinsic");
+ if (M.getNamedValue(Name))
+ return true;
+ }
+
+ return false;
+}
+
// Verifies if a module has named values listed. Also, in debug mode verifies
// that names are intrinsic names.
bool coro::declaresIntrinsics(const Module &M,
; CHECK-DEFAULT-NEXT: Running analysis: ProfileSummaryAnalysis
; CHECK-MATRIX: Running pass: LowerMatrixIntrinsicsPass
; CHECK-MATRIX-NEXT: Running analysis: TargetIRAnalysis
-; CHECK-CORO-NEXT: Running pass: CoroEarlyPass
-; CHECK-CORO-NEXT: Running analysis: InnerAnalysisManagerProxy
-; CHECK-CORO-NEXT: Running analysis: LazyCallGraphAnalysis
-; CHECK-CORO-NEXT: Running analysis: TargetLibraryAnalysis
-; CHECK-CORO-NEXT: Running analysis: FunctionAnalysisManagerCGSCCProxy
-; CHECK-CORO-NEXT: Running analysis: OuterAnalysisManagerProxy
-; CHECK-CORO-NEXT: Running pass: CoroSplitPass
-; CHECK-CORO-NEXT: Running pass: CoroCleanupPass
+; CHECK-CORO-NEXT: Running pass: CoroConditionalWrapper
; CHECK-PRE-LINK: Running pass: CanonicalizeAliasesPass
; CHECK-PRE-LINK-NEXT: Running pass: NameAnonGlobalPass
; CHECK-THINLTO: Running pass: Annotation2MetadataPass
; CHECK-LTO-NEXT: Running pass: LowerTypeTestsPass
; CHECK-LTO-NEXT: Running pass: LowerTypeTestsPass
; CHECK-CORO-NEXT: Running pass: AnnotationRemarksPass
+; CHECK-CORO-NEXT: Running analysis: TargetLibraryAnalysis
; CHECK-LTO-NEXT: Running pass: AnnotationRemarksPass
; CHECK-LTO-NEXT: Running analysis: TargetLibraryAnalysis
; CHECK-NEXT: Running pass: PrintModulePass
--- /dev/null
+; RUN: opt -passes='default<O0>' -S < %s | FileCheck %s
+
+; CHECK-NOT: call .*llvm.coro.size
+
+declare i64 @llvm.coro.size.i64()
+define internal i64 @f() {
+ %a = call i64 @llvm.coro.size.i64()
+ ret i64 %a
+}
+
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx10.12.0"
-; CHECK: define internal { i8*, i32 } @f(i8* %buffer, i32* %array)
-; CHECK-NEXT: entry:
-; CHECK-NEXT: unreachable
+; CHECK-NOT: define
define internal {i8*, i32} @f(i8* %buffer, i32* %array) {
entry:
; CHECK-ALL: CoroSplitPass
; CHECK-ALL: CoroCleanupPass
+declare token @llvm.coro.id(i32, i8*, i8*, i8*)
+
define void @foo() {
ret void
}
]
sources = [
"CoroCleanup.cpp",
+ "CoroConditionalWrapper.cpp",
"CoroEarly.cpp",
"CoroElide.cpp",
"CoroFrame.cpp",