silvas updated this revision to Diff 64420.
silvas added a comment.
Rebase after r275507.
https://reviews.llvm.org/D21954
Files:
include/clang/Driver/CC1Options.td
include/clang/Frontend/CodeGenOptions.h
lib/CodeGen/BackendUtil.cpp
lib/CodeGen/CMakeLists.txt
lib/Frontend/CompilerInvocation.cpp
test/CodeGen/middle-end-passes.c
Index: test/CodeGen/middle-end-passes.c
===================================================================
--- /dev/null
+++ test/CodeGen/middle-end-passes.c
@@ -0,0 +1,26 @@
+// Check that passes get run.
+
+// RUN: %clang_cc1 %s -emit-llvm -o /dev/null -middle-end-passes=mem2reg,aa-eval 2>&1 | FileCheck %s --check-prefix=NO-AA
+
+// NO-AA: ===== Alias Analysis Evaluator Report =====
+// NO-AA: 0 must alias responses
+
+// RUN: %clang_cc1 %s -emit-llvm -o /dev/null -middle-end-passes=mem2reg,aa-eval -middle-end-aa-pipeline=basic-aa 2>&1 | FileCheck %s --check-prefix=WITH-AA
+
+// WITH-AA: ===== Alias Analysis Evaluator Report =====
+// WITH-AA: 1 must alias responses
+
+
+// The actual output with -flto or -emit-llvm is generated by running a
+// pass in the old PM. Verify that that we still get output.
+
+// RUN: %clang -flto -c %s -o - -Xclang -middle-end-passes=mem2reg 2>&1 | opt -S | FileCheck %s --check-prefix=OUTPUT-IS-GENERATED
+// RUN: %clang -emit-llvm -S %s -o - -Xclang -middle-end-passes=mem2reg 2>&1 | FileCheck %s --check-prefix=OUTPUT-IS-GENERATED
+
+// OUTPUT-IS-GENERATED: @foo
+
+int foo(int *x) {
+ int *y = x + 1;
+ int *z = y - 1;
+ return *x + *z;
+}
Index: lib/Frontend/CompilerInvocation.cpp
===================================================================
--- lib/Frontend/CompilerInvocation.cpp
+++ lib/Frontend/CompilerInvocation.cpp
@@ -845,6 +845,11 @@
Opts.EmitCheckPathComponentsToStrip = getLastArgIntValue(
Args, OPT_fsanitize_undefined_strip_path_components_EQ, 0, Diags);
+ if (Arg *A = Args.getLastArg(OPT_middle_end_passes_EQ))
+ Opts.MiddleEndPasses = A->getValue();
+ if (Arg *A = Args.getLastArg(OPT_middle_end_aa_pipeline_EQ))
+ Opts.MiddleEndAAPipeline = A->getValue();
+
return Success;
}
Index: lib/CodeGen/CMakeLists.txt
===================================================================
--- lib/CodeGen/CMakeLists.txt
+++ lib/CodeGen/CMakeLists.txt
@@ -12,6 +12,7 @@
MC
ObjCARCOpts
Object
+ Passes
ProfileData
ScalarOpts
Support
Index: lib/CodeGen/BackendUtil.cpp
===================================================================
--- lib/CodeGen/BackendUtil.cpp
+++ lib/CodeGen/BackendUtil.cpp
@@ -31,6 +31,7 @@
#include "llvm/IR/Verifier.h"
#include "llvm/MC/SubtargetFeature.h"
#include "llvm/Object/ModuleSummaryIndexObjectFile.h"
+#include "llvm/Passes/PassBuilder.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/TargetRegistry.h"
@@ -643,6 +644,43 @@
return true;
}
+static void runMiddleEndPasses(Module &M, TargetMachine *TM, StringRef Passes,
+ StringRef AAPipeline) {
+ // This is a really low-level internal developer option.
+ // Use report_fatal_error if anything goes wrong.
+
+ PassBuilder PB(TM);
+ AAManager AA;
+ if (!PB.parseAAPipeline(AA, AAPipeline))
+ report_fatal_error("Unable to parse AA pipeline description: " +
+ AAPipeline);
+
+ LoopAnalysisManager LAM;
+ FunctionAnalysisManager FAM;
+ CGSCCAnalysisManager CGAM;
+ ModuleAnalysisManager MAM;
+
+ // Register the AA manager first so that our version is the one used.
+ FAM.registerPass([&] { return std::move(AA); });
+
+ // Register all the basic analyses with the managers.
+ PB.registerModuleAnalyses(MAM);
+ PB.registerCGSCCAnalyses(CGAM);
+ PB.registerFunctionAnalyses(FAM);
+ PB.registerLoopAnalyses(LAM);
+ PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
+
+ ModulePassManager MPM;
+ MPM.addPass(VerifierPass());
+
+ // Now, add all the passes we've been requested to.
+ if (!PB.parsePassPipeline(MPM, Passes))
+ report_fatal_error("Unable to parse pass pipeline description: " + Passes);
+
+ MPM.addPass(VerifierPass());
+ MPM.run(M, MAM);
+}
+
void EmitAssemblyHelper::EmitAssembly(BackendAction Action,
std::unique_ptr<raw_pwrite_stream> OS) {
TimeRegion Region(llvm::TimePassesIsEnabled ? &CodeGenerationTime : nullptr);
@@ -687,7 +725,11 @@
PerFunctionPasses.add(
createTargetTransformInfoWrapperPass(getTargetIRAnalysis()));
- CreatePasses(PerModulePasses, PerFunctionPasses, ModuleSummary.get());
+ bool UseCustomMiddleEndPasses = !CodeGenOpts.MiddleEndPasses.empty();
+ // If we are going to use a custom middle-end pass pipeline, don't add
+ // any of the usual passes.
+ if (!UseCustomMiddleEndPasses)
+ CreatePasses(PerModulePasses, PerFunctionPasses, ModuleSummary.get());
legacy::PassManager CodeGenPasses;
CodeGenPasses.add(
@@ -716,6 +758,18 @@
// Before executing passes, print the final values of the LLVM options.
cl::PrintOptionValues();
+ if (UseCustomMiddleEndPasses) {
+ // Override the middle-end pass pipeline.
+ // Note that we still run the old PM managers later because they
+ // contain e.g. the passes for printing out a BC or LL file (e.g. for
+ // -flto).
+ // But these passes don't affect the actual optimization because there
+ // is nothing else run in the old PM except for the printing passes.
+
+ runMiddleEndPasses(*TheModule, TM.get(), CodeGenOpts.MiddleEndPasses,
+ CodeGenOpts.MiddleEndAAPipeline);
+ }
+
// Run passes. For now we do all passes at once, but eventually we
// would like to have the option of streaming code generation.
Index: include/clang/Frontend/CodeGenOptions.h
===================================================================
--- include/clang/Frontend/CodeGenOptions.h
+++ include/clang/Frontend/CodeGenOptions.h
@@ -107,6 +107,24 @@
/// Enable additional debugging information.
std::string DebugPass;
+ /// Pass description string to override the middle-end pass pipeline.
+ /// This is primarily for developers experimenting with different
+ /// optimization pipelines.
+ /// This will completely replace the middle-end pass pipeline, so
+ /// features that depend on changes to the pipeline (e.g. sanitizers) may
+ /// not work as expected in conjunction with this option.
+ /// The string has the same format as the string passed to opt's
+ /// `-passes=` flag.
+ std::string MiddleEndPasses;
+
+ /// Alias analysis description string to use with MiddleEndPasses.
+ /// This is primarily for developers experimenting with different
+ /// optimization pipelines.
+ /// This option only affects passes run by MiddleEndPasses.
+ /// The string has the same format as the string passed to opt's
+ /// `-aa-pipeline=` flag.
+ std::string MiddleEndAAPipeline;
+
/// The string to embed in debug information as the current working directory.
std::string DebugCompilationDir;
Index: include/clang/Driver/CC1Options.td
===================================================================
--- include/clang/Driver/CC1Options.td
+++ include/clang/Driver/CC1Options.td
@@ -157,6 +157,13 @@
HelpText<"Disable implicit builtin knowledge of math functions">;
}
+def middle_end_passes_EQ
+ : Joined<[ "-" ], "middle-end-passes=">,
+ HelpText<"Override the middle-end passes that are run">;
+def middle_end_aa_pipeline_EQ
+ : Joined<[ "-" ], "middle-end-aa-pipeline=">,
+ HelpText<"Alias analysis pipeline to use with -middle-end-passes=">;
+
def disable_llvm_optzns : Flag<["-"], "disable-llvm-optzns">,
HelpText<"Don't run LLVM optimization passes">;
def disable_llvm_verifier : Flag<["-"], "disable-llvm-verifier">,
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits