[polly] 5aafcb2 - [Polly] Add support for -polly-position=early with the NPM.
Michael Kruse via llvm-commits
llvm-commits at lists.llvm.org
Fri May 14 10:56:26 PDT 2021
Author: Michael Kruse
Date: 2021-05-14T12:55:03-05:00
New Revision: 5aafcb2b440fb71a026e9c74101f272caecf08b0
URL: https://github.com/llvm/llvm-project/commit/5aafcb2b440fb71a026e9c74101f272caecf08b0
DIFF: https://github.com/llvm/llvm-project/commit/5aafcb2b440fb71a026e9c74101f272caecf08b0.diff
LOG: [Polly] Add support for -polly-position=early with the NPM.
This required support for the canonicalization passes, inlcuding
porting RewriteByReferenceParams to the NPM.
For some reason, the legacy pass pipeline with -polly-position=early did
not run the CodePreparation pass. This was fixed as well.
Added:
polly/include/polly/RewriteByReferenceParameters.h
polly/test/Support/pipelineposition.ll
Modified:
polly/include/polly/Canonicalization.h
polly/include/polly/LinkAllPasses.h
polly/lib/Support/RegisterPasses.cpp
polly/lib/Transform/Canonicalization.cpp
polly/lib/Transform/RewriteByReferenceParameters.cpp
Removed:
################################################################################
diff --git a/polly/include/polly/Canonicalization.h b/polly/include/polly/Canonicalization.h
index 763f2df629a03..988c738bc8cd8 100644
--- a/polly/include/polly/Canonicalization.h
+++ b/polly/include/polly/Canonicalization.h
@@ -9,6 +9,8 @@
#ifndef POLLY_CANONICALIZATION_H
#define POLLY_CANONICALIZATION_H
+#include "llvm/Passes/PassBuilder.h"
+
namespace llvm {
namespace legacy {
class PassManagerBase;
@@ -25,6 +27,11 @@ namespace polly {
/// of Polly. The set of optimization passes scheduled here is probably not yet
/// optimal. TODO: Optimize the set of canonicalization passes.
void registerCanonicalicationPasses(llvm::legacy::PassManagerBase &PM);
+
+llvm::FunctionPassManager
+buildCanonicalicationPassesForNPM(llvm::ModulePassManager &MPM,
+ llvm::PassBuilder::OptimizationLevel Level);
+
} // namespace polly
#endif
diff --git a/polly/include/polly/LinkAllPasses.h b/polly/include/polly/LinkAllPasses.h
index 1d1e455c299b8..78843690a3dad 100644
--- a/polly/include/polly/LinkAllPasses.h
+++ b/polly/include/polly/LinkAllPasses.h
@@ -42,7 +42,7 @@ llvm::Pass *createPolyhedralInfoPass();
llvm::Pass *createScopDetectionWrapperPassPass();
llvm::Pass *createScopInfoRegionPassPass();
llvm::Pass *createScopInfoWrapperPassPass();
-llvm::Pass *createRewriteByrefParamsPass();
+llvm::Pass *createRewriteByrefParamsWrapperPass();
llvm::Pass *createIslAstInfoWrapperPassPass();
llvm::Pass *createCodeGenerationPass();
#ifdef GPU_CODEGEN
@@ -87,6 +87,7 @@ struct PollyForcePassLinking {
polly::createScopInfoRegionPassPass();
polly::createPollyCanonicalizePass();
polly::createPolyhedralInfoPass();
+ polly::createRewriteByrefParamsWrapperPass();
polly::createIslAstInfoWrapperPassPass();
polly::createCodeGenerationPass();
#ifdef GPU_CODEGEN
@@ -114,7 +115,7 @@ void initializeJSONExporterPass(llvm::PassRegistry &);
void initializeJSONImporterPass(llvm::PassRegistry &);
void initializeIslAstInfoWrapperPassPass(llvm::PassRegistry &);
void initializeCodeGenerationPass(llvm::PassRegistry &);
-void initializeRewriteByrefParamsPass(llvm::PassRegistry &);
+void initializeRewriteByrefParamsWrapperPassPass(llvm::PassRegistry &);
#ifdef GPU_CODEGEN
void initializePPCGCodeGenerationPass(llvm::PassRegistry &);
void initializeManagedMemoryRewritePassPass(llvm::PassRegistry &);
diff --git a/polly/include/polly/RewriteByReferenceParameters.h b/polly/include/polly/RewriteByReferenceParameters.h
new file mode 100644
index 0000000000000..5ed5fdca2a095
--- /dev/null
+++ b/polly/include/polly/RewriteByReferenceParameters.h
@@ -0,0 +1,38 @@
+//===- RewriteByReferenceParameters.h -------------------------------------===//
+//
+// 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 POLLY_REWRITEBYREFERENCEPARAMETERS_H
+#define POLLY_REWRITEBYREFERENCEPARAMETERS_H
+
+#include "polly/ScopPass.h"
+
+namespace llvm {
+class PassRegistry;
+class Pass;
+class raw_ostream;
+} // namespace llvm
+
+namespace polly {
+llvm::Pass *createRewriteByrefParamsWrapperPass();
+
+struct RewriteByrefParamsPass : llvm::PassInfoMixin<RewriteByrefParamsPass> {
+ RewriteByrefParamsPass() {}
+
+ llvm::PreservedAnalyses run(llvm::Function &F,
+ llvm::FunctionAnalysisManager &FAM);
+};
+
+} // namespace polly
+
+namespace llvm {
+void initializeRewriteByrefParamsWrapperPassPass(llvm::PassRegistry &);
+} // namespace llvm
+
+#endif /* POLLY_REWRITEBYREFERENCEPARAMETERS_H */
diff --git a/polly/lib/Support/RegisterPasses.cpp b/polly/lib/Support/RegisterPasses.cpp
index 1c8703f165217..d8fe5efdd9f35 100644
--- a/polly/lib/Support/RegisterPasses.cpp
+++ b/polly/lib/Support/RegisterPasses.cpp
@@ -263,7 +263,7 @@ void initializePollyPasses(PassRegistry &Registry) {
initializeScopInlinerPass(Registry);
initializeScopInfoRegionPassPass(Registry);
initializeScopInfoWrapperPassPass(Registry);
- initializeRewriteByrefParamsPass(Registry);
+ initializeRewriteByrefParamsWrapperPassPass(Registry);
initializeCodegenCleanupPass(Registry);
initializeFlattenSchedulePass(Registry);
initializeForwardOpTreeWrapperPassPass(Registry);
@@ -429,6 +429,7 @@ registerPollyEarlyAsPossiblePasses(const llvm::PassManagerBuilder &Builder,
return;
registerCanonicalicationPasses(PM);
+ PM.add(polly::createCodePreparationPass());
registerPollyPasses(PM, EnableForOpt);
}
@@ -466,13 +467,17 @@ registerPollyScalarOptimizerLatePasses(const llvm::PassManagerBuilder &Builder,
PM.add(createCodegenCleanupPass());
}
-static void buildDefaultPollyPipeline(FunctionPassManager &PM,
- PassBuilder::OptimizationLevel Level) {
- bool EnableForOpt =
- shouldEnablePollyForOptimization() && Level.isOptimizingForSpeed();
- if (!shouldEnablePollyForDiagnostic() && !EnableForOpt)
- return;
-
+/// Add the pass sequence required for Polly to the New Pass Manager.
+///
+/// @param PM The pass manager itself.
+/// @param Level The optimization level. Used for the cleanup of Polly's
+/// output.
+/// @param EnableForOpt Whether to add Polly IR transformations. If False, only
+/// the analysis passes are added, skipping Polly itself.
+/// The IR may still be modified.
+static void buildCommonPollyPipeline(FunctionPassManager &PM,
+ PassBuilder::OptimizationLevel Level,
+ bool EnableForOpt) {
PassBuilder PB;
ScopPassManager SPM;
@@ -583,6 +588,43 @@ static void buildDefaultPollyPipeline(FunctionPassManager &PM,
PM.addPass(llvm::CFGPrinterPass());
}
+static void buildEarlyPollyPipeline(ModulePassManager &MPM,
+ PassBuilder::OptimizationLevel Level) {
+ bool EnableForOpt =
+ shouldEnablePollyForOptimization() && Level.isOptimizingForSpeed();
+ if (!shouldEnablePollyForDiagnostic() && !EnableForOpt)
+ return;
+
+ FunctionPassManager FPM = buildCanonicalicationPassesForNPM(MPM, Level);
+
+ if (DumpBefore)
+ report_fatal_error("Option -polly-dump-before not supported with NPM",
+ false);
+ if (!DumpBeforeFile.empty())
+ report_fatal_error("Option -polly-dump-before-file not supported with NPM",
+ false);
+
+ buildCommonPollyPipeline(FPM, Level, EnableForOpt);
+ MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
+}
+
+static void buildLatePollyPipeline(FunctionPassManager &PM,
+ PassBuilder::OptimizationLevel Level) {
+ bool EnableForOpt =
+ shouldEnablePollyForOptimization() && Level.isOptimizingForSpeed();
+ if (!shouldEnablePollyForDiagnostic() && !EnableForOpt)
+ return;
+
+ if (DumpBefore)
+ report_fatal_error("Option -polly-dump-before not supported with NPM",
+ false);
+ if (!DumpBeforeFile.empty())
+ report_fatal_error("Option -polly-dump-before-file not supported with NPM",
+ false);
+
+ buildCommonPollyPipeline(PM, Level, EnableForOpt);
+}
+
/// Register Polly to be available as an optimizer
///
///
@@ -776,9 +818,20 @@ void registerPollyPasses(PassBuilder &PB) {
return parseTopLevelPipeline(MPM, PIC, Pipeline);
});
- if (PassPosition != POSITION_BEFORE_VECTORIZER)
- report_fatal_error("Option -polly-position not supported with NPM", false);
- PB.registerVectorizerStartEPCallback(buildDefaultPollyPipeline);
+ switch (PassPosition) {
+ case POSITION_EARLY:
+ PB.registerPipelineStartEPCallback(buildEarlyPollyPipeline);
+ break;
+ case POSITION_AFTER_LOOPOPT:
+ report_fatal_error(
+ "Option -polly-position=after-loopopt not supported with NPM", false);
+ break;
+ case POSITION_BEFORE_VECTORIZER:
+ PB.registerVectorizerStartEPCallback(buildLatePollyPipeline);
+ break;
+ default:
+ llvm_unreachable("Unknown -polly-position option");
+ }
}
} // namespace polly
diff --git a/polly/lib/Transform/Canonicalization.cpp b/polly/lib/Transform/Canonicalization.cpp
index 3b19ecaff06db..6b79707edf9c2 100644
--- a/polly/lib/Transform/Canonicalization.cpp
+++ b/polly/lib/Transform/Canonicalization.cpp
@@ -15,11 +15,22 @@
#include "polly/Canonicalization.h"
#include "polly/LinkAllPasses.h"
#include "polly/Options.h"
+#include "polly/RewriteByReferenceParameters.h"
+#include "llvm/Analysis/GlobalsModRef.h"
+#include "llvm/Analysis/ProfileSummaryInfo.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/Transforms/IPO.h"
+#include "llvm/Transforms/IPO/FunctionAttrs.h"
#include "llvm/Transforms/InstCombine/InstCombine.h"
#include "llvm/Transforms/Scalar.h"
+#include "llvm/Transforms/Scalar/EarlyCSE.h"
+#include "llvm/Transforms/Scalar/IndVarSimplify.h"
+#include "llvm/Transforms/Scalar/LoopRotation.h"
+#include "llvm/Transforms/Scalar/Reassociate.h"
+#include "llvm/Transforms/Scalar/SimplifyCFG.h"
+#include "llvm/Transforms/Scalar/TailRecursionElimination.h"
#include "llvm/Transforms/Utils.h"
+#include "llvm/Transforms/Utils/Mem2Reg.h"
using namespace llvm;
using namespace polly;
@@ -31,7 +42,7 @@ static cl::opt<bool>
void polly::registerCanonicalicationPasses(llvm::legacy::PassManagerBase &PM) {
bool UseMemSSA = true;
- PM.add(polly::createRewriteByrefParamsPass());
+ PM.add(polly::createRewriteByrefParamsWrapperPass());
PM.add(llvm::createPromoteMemoryToRegisterPass());
PM.add(llvm::createEarlyCSEPass(UseMemSSA));
PM.add(llvm::createInstructionCombiningPass());
@@ -49,7 +60,77 @@ void polly::registerCanonicalicationPasses(llvm::legacy::PassManagerBase &PM) {
}
PM.add(llvm::createInstructionCombiningPass());
PM.add(llvm::createIndVarSimplifyPass());
- PM.add(polly::createCodePreparationPass());
+}
+
+/// Adapted from llvm::PassBuilder::buildInlinerPipeline
+static ModuleInlinerWrapperPass
+buildInlinePasses(llvm::PassBuilder::OptimizationLevel Level) {
+ InlineParams IP = getInlineParams(200);
+ ModuleInlinerWrapperPass MIWP(IP);
+
+ // Require the GlobalsAA analysis for the module so we can query it within
+ // the CGSCC pipeline.
+ MIWP.addModulePass(RequireAnalysisPass<GlobalsAA, Module>());
+ // Invalidate AAManager so it can be recreated and pick up the newly available
+ // GlobalsAA.
+ MIWP.addModulePass(
+ createModuleToFunctionPassAdaptor(InvalidateAnalysisPass<AAManager>()));
+
+ // Require the ProfileSummaryAnalysis for the module so we can query it within
+ // the inliner pass.
+ MIWP.addModulePass(RequireAnalysisPass<ProfileSummaryAnalysis, Module>());
+
+ // Now begin the main postorder CGSCC pipeline.
+ // FIXME: The current CGSCC pipeline has its origins in the legacy pass
+ // manager and trying to emulate its precise behavior. Much of this doesn't
+ // make a lot of sense and we should revisit the core CGSCC structure.
+ CGSCCPassManager &MainCGPipeline = MIWP.getPM();
+
+ // Now deduce any function attributes based in the current code.
+ MainCGPipeline.addPass(PostOrderFunctionAttrsPass());
+
+ return MIWP;
+}
+
+FunctionPassManager polly::buildCanonicalicationPassesForNPM(
+ llvm::ModulePassManager &MPM, llvm::PassBuilder::OptimizationLevel Level) {
+ FunctionPassManager FPM;
+
+ bool UseMemSSA = true;
+ FPM.addPass(RewriteByrefParamsPass());
+ FPM.addPass(PromotePass());
+ FPM.addPass(EarlyCSEPass(UseMemSSA));
+ FPM.addPass(InstCombinePass());
+ FPM.addPass(SimplifyCFGPass());
+ FPM.addPass(TailCallElimPass());
+ FPM.addPass(SimplifyCFGPass());
+ FPM.addPass(ReassociatePass());
+ {
+ LoopPassManager LPM;
+ LPM.addPass(LoopRotatePass(Level != PassBuilder::OptimizationLevel::Oz));
+ FPM.addPass(createFunctionToLoopPassAdaptor<LoopPassManager>(
+ std::move(LPM), /*UseMemorySSA=*/false,
+ /*UseBlockFrequencyInfo=*/false));
+ }
+ if (PollyInliner) {
+ MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
+ MPM.addPass(buildInlinePasses(Level));
+ FPM = FunctionPassManager();
+
+ FPM.addPass(PromotePass());
+ FPM.addPass(SimplifyCFGPass());
+ FPM.addPass(InstCombinePass());
+ }
+ FPM.addPass(InstCombinePass());
+ {
+ LoopPassManager LPM;
+ LPM.addPass(IndVarSimplifyPass());
+ FPM.addPass(createFunctionToLoopPassAdaptor<LoopPassManager>(
+ std::move(LPM), /*UseMemorySSA=*/false,
+ /*UseBlockFrequencyInfo=*/true));
+ }
+
+ return FPM;
}
namespace {
diff --git a/polly/lib/Transform/RewriteByReferenceParameters.cpp b/polly/lib/Transform/RewriteByReferenceParameters.cpp
index 88ef395379f7b..2cf4764cd6217 100644
--- a/polly/lib/Transform/RewriteByReferenceParameters.cpp
+++ b/polly/lib/Transform/RewriteByReferenceParameters.cpp
@@ -13,6 +13,7 @@
//
//===----------------------------------------------------------------------===//
+#include "polly/RewriteByReferenceParameters.h"
#include "polly/LinkAllPasses.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
@@ -23,76 +24,89 @@
using namespace llvm;
namespace {
+static void tryRewriteInstruction(Instruction &Inst) {
+ BasicBlock *Entry = &Inst.getParent()->getParent()->getEntryBlock();
-class RewriteByrefParams : public FunctionPass {
-private:
- RewriteByrefParams(const RewriteByrefParams &) = delete;
- const RewriteByrefParams &operator=(const RewriteByrefParams &) = delete;
+ auto *Call = dyn_cast<CallInst>(&Inst);
-public:
- static char ID;
- explicit RewriteByrefParams() : FunctionPass(ID) {}
+ if (!Call)
+ return;
- virtual void getAnalysisUsage(AnalysisUsage &AU) const override {}
+ llvm::Function *F = Call->getCalledFunction();
- void tryRewriteInstruction(Instruction &Inst) {
- BasicBlock *Entry = &Inst.getParent()->getParent()->getEntryBlock();
+ if (!F)
+ return;
- auto *Call = dyn_cast<CallInst>(&Inst);
+ // We currently match for a very specific function. In case this proves
+ // useful, we can make this code dependent on readonly metadata.
+ if (!F->hasName() || F->getName() != "_gfortran_transfer_integer_write")
+ return;
- if (!Call)
- return;
+ auto *BitCast = dyn_cast<BitCastInst>(Call->getOperand(1));
- llvm::Function *F = Call->getCalledFunction();
+ if (!BitCast)
+ return;
- if (!F)
- return;
+ auto *Alloca = dyn_cast<AllocaInst>(BitCast->getOperand(0));
- // We currently match for a very specific function. In case this proves
- // useful, we can make this code dependent on readonly metadata.
- if (!F->hasName() || F->getName() != "_gfortran_transfer_integer_write")
- return;
+ if (!Alloca)
+ return;
- auto *BitCast = dyn_cast<BitCastInst>(Call->getOperand(1));
+ std::string InstName = Alloca->getName().str();
- if (!BitCast)
- return;
+ auto NewAlloca =
+ new AllocaInst(Alloca->getAllocatedType(), 0,
+ "polly_byref_alloca_" + InstName, &*Entry->begin());
- auto *Alloca = dyn_cast<AllocaInst>(BitCast->getOperand(0));
+ auto *LoadedVal = new LoadInst(Alloca->getAllocatedType(), Alloca,
+ "polly_byref_load_" + InstName, &Inst);
- if (!Alloca)
- return;
+ new StoreInst(LoadedVal, NewAlloca, &Inst);
+ auto *NewBitCast = new BitCastInst(NewAlloca, BitCast->getType(),
+ "polly_byref_cast_" + InstName, &Inst);
+ Call->setOperand(1, NewBitCast);
+}
- std::string InstName = Alloca->getName().str();
+static void runRewriteByrefParams(Function &F) {
+ for (BasicBlock &BB : F)
+ for (Instruction &Inst : BB)
+ tryRewriteInstruction(Inst);
+}
- auto NewAlloca =
- new AllocaInst(Alloca->getAllocatedType(), 0,
- "polly_byref_alloca_" + InstName, &*Entry->begin());
+class RewriteByrefParamsWrapperPass : public FunctionPass {
+private:
+ RewriteByrefParamsWrapperPass(const RewriteByrefParamsWrapperPass &) = delete;
+ const RewriteByrefParamsWrapperPass &
+ operator=(const RewriteByrefParamsWrapperPass &) = delete;
- auto *LoadedVal = new LoadInst(Alloca->getAllocatedType(), Alloca,
- "polly_byref_load_" + InstName, &Inst);
+public:
+ static char ID;
+ explicit RewriteByrefParamsWrapperPass() : FunctionPass(ID) {}
- new StoreInst(LoadedVal, NewAlloca, &Inst);
- auto *NewBitCast = new BitCastInst(NewAlloca, BitCast->getType(),
- "polly_byref_cast_" + InstName, &Inst);
- Call->setOperand(1, NewBitCast);
- }
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const override {}
virtual bool runOnFunction(Function &F) override {
- for (BasicBlock &BB : F)
- for (Instruction &Inst : BB)
- tryRewriteInstruction(Inst);
-
+ runRewriteByrefParams(F);
return true;
}
};
-char RewriteByrefParams::ID;
+char RewriteByrefParamsWrapperPass::ID;
} // anonymous namespace
-Pass *polly::createRewriteByrefParamsPass() { return new RewriteByrefParams(); }
+Pass *polly::createRewriteByrefParamsWrapperPass() {
+ return new RewriteByrefParamsWrapperPass();
+}
+
+llvm::PreservedAnalyses
+polly ::RewriteByrefParamsPass::run(llvm::Function &F,
+ llvm::FunctionAnalysisManager &FAM) {
+ runRewriteByrefParams(F);
+ return PreservedAnalyses::none();
+}
-INITIALIZE_PASS_BEGIN(RewriteByrefParams, "polly-rewrite-byref-params",
+INITIALIZE_PASS_BEGIN(RewriteByrefParamsWrapperPass,
+ "polly-rewrite-byref-params",
"Polly - Rewrite by reference parameters", false, false)
-INITIALIZE_PASS_END(RewriteByrefParams, "polly-rewrite-byref-params",
+INITIALIZE_PASS_END(RewriteByrefParamsWrapperPass, "polly-rewrite-byref-params",
"Polly - Rewrite by reference parameters", false, false)
diff --git a/polly/test/Support/pipelineposition.ll b/polly/test/Support/pipelineposition.ll
new file mode 100644
index 0000000000000..fc2e5bb9325a8
--- /dev/null
+++ b/polly/test/Support/pipelineposition.ll
@@ -0,0 +1,91 @@
+; Legacy pass manager
+; RUN: opt %loadPolly -O3 -enable-new-pm=0 -polly -polly-position=early -disable-output -debug-only=polly-scops < %s 2>&1 | FileCheck %s --check-prefix=NOINLINE
+; RUN: opt %loadPolly -O3 -enable-new-pm=0 -polly -polly-position=early -polly-run-inliner -disable-output -debug-only=polly-scops < %s 2>&1 | FileCheck %s --check-prefix=INLINED1
+; RUN: opt %loadPolly -O3 -enable-new-pm=0 -polly -polly-position=after-loopopt -disable-output -debug-only=polly-scops < %s 2>&1 | FileCheck %s --check-prefix=INLINED2
+; RUN: opt %loadPolly -O3 -enable-new-pm=0 -polly -polly-position=before-vectorizer -disable-output -debug-only=polly-scops < %s 2>&1 | FileCheck %s --check-prefix=INLINED3
+;
+; New pass manager
+; RUN: opt %loadPolly -O3 -enable-new-pm=1 -polly -polly-position=early -disable-output -debug-only=polly-scops < %s 2>&1 | FileCheck %s --check-prefix=NOINLINE
+; RUN: opt %loadPolly -O3 -enable-new-pm=1 -polly -polly-position=early -polly-run-inliner -disable-output -debug-only=polly-scops < %s 2>&1 | FileCheck %s --check-prefix=INLINED1
+; RUN: opt %loadPolly -O3 -enable-new-pm=1 -polly -polly-position=before-vectorizer -disable-output -debug-only=polly-scops < %s 2>&1 | FileCheck %s --check-prefix=INLINED3
+;
+; REQUIRES: asserts
+;
+; void callee(int n, double A[], int i) {
+; for (int j = 0; j < n; j += 1)
+; A[i+j] = 42.0;
+; }
+;
+; void caller(int n, double A[]) {
+; for (int i = 0; i < n; i += 1)
+; callee(n, A, i);
+; }
+
+
+define internal void @callee(i32 %n, double* noalias nonnull %A, i32 %i) {
+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:
+ %idx = add i32 %i, %j
+ %arrayidx = getelementptr inbounds double, double* %A, i32 %idx
+ store double 42.0, double* %arrayidx
+ br label %inc
+
+inc:
+ %j.inc = add nuw nsw i32 %j, 1
+ br label %for
+
+exit:
+ br label %return
+
+return:
+ ret void
+}
+
+
+define void @caller(i32 %n, double* noalias nonnull %A) {
+entry:
+ br label %for
+
+for:
+ %i = phi i32 [0, %entry], [%j.inc, %inc]
+ %i.cmp = icmp slt i32 %i, %n
+ br i1 %i.cmp, label %body, label %exit
+
+ body:
+ call void @callee(i32 %n, double* %A, i32 %i)
+ br label %inc
+
+inc:
+ %j.inc = add nuw nsw i32 %i, 1
+ br label %for
+
+exit:
+ br label %return
+
+return:
+ ret void
+}
+
+
+; NOINLINE-LABEL: Function: callee
+; NOINLINE: Schedule :=
+; NOINLINE-NEXT: [n, i] -> { Stmt_body[i0] -> [i0] };
+
+; INLINED1-LABEL: Function: caller
+; INLINED1: Schedule :=
+; INLINED1-NEXT: [n] -> { Stmt_body_i[i0, i1] -> [i0, i1] };
+
+; INLINED2-LABEL: Function: caller
+; INLINED2: Schedule :=
+; INLINED2-NEXT: [n] -> { Stmt_polly_loop_header_i_us_us[i0, i1] -> [i0, 1, i1] };
+
+; INLINED3-LABEL: Function: caller
+; INLINED3: Schedule :=
+; INLINED3-NEXT: [n] -> { Stmt_body_i_us[i0, i1] -> [i0, i1] };
More information about the llvm-commits
mailing list