diff options
author | David Majnemer <david.majnemer@gmail.com> | 2016-07-28 21:04:31 +0000 |
---|---|---|
committer | David Majnemer <david.majnemer@gmail.com> | 2016-07-28 21:04:31 +0000 |
commit | 3d32b7ed0d811b5ed5267f581cdc40f18c87faab (patch) | |
tree | 4303317f5aee2a3fc855e7b987377f7be8ab846a /llvm/lib | |
parent | 644f3f066b95f6ba83f636d7738f680a6a9f126a (diff) | |
download | bcm5719-llvm-3d32b7ed0d811b5ed5267f581cdc40f18c87faab.tar.gz bcm5719-llvm-3d32b7ed0d811b5ed5267f581cdc40f18c87faab.zip |
[coroutines] Part 3 of N: Adding Boilerplate for Coroutine Passes
This adds boilerplate code for all coroutine passes,
the passes are no-ops for now.
Also, a small test has been added to verify that passes execute in
the expected order or not at all if coroutine support is disabled.
Patch by Gor Nishanov!
Differential Revision: https://reviews.llvm.org/D22847
llvm-svn: 277033
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Transforms/CMakeLists.txt | 1 | ||||
-rw-r--r-- | llvm/lib/Transforms/Coroutines/CMakeLists.txt | 8 | ||||
-rw-r--r-- | llvm/lib/Transforms/Coroutines/CoroCleanup.cpp | 42 | ||||
-rw-r--r-- | llvm/lib/Transforms/Coroutines/CoroEarly.cpp | 43 | ||||
-rw-r--r-- | llvm/lib/Transforms/Coroutines/CoroElide.cpp | 49 | ||||
-rw-r--r-- | llvm/lib/Transforms/Coroutines/CoroInternal.h | 28 | ||||
-rw-r--r-- | llvm/lib/Transforms/Coroutines/CoroSplit.cpp | 45 | ||||
-rw-r--r-- | llvm/lib/Transforms/Coroutines/Coroutines.cpp | 68 | ||||
-rw-r--r-- | llvm/lib/Transforms/Coroutines/LLVMBuild.txt | 22 | ||||
-rw-r--r-- | llvm/lib/Transforms/LLVMBuild.txt | 2 |
10 files changed, 307 insertions, 1 deletions
diff --git a/llvm/lib/Transforms/CMakeLists.txt b/llvm/lib/Transforms/CMakeLists.txt index 2bb6e905909..67bdeb27212 100644 --- a/llvm/lib/Transforms/CMakeLists.txt +++ b/llvm/lib/Transforms/CMakeLists.txt @@ -6,3 +6,4 @@ add_subdirectory(IPO) add_subdirectory(Vectorize) add_subdirectory(Hello) add_subdirectory(ObjCARC) +add_subdirectory(Coroutines) diff --git a/llvm/lib/Transforms/Coroutines/CMakeLists.txt b/llvm/lib/Transforms/Coroutines/CMakeLists.txt new file mode 100644 index 00000000000..0e9e9e43e8e --- /dev/null +++ b/llvm/lib/Transforms/Coroutines/CMakeLists.txt @@ -0,0 +1,8 @@ +add_llvm_library(LLVMCoroutines + Coroutines.cpp + CoroCleanup.cpp + CoroEarly.cpp + CoroElide.cpp + CoroSplit.cpp + ) + diff --git a/llvm/lib/Transforms/Coroutines/CoroCleanup.cpp b/llvm/lib/Transforms/Coroutines/CoroCleanup.cpp new file mode 100644 index 00000000000..078a09f6e1f --- /dev/null +++ b/llvm/lib/Transforms/Coroutines/CoroCleanup.cpp @@ -0,0 +1,42 @@ +//===- CoroCleanup.cpp - Coroutine Cleanup Pass ---------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// This pass lowers all remaining coroutine intrinsics. +//===----------------------------------------------------------------------===// + +#include "CoroInternal.h" +#include "llvm/Pass.h" + +using namespace llvm; + +#define DEBUG_TYPE "coro-cleanup" + +//===----------------------------------------------------------------------===// +// Top Level Driver +//===----------------------------------------------------------------------===// + +namespace { + +struct CoroCleanup : FunctionPass { + static char ID; // Pass identification, replacement for typeid + + CoroCleanup() : FunctionPass(ID) {} + + bool runOnFunction(Function &F) override { return false; } + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.setPreservesAll(); + } +}; + +} + +char CoroCleanup::ID = 0; +INITIALIZE_PASS(CoroCleanup, "coro-cleanup", + "Lower all coroutine related intrinsics", false, false) + +Pass *llvm::createCoroCleanupPass() { return new CoroCleanup(); } diff --git a/llvm/lib/Transforms/Coroutines/CoroEarly.cpp b/llvm/lib/Transforms/Coroutines/CoroEarly.cpp new file mode 100644 index 00000000000..baedb2422d0 --- /dev/null +++ b/llvm/lib/Transforms/Coroutines/CoroEarly.cpp @@ -0,0 +1,43 @@ +//===- CoroEarly.cpp - Coroutine Early Function Pass ----------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// This pass lowers coroutine intrinsics that hide the details of the exact +// calling convention for coroutine resume and destroy functions and details of +// the structure of the coroutine frame. +//===----------------------------------------------------------------------===// + +#include "CoroInternal.h" +#include "llvm/Pass.h" + +using namespace llvm; + +#define DEBUG_TYPE "coro-early" + +//===----------------------------------------------------------------------===// +// Top Level Driver +//===----------------------------------------------------------------------===// + +namespace { + +struct CoroEarly : public FunctionPass { + static char ID; // Pass identification, replacement for typeid + CoroEarly() : FunctionPass(ID) {} + + bool runOnFunction(Function &F) override { return false; } + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.setPreservesAll(); + } +}; + +} + +char CoroEarly::ID = 0; +INITIALIZE_PASS(CoroEarly, "coro-early", "Lower early coroutine intrinsics", + false, false) + +Pass *llvm::createCoroEarlyPass() { return new CoroEarly(); } diff --git a/llvm/lib/Transforms/Coroutines/CoroElide.cpp b/llvm/lib/Transforms/Coroutines/CoroElide.cpp new file mode 100644 index 00000000000..b21380ca008 --- /dev/null +++ b/llvm/lib/Transforms/Coroutines/CoroElide.cpp @@ -0,0 +1,49 @@ +//===- CoroElide.cpp - Coroutine Frame Allocation Elision Pass ------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// This pass replaces dynamic allocation of coroutine frame with alloca and +// replaces calls to llvm.coro.resume and llvm.coro.destroy with direct calls +// to coroutine sub-functions. +//===----------------------------------------------------------------------===// + +#include "CoroInternal.h" +#include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Pass.h" + +using namespace llvm; + +#define DEBUG_TYPE "coro-elide" + +//===----------------------------------------------------------------------===// +// Top Level Driver +//===----------------------------------------------------------------------===// + +namespace { + +struct CoroElide : FunctionPass { + static char ID; + CoroElide() : FunctionPass(ID) {} + bool runOnFunction(Function &F) override { return false; } + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.setPreservesAll(); + } +}; + +} + +char CoroElide::ID = 0; +INITIALIZE_PASS_BEGIN( + CoroElide, "coro-elide", + "Coroutine frame allocation elision and indirect calls replacement", false, + false) +INITIALIZE_PASS_END( + CoroElide, "coro-elide", + "Coroutine frame allocation elision and indirect calls replacement", false, + false) + +Pass *llvm::createCoroElidePass() { return new CoroElide(); } diff --git a/llvm/lib/Transforms/Coroutines/CoroInternal.h b/llvm/lib/Transforms/Coroutines/CoroInternal.h new file mode 100644 index 00000000000..97620921fc9 --- /dev/null +++ b/llvm/lib/Transforms/Coroutines/CoroInternal.h @@ -0,0 +1,28 @@ +//===- CoroInternal.h - Internal Coroutine interfaces ---------*- C++ -*---===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Common definitions/declarations used internally by coroutine lowering passes. +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TRANSFORMS_COROUTINES_COROINTERNAL_H +#define LLVM_LIB_TRANSFORMS_COROUTINES_COROINTERNAL_H + +#include "llvm/Transforms/Coroutines.h" + +namespace llvm { + +class PassRegistry; + +void initializeCoroEarlyPass(PassRegistry &); +void initializeCoroSplitPass(PassRegistry &); +void initializeCoroElidePass(PassRegistry &); +void initializeCoroCleanupPass(PassRegistry &); + +} + +#endif diff --git a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp new file mode 100644 index 00000000000..70d5aa92f20 --- /dev/null +++ b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp @@ -0,0 +1,45 @@ +//===- CoroSplit.cpp - Converts a coroutine into a state machine ----------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// This pass builds the coroutine frame and outlines resume and destroy parts +// of the coroutine into separate functions. +//===----------------------------------------------------------------------===// + +#include "CoroInternal.h" +#include "llvm/Analysis/CallGraphSCCPass.h" + +using namespace llvm; + +#define DEBUG_TYPE "coro-split" + +//===----------------------------------------------------------------------===// +// Top Level Driver +//===----------------------------------------------------------------------===// + +namespace { + +struct CoroSplit : public CallGraphSCCPass { + static char ID; // Pass identification, replacement for typeid + CoroSplit() : CallGraphSCCPass(ID) {} + + bool runOnSCC(CallGraphSCC &SCC) override { return false; } + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.setPreservesAll(); + CallGraphSCCPass::getAnalysisUsage(AU); + } +}; + +} + +char CoroSplit::ID = 0; +INITIALIZE_PASS( + CoroSplit, "coro-split", + "Split coroutine into a set of functions driving its state machine", false, + false) + +Pass *llvm::createCoroSplitPass() { return new CoroSplit(); } diff --git a/llvm/lib/Transforms/Coroutines/Coroutines.cpp b/llvm/lib/Transforms/Coroutines/Coroutines.cpp new file mode 100644 index 00000000000..70b3d41a58b --- /dev/null +++ b/llvm/lib/Transforms/Coroutines/Coroutines.cpp @@ -0,0 +1,68 @@ +//===-- Coroutines.cpp ----------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// This file implements the common infrastructure for Coroutine Passes. +//===----------------------------------------------------------------------===// + +#include "CoroInternal.h" +#include "llvm/IR/LegacyPassManager.h" +#include "llvm/IR/Verifier.h" +#include "llvm/InitializePasses.h" +#include "llvm/Transforms/IPO.h" +#include "llvm/Transforms/IPO/PassManagerBuilder.h" + +using namespace llvm; + +void llvm::initializeCoroutines(PassRegistry &Registry) { + initializeCoroEarlyPass(Registry); + initializeCoroSplitPass(Registry); + initializeCoroElidePass(Registry); + initializeCoroCleanupPass(Registry); +} + +static void addCoroutineOpt0Passes(const PassManagerBuilder &Builder, + legacy::PassManagerBase &PM) { + PM.add(createCoroSplitPass()); + PM.add(createCoroElidePass()); + + PM.add(createBarrierNoopPass()); + PM.add(createCoroCleanupPass()); +} + +static void addCoroutineEarlyPasses(const PassManagerBuilder &Builder, + legacy::PassManagerBase &PM) { + PM.add(createCoroEarlyPass()); +} + +static void addCoroutineScalarOptimizerPasses(const PassManagerBuilder &Builder, + legacy::PassManagerBase &PM) { + PM.add(createCoroElidePass()); +} + +static void addCoroutineSCCPasses(const PassManagerBuilder &Builder, + legacy::PassManagerBase &PM) { + PM.add(createCoroSplitPass()); +} + +static void addCoroutineOptimizerLastPasses(const PassManagerBuilder &Builder, + legacy::PassManagerBase &PM) { + PM.add(createCoroCleanupPass()); +} + +void llvm::addCoroutinePassesToExtensionPoints(PassManagerBuilder &Builder) { + Builder.addExtension(PassManagerBuilder::EP_EarlyAsPossible, + addCoroutineEarlyPasses); + Builder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, + addCoroutineOpt0Passes); + Builder.addExtension(PassManagerBuilder::EP_CGSCCOptimizerLate, + addCoroutineSCCPasses); + Builder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate, + addCoroutineScalarOptimizerPasses); + Builder.addExtension(PassManagerBuilder::EP_OptimizerLast, + addCoroutineOptimizerLastPasses); +} diff --git a/llvm/lib/Transforms/Coroutines/LLVMBuild.txt b/llvm/lib/Transforms/Coroutines/LLVMBuild.txt new file mode 100644 index 00000000000..41dc4b031a4 --- /dev/null +++ b/llvm/lib/Transforms/Coroutines/LLVMBuild.txt @@ -0,0 +1,22 @@ +;===- ./lib/Transforms/Coroutines/LLVMBuild.txt ----------------*- Conf -*--===; +; +; The LLVM Compiler Infrastructure +; +; This file is distributed under the University of Illinois Open Source +; License. See LICENSE.TXT for details. +; +;===------------------------------------------------------------------------===; +; +; This is an LLVMBuild description file for the components in this subdirectory. +; +; For more information on the LLVMBuild system, please see: +; +; http://llvm.org/docs/LLVMBuild.html +; +;===------------------------------------------------------------------------===; + +[component_0] +type = Library +name = Coroutines +parent = Transforms +required_libraries = Analysis Core IPO Scalar Support TransformUtils diff --git a/llvm/lib/Transforms/LLVMBuild.txt b/llvm/lib/Transforms/LLVMBuild.txt index 15e9fba0a76..95482ad2022 100644 --- a/llvm/lib/Transforms/LLVMBuild.txt +++ b/llvm/lib/Transforms/LLVMBuild.txt @@ -16,7 +16,7 @@ ;===------------------------------------------------------------------------===; [common] -subdirectories = IPO InstCombine Instrumentation Scalar Utils Vectorize ObjCARC +subdirectories = Coroutines IPO InstCombine Instrumentation Scalar Utils Vectorize ObjCARC [component_0] type = Group |