From 36e79ecaec8e95674c30256111ca8c5376e7d3ba Mon Sep 17 00:00:00 2001 From: Michael Kruse Date: Tue, 29 Nov 2016 16:41:21 +0000 Subject: [PATCH] [DeLICM] Add pass boilerplate code. Add an empty DeLICM pass, without any functional parts. Extracting the boilerplate from the the functional part reduces the size of the code to review (https://reviews.llvm.org/D24716) Suggested-by: Tobias Grosser llvm-svn: 288160 --- polly/include/polly/DeLICM.h | 35 ++++++++++++++ polly/include/polly/LinkAllPasses.h | 3 ++ polly/lib/CMakeLists.txt | 1 + polly/lib/Support/RegisterPasses.cpp | 10 ++++ polly/lib/Transform/DeLICM.cpp | 70 ++++++++++++++++++++++++++++ polly/test/DeLICM/pass_existance.ll | 36 ++++++++++++++ 6 files changed, 155 insertions(+) create mode 100644 polly/include/polly/DeLICM.h create mode 100644 polly/lib/Transform/DeLICM.cpp create mode 100644 polly/test/DeLICM/pass_existance.ll diff --git a/polly/include/polly/DeLICM.h b/polly/include/polly/DeLICM.h new file mode 100644 index 000000000000..e7fe4c2d5574 --- /dev/null +++ b/polly/include/polly/DeLICM.h @@ -0,0 +1,35 @@ +//===------ DeLICM.h --------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Undo the effect of Loop Invariant Code Motion (LICM) and +// GVN Partial Redundancy Elimination (PRE) on SCoP-level. +// +// Namely, remove register/scalar dependencies by mapping them back to array +// elements. +// +//===----------------------------------------------------------------------===// + +#ifndef POLLY_DELICM_H +#define POLLY_DELICM_H + +namespace llvm { +class PassRegistry; +class Pass; +} // anonymous namespace + +namespace polly { +/// Create a new DeLICM pass instance. +llvm::Pass *createDeLICMPass(); +} // namespace polly + +namespace llvm { +void initializeDeLICMPass(llvm::PassRegistry &); +} // namespace llvm + +#endif /* POLLY_DELICM_H */ diff --git a/polly/include/polly/LinkAllPasses.h b/polly/include/polly/LinkAllPasses.h index ff6f5960caca..6f0dd1ca0553 100644 --- a/polly/include/polly/LinkAllPasses.h +++ b/polly/include/polly/LinkAllPasses.h @@ -48,6 +48,7 @@ llvm::Pass *createPPCGCodeGenerationPass(); #endif llvm::Pass *createIslScheduleOptimizerPass(); llvm::Pass *createFlattenSchedulePass(); +llvm::Pass *createDeLICMPass(); extern char &CodePreparationID; } // namespace polly @@ -82,6 +83,7 @@ struct PollyForcePassLinking { #endif polly::createIslScheduleOptimizerPass(); polly::createFlattenSchedulePass(); + polly::createDeLICMPass(); } } PollyForcePassLinking; // Force link by creating a global definition. } // namespace @@ -100,6 +102,7 @@ void initializePPCGCodeGenerationPass(llvm::PassRegistry &); void initializeIslScheduleOptimizerPass(llvm::PassRegistry &); void initializePollyCanonicalizePass(llvm::PassRegistry &); void initializeFlattenSchedulePass(llvm::PassRegistry &); +void initializeDeLICMPass(llvm::PassRegistry &); } // namespace llvm #endif diff --git a/polly/lib/CMakeLists.txt b/polly/lib/CMakeLists.txt index 4d132392e526..c4ae26f9f44d 100644 --- a/polly/lib/CMakeLists.txt +++ b/polly/lib/CMakeLists.txt @@ -57,6 +57,7 @@ add_polly_library(Polly Transform/ScheduleOptimizer.cpp Transform/FlattenSchedule.cpp Transform/FlattenAlgo.cpp + Transform/DeLICM.cpp ${POLLY_HEADER_FILES} ) diff --git a/polly/lib/Support/RegisterPasses.cpp b/polly/lib/Support/RegisterPasses.cpp index a154ec97aab8..949328962f05 100644 --- a/polly/lib/Support/RegisterPasses.cpp +++ b/polly/lib/Support/RegisterPasses.cpp @@ -23,6 +23,7 @@ #include "polly/Canonicalization.h" #include "polly/CodeGen/CodeGeneration.h" #include "polly/CodeGen/CodegenCleanup.h" +#include "polly/DeLICM.h" #include "polly/DependenceInfo.h" #include "polly/FlattenSchedule.h" #include "polly/LinkAllPasses.h" @@ -159,6 +160,11 @@ static cl::opt cl::desc("Enable polyhedral interface of Polly"), cl::Hidden, cl::init(false), cl::cat(PollyCategory)); +static cl::opt + EnableDeLICM("polly-enable-delicm", + cl::desc("Eliminate scalar loop carried dependences"), + cl::Hidden, cl::init(false), cl::cat(PollyCategory)); + namespace polly { void initializePollyPasses(PassRegistry &Registry) { initializeCodeGenerationPass(Registry); @@ -181,6 +187,7 @@ void initializePollyPasses(PassRegistry &Registry) { initializeScopInfoWrapperPassPass(Registry); initializeCodegenCleanupPass(Registry); initializeFlattenSchedulePass(Registry); + initializeDeLICMPass(Registry); } /// Register Polly passes such that they form a polyhedral optimizer. @@ -228,6 +235,9 @@ void registerPollyPasses(llvm::legacy::PassManagerBase &PM) { if (EnablePolyhedralInfo) PM.add(polly::createPolyhedralInfoPass()); + if (EnableDeLICM) + PM.add(polly::createDeLICMPass()); + if (ImportJScop) PM.add(polly::createJSONImporterPass()); diff --git a/polly/lib/Transform/DeLICM.cpp b/polly/lib/Transform/DeLICM.cpp new file mode 100644 index 000000000000..af329fbe0fdc --- /dev/null +++ b/polly/lib/Transform/DeLICM.cpp @@ -0,0 +1,70 @@ +//===------ DeLICM.cpp -----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Undo the effect of Loop Invariant Code Motion (LICM) and +// GVN Partial Redundancy Elimination (PRE) on SCoP-level. +// +// Namely, remove register/scalar dependencies by mapping them back to array +// elements. +// +//===----------------------------------------------------------------------===// + +#include "polly/DeLICM.h" +#include "polly/ScopInfo.h" +#include "polly/ScopPass.h" +#define DEBUG_TYPE "polly-delicm" + +using namespace polly; +using namespace llvm; + +namespace { + +class DeLICM : public ScopPass { +private: + DeLICM(const DeLICM &) = delete; + const DeLICM &operator=(const DeLICM &) = delete; + +public: + static char ID; + explicit DeLICM() : ScopPass(ID) {} + + virtual void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.addRequiredTransitive(); + AU.setPreservesAll(); + } + + virtual bool runOnScop(Scop &S) override { + // Free resources for previous scop's computation, if not yet done. + releaseMemory(); + + // TODO: Run DeLICM algorithm + + return false; + } + + virtual void printScop(raw_ostream &OS, Scop &S) const override { + OS << "DeLICM result:\n"; + // TODO: Print analysis results and performed transformation details + } + + virtual void releaseMemory() override { + // TODO: Release resources (eg. shared_ptr to isl_ctx) + } +}; + +char DeLICM::ID; +} // anonymous namespace + +Pass *polly::createDeLICMPass() { return new DeLICM(); } + +INITIALIZE_PASS_BEGIN(DeLICM, "polly-delicm", "Polly - DeLICM/DePRE", false, + false) +INITIALIZE_PASS_DEPENDENCY(ScopInfoWrapperPass) +INITIALIZE_PASS_END(DeLICM, "polly-delicm", "Polly - DeLICM/DePRE", false, + false) diff --git a/polly/test/DeLICM/pass_existance.ll b/polly/test/DeLICM/pass_existance.ll new file mode 100644 index 000000000000..dcec39cce685 --- /dev/null +++ b/polly/test/DeLICM/pass_existance.ll @@ -0,0 +1,36 @@ +; RUN: opt %loadPolly -polly-delicm -analyze < %s | FileCheck %s +; +; Simple test for the existence of the DeLICM pass. +; +; // Simplest detected SCoP to run DeLICM on. +; for (int j = 0; j < n; j += 1) { +; body: A[0] = 0.0; +; } +; +define void @func(i32 %n, double* noalias nonnull %A) { +entry: + br label %for + +for: + %j = phi i32 [0, %entry], [%j.inc, %inc] + %j.cmp = icmp slt i32 %j, %n + br i1 %j.cmp, label %body, label %exit + + body: + store double 0.0, double* %A + br label %inc + +inc: + %j.inc = add nuw nsw i32 %j, 1 + br label %for + +exit: + br label %return + +return: + ret void +} + + +; Verify that the DeLICM has a custom printScop() function. +; CHECK: DeLICM result: