Files
paddlepaddle--paddle/paddle/cinn/backends/llvm/llvm_optimizer.cc
T
2026-07-13 12:40:42 +08:00

172 lines
6.2 KiB
C++

// Copyright (c) 2021 CINN Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "paddle/cinn/backends/llvm/llvm_optimizer.h"
#include <glog/logging.h>
#include <llvm/ADT/Triple.h>
#include <llvm/Analysis/CGSCCPassManager.h>
#include <llvm/AsmParser/Parser.h>
#include <llvm/ExecutionEngine/ExecutionEngine.h>
#include <llvm/ExecutionEngine/JITSymbol.h>
#include <llvm/ExecutionEngine/Orc/CompileUtils.h>
#include <llvm/ExecutionEngine/Orc/Core.h>
#include <llvm/ExecutionEngine/Orc/ExecutionUtils.h>
#include <llvm/ExecutionEngine/Orc/IRCompileLayer.h>
#include <llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h>
#include <llvm/ExecutionEngine/Orc/ThreadSafeModule.h>
#include <llvm/ExecutionEngine/SectionMemoryManager.h>
#include <llvm/IR/IRBuilder.h>
#include <llvm/IR/LegacyPassManager.h>
#include <llvm/IR/Module.h>
#include <llvm/IR/PassManager.h>
#include <llvm/IRReader/IRReader.h>
#include <llvm/Passes/PassBuilder.h>
#include <llvm/Support/Error.h>
#include <llvm/Support/MemoryBuffer.h>
#include <llvm/Support/SmallVectorMemoryBuffer.h>
#include <llvm/Support/SourceMgr.h>
#include <llvm/Support/TargetRegistry.h>
#include <llvm/Support/TargetSelect.h>
#include <llvm/Support/raw_ostream.h>
#include <llvm/Target/TargetMachine.h>
#include <llvm/Target/TargetOptions.h>
#include <llvm/Transforms/IPO.h>
#include <llvm/Transforms/IPO/PassManagerBuilder.h>
#include <llvm/Transforms/InstCombine/InstCombine.h>
#include <llvm/Transforms/Scalar.h>
#include <llvm/Transforms/Scalar/GVN.h>
#include <llvm/Transforms/Scalar/NewGVN.h>
#include <llvm/Transforms/Scalar/Reassociate.h>
#include <llvm/Transforms/Scalar/SimplifyCFG.h>
#include <llvm/Transforms/Vectorize.h>
#include <algorithm>
#include <memory>
#include <string>
#include <type_traits>
#include <utility>
#include "llvm/Support/CodeGen.h"
namespace cinn::backends {
namespace {
template <typename PassManagerT>
class CustomPassManager : public PassManagerT {
public:
template <typename... Ts>
explicit CustomPassManager(bool print_passes, Ts &&...ts)
: PassManagerT(std::forward<Ts>(ts)...), print_passes_(print_passes) {}
void add(llvm::Pass *pass) override {
if (print_passes_) {
if (is_function_pass_manager_) {
VLOG(4) << "llvm run function pass[" << std::string(pass->getPassName())
<< "]";
}
if (is_module_pass_manager_) {
VLOG(4) << "llvm run module pass[" << std::string(pass->getPassName())
<< "]";
}
}
// static bool add_pass = true;
// if (add_pass) {
// PassManagerT::add(pass);
//}
// if (std::string(pass->getPassName()) == "Loop Vectorization") {
// return;
//}
PassManagerT::add(pass);
}
void run(llvm::Function &f) { // NOLINT
if (is_function_pass_manager_) {
PassManagerT::run(f);
}
}
void run(llvm::Module &m) { // NOLINT
if (is_module_pass_manager_) {
PassManagerT::run(m);
}
}
private:
static constexpr bool is_function_pass_manager_ =
std::is_same<llvm::legacy::FunctionPassManager, PassManagerT>::value;
static constexpr bool is_module_pass_manager_ =
std::is_same<llvm::legacy::PassManager, PassManagerT>::value;
bool print_passes_;
};
using CustomFunctionPassManager =
CustomPassManager<llvm::legacy::FunctionPassManager>;
using CustomModulePassManager = CustomPassManager<llvm::legacy::PassManager>;
} // namespace
LLVMModuleOptimizer::LLVMModuleOptimizer(llvm::TargetMachine *machine,
int opt_level,
llvm::FastMathFlags fast_math_flags,
bool print_passes)
: opt_level_(opt_level), print_passes_(print_passes), machine_(machine) {}
void LLVMModuleOptimizer::operator()(llvm::Module *m) {
auto machine = std::move(llvm::cantFail(
llvm::cantFail(llvm::orc::JITTargetMachineBuilder::detectHost())
.createTargetMachine()));
auto fpm = std::make_unique<CustomFunctionPassManager>(print_passes_, m);
// fpm->add(llvm::createTargetTransformInfoWrapperPass(llvm::TargetIRAnalysis()));
// fpm->add(llvm::createInstructionCombiningPass());
// fpm->add(llvm::createReassociatePass());
// fpm->add(llvm::createGVNPass());
// fpm->add(llvm::createCFGSimplificationPass());
// fpm->add(llvm::createSROAPass());
// fpm->add(llvm::createEarlyCSEPass());
// fpm->add(llvm::createLowerExpectIntrinsicPass());
// fpm->add(llvm::createCallSiteSplittingPass());
// fpm->add(llvm::createLoopVectorizePass());
// fpm->add(llvm::createSLPVectorizerPass());
// fpm->add(llvm::createLoadStoreVectorizerPass());
// fpm->add(llvm::createLoopUnrollPass());
auto mpm = std::make_unique<CustomModulePassManager>(print_passes_);
// mpm->add(llvm::createTargetTransformInfoWrapperPass(llvm::TargetIRAnalysis()));
// LOG(INFO) << "llvm run pass: target machine: name[" <<
// machine_->getTarget().getName() << "]"; LOG(INFO) << "llvm run pass: target
// machine: cpu[" << machine_->getTargetCPU().str() << "]";
fpm->add(llvm::createTargetTransformInfoWrapperPass(
machine->getTargetIRAnalysis()));
mpm->add(llvm::createTargetTransformInfoWrapperPass(
machine->getTargetIRAnalysis()));
auto builder = std::make_unique<llvm::PassManagerBuilder>();
builder->OptLevel = opt_level_;
builder->Inliner = llvm::createFunctionInliningPass();
builder->LoopVectorize = true;
builder->SLPVectorize = true;
machine->adjustPassManager(*builder);
builder->populateFunctionPassManager(*fpm);
builder->populateModulePassManager(*mpm);
fpm->doInitialization();
std::for_each(m->begin(), m->end(), [&fpm](auto &fn) { fpm->run(fn); });
fpm->doFinalization();
mpm->run(*m);
}
} // namespace cinn::backends