Skip to content

Commit

Permalink
[OpenMP] Introduce the OpenMPOpt transformation pass
Browse files Browse the repository at this point in the history
The OpenMPOpt pass is a CGSCC pass in which OpenMP specific
optimizations can reside.

The OpenMPOpt pass uses the OpenMPKinds.def file to identify runtime
calls and their uses. This allows targeted transformations and eases
their implementation.

This initial patch deduplicates `__kmpc_global_thread_num` and
`omp_get_thread_num` calls. We can also identify arguments that are
equivalent to such a call result and use it instead. Later we can
determine "gtid" arguments based on the use in kernel functions etc.

Reviewed By: JonChesterfield

Differential Revision: https://reviews.llvm.org/D69930
  • Loading branch information
jdoerfert committed Feb 8, 2020
1 parent 72277ec commit 9548b74
Show file tree
Hide file tree
Showing 20 changed files with 594 additions and 1 deletion.
2 changes: 2 additions & 0 deletions llvm/include/llvm/Frontend/OpenMP/OMPKinds.def
Expand Up @@ -177,6 +177,8 @@ __OMP_RTL(__kmpc_end_serialized_parallel, false, Void, IdentPtr, Int32)

__OMP_RTL(omp_get_thread_num, false, Int32, )

__OMP_RTL(__last, false, Void, )

#undef __OMP_RTL
#undef OMP_RTL

Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/InitializePasses.h
Expand Up @@ -71,6 +71,7 @@ void initializeAggressiveInstCombinerLegacyPassPass(PassRegistry&);
void initializeAliasSetPrinterPass(PassRegistry&);
void initializeAlignmentFromAssumptionsPass(PassRegistry&);
void initializeAlwaysInlinerLegacyPassPass(PassRegistry&);
void initializeOpenMPOptLegacyPassPass(PassRegistry &);
void initializeArgPromotionPass(PassRegistry&);
void initializeAssumptionCacheTrackerPass(PassRegistry&);
void initializeAtomicExpandPass(PassRegistry&);
Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/LinkAllPasses.h
Expand Up @@ -71,6 +71,7 @@ namespace {
(void) llvm::createAggressiveDCEPass();
(void) llvm::createAggressiveInstCombinerPass();
(void) llvm::createBitTrackingDCEPass();
(void) llvm::createOpenMPOptLegacyPass();
(void) llvm::createArgumentPromotionPass();
(void) llvm::createAlignmentFromAssumptionsPass();
(void) llvm::createBasicAAWrapperPass();
Expand Down
4 changes: 4 additions & 0 deletions llvm/include/llvm/Transforms/IPO.h
Expand Up @@ -152,6 +152,10 @@ ModulePass *createDeadArgHackingPass();
///
Pass *createArgumentPromotionPass(unsigned maxElements = 3);

//===----------------------------------------------------------------------===//
/// createOpenMPOptLegacyPass - OpenMP specific optimizations.
Pass *createOpenMPOptLegacyPass();

//===----------------------------------------------------------------------===//
/// createIPConstantPropagationPass - This pass propagates constants from call
/// sites into the bodies of functions.
Expand Down
54 changes: 54 additions & 0 deletions llvm/include/llvm/Transforms/IPO/OpenMPOpt.h
@@ -0,0 +1,54 @@
//===- IPO/OpenMPOpt.h - Collection of OpenMP optimizations -----*- 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_IPO_OPENMP_OPT_H
#define LLVM_TRANSFORMS_IPO_OPENMP_OPT_H

#include "llvm/Analysis/CGSCCPassManager.h"
#include "llvm/Analysis/LazyCallGraph.h"
#include "llvm/IR/PassManager.h"

namespace llvm {

namespace omp {

/// Helper to remember if the module contains OpenMP (runtime calls), to be used
/// foremost with containsOpenMP.
struct OpenMPInModule {
OpenMPInModule &operator=(bool Found) {
if (Found)
Value = OpenMPInModule::OpenMP::FOUND;
else
Value = OpenMPInModule::OpenMP::NOT_FOUND;
return *this;
}
bool isKnown() { return Value != OpenMP::UNKNOWN; }
operator bool() { return Value != OpenMP::NOT_FOUND; }

private:
enum class OpenMP { FOUND, NOT_FOUND, UNKNOWN } Value = OpenMP::UNKNOWN;
};

/// Helper to determine if \p M contains OpenMP (runtime calls).
bool containsOpenMP(Module &M, OpenMPInModule &OMPInModule);

} // namespace omp

/// OpenMP optimizations pass.
class OpenMPOptPass : public PassInfoMixin<OpenMPOptPass> {
/// Helper to remember if the module contains OpenMP (runtime calls).
omp::OpenMPInModule OMPInModule;

public:
PreservedAnalyses run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
LazyCallGraph &CG, CGSCCUpdateResult &UR);
};

} // end namespace llvm

#endif // LLVM_TRANSFORMS_IPO_OPENMP_OPT_H
1 change: 1 addition & 0 deletions llvm/lib/LTO/LTOCodeGenerator.cpp
Expand Up @@ -134,6 +134,7 @@ void LTOCodeGenerator::initializeLTOPasses() {
initializeSimpleInlinerPass(R);
initializePruneEHPass(R);
initializeGlobalDCELegacyPassPass(R);
initializeOpenMPOptLegacyPassPass(R);
initializeArgPromotionPass(R);
initializeJumpThreadingPass(R);
initializeSROALegacyPassPass(R);
Expand Down
6 changes: 6 additions & 0 deletions llvm/lib/Passes/PassBuilder.cpp
Expand Up @@ -87,6 +87,7 @@
#include "llvm/Transforms/IPO/Internalize.h"
#include "llvm/Transforms/IPO/LowerTypeTests.h"
#include "llvm/Transforms/IPO/MergeFunctions.h"
#include "llvm/Transforms/IPO/OpenMPOpt.h"
#include "llvm/Transforms/IPO/PartialInlining.h"
#include "llvm/Transforms/IPO/SCCP.h"
#include "llvm/Transforms/IPO/SampleProfile.h"
Expand Down Expand Up @@ -837,6 +838,11 @@ PassBuilder::buildModuleSimplificationPipeline(OptimizationLevel Level,
if (Level == OptimizationLevel::O3)
MainCGPipeline.addPass(ArgumentPromotionPass());

// Try to perform OpenMP specific optimizations. This is a (quick!) no-op if
// there are no OpenMP runtime calls present in the module.
if (Level == OptimizationLevel::O2 || Level == OptimizationLevel::O3)
MainCGPipeline.addPass(OpenMPOptPass());

// Lastly, add the core function simplification pipeline nested inside the
// CGSCC walk.
MainCGPipeline.addPass(createCGSCCToFunctionPassAdaptor(
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Passes/PassRegistry.def
Expand Up @@ -109,6 +109,7 @@ CGSCC_PASS("argpromotion", ArgumentPromotionPass())
CGSCC_PASS("invalidate<all>", InvalidateAllAnalysesPass())
CGSCC_PASS("function-attrs", PostOrderFunctionAttrsPass())
CGSCC_PASS("inline", InlinerPass())
CGSCC_PASS("openmpopt", OpenMPOptPass())
CGSCC_PASS("no-op-cgscc", NoOpCGSCCPass())
#undef CGSCC_PASS

Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Transforms/IPO/CMakeLists.txt
Expand Up @@ -26,6 +26,7 @@ add_llvm_component_library(LLVMipo
LoopExtractor.cpp
LowerTypeTests.cpp
MergeFunctions.cpp
OpenMPOpt.cpp
PartialInlining.cpp
PassManagerBuilder.cpp
PruneEH.cpp
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Transforms/IPO/IPO.cpp
Expand Up @@ -23,6 +23,7 @@
using namespace llvm;

void llvm::initializeIPO(PassRegistry &Registry) {
initializeOpenMPOptLegacyPassPass(Registry);
initializeArgPromotionPass(Registry);
initializeCalledValuePropagationLegacyPassPass(Registry);
initializeConstantMergeLegacyPassPass(Registry);
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Transforms/IPO/LLVMBuild.txt
Expand Up @@ -19,4 +19,4 @@ type = Library
name = IPO
parent = Transforms
library_name = ipo
required_libraries = AggressiveInstCombine Analysis BitReader BitWriter Core InstCombine IRReader Linker Object ProfileData Scalar Support TransformUtils Vectorize Instrumentation
required_libraries = AggressiveInstCombine Analysis BitReader BitWriter Core FrontendOpenMP InstCombine IRReader Linker Object ProfileData Scalar Support TransformUtils Vectorize Instrumentation

0 comments on commit 9548b74

Please sign in to comment.