#include "mlir/ExecutionEngine/OptUtils.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/IR/Module.h"
#include "llvm/Passes/OptimizationLevel.h"
#include "llvm/Passes/PassBuilder.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Target/TargetMachine.h"
#include <optional>
using namespace llvm;
static std::optional<OptimizationLevel> mapToLevel(unsigned optLevel,
unsigned sizeLevel) {
switch (optLevel) {
case 0:
return OptimizationLevel::O0;
case 1:
return OptimizationLevel::O1;
case 2:
switch (sizeLevel) {
case 0:
return OptimizationLevel::O2;
case 1:
return OptimizationLevel::Os;
case 2:
return OptimizationLevel::Oz;
}
break;
case 3:
return OptimizationLevel::O3;
}
return std::nullopt;
}
std::function<Error(Module *)>
mlir::makeOptimizingTransformer(unsigned optLevel, unsigned sizeLevel,
TargetMachine *targetMachine) {
return [optLevel, sizeLevel, targetMachine](Module *m) -> Error {
std::optional<OptimizationLevel> ol = mapToLevel(optLevel, sizeLevel);
if (!ol) {
return make_error<StringError>(
formatv("invalid optimization/size level {0}/{1}", optLevel,
sizeLevel)
.str(),
inconvertibleErrorCode());
}
LoopAnalysisManager lam;
FunctionAnalysisManager fam;
CGSCCAnalysisManager cgam;
ModuleAnalysisManager mam;
PipelineTuningOptions tuningOptions;
tuningOptions.LoopUnrolling = true;
tuningOptions.LoopInterleaving = true;
tuningOptions.LoopVectorization = true;
tuningOptions.SLPVectorization = true;
PassBuilder pb(targetMachine, tuningOptions);
pb.registerModuleAnalyses(mam);
pb.registerCGSCCAnalyses(cgam);
pb.registerFunctionAnalyses(fam);
pb.registerLoopAnalyses(lam);
pb.crossRegisterProxies(lam, fam, cgam, mam);
ModulePassManager mpm;
mpm.addPass(pb.buildPerModuleDefaultPipeline(*ol));
mpm.run(*m, mam);
return Error::success();
};
}