blob: 940906b785c2ba2ba4464db6a46a125822011d4f [file] [edit]
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
#include "SystemZ.h"
#include "SystemZTargetMachine.h"
#include "llvm/CodeGen/AtomicExpand.h"
#include "llvm/CodeGen/EarlyIfConversion.h"
#include "llvm/CodeGen/MachineCombiner.h"
#include "llvm/CodeGen/MachineScheduler.h"
#include "llvm/IR/PassInstrumentation.h"
#include "llvm/Passes/CodeGenPassBuilder.h"
#include "llvm/Passes/PassBuilder.h"
#include "llvm/Support/CodeGen.h"
#include "llvm/Target/CGPassBuilderOption.h"
#include "llvm/Transforms/Scalar/LoopDataPrefetch.h"
using namespace llvm;
extern cl::opt<bool> EnableMachineCombinerPass;
namespace {
class SystemZCodeGenPassBuilder : public CodeGenPassBuilder {
using Base = CodeGenPassBuilder;
SystemZTargetMachine &getTM() const {
return static_cast<SystemZTargetMachine &>(TM);
}
public:
explicit SystemZCodeGenPassBuilder(SystemZTargetMachine &TM,
const CGPassBuilderOption &Opts,
PassInstrumentationCallbacks *PIC)
: CodeGenPassBuilder(TM, Opts, PIC) {}
void addIRPasses(PassManagerWrapper &PMW) override;
Error addInstSelector(PassManagerWrapper &PMW) override;
void addILPOpts(PassManagerWrapper &PMW) override;
void addPreRegAlloc(PassManagerWrapper &PMW) override;
void addPostRewrite(PassManagerWrapper &PMW) override;
void addPostRegAlloc(PassManagerWrapper &PMW) override;
void addPreSched2(PassManagerWrapper &PMW) override;
void addPreEmitPass(PassManagerWrapper &PMW) override;
void addAsmPrinterBegin(PassManagerWrapper &PMW) override;
void addAsmPrinter(PassManagerWrapper &PMW) override;
void addAsmPrinterEnd(PassManagerWrapper &PMW) override;
};
void SystemZCodeGenPassBuilder::addIRPasses(PassManagerWrapper &PMW) {
if (getOptLevel() != CodeGenOptLevel::None) {
flushFPMsToMPM(PMW);
addModulePass(SystemZAlignGlobalsPass(), PMW);
// TODO(boomanaiden154): Add SystemZTDCPass
addFunctionPass(LoopDataPrefetchPass(), PMW);
}
addFunctionPass(AtomicExpandPass(getTM()), PMW);
Base::addIRPasses(PMW);
}
Error SystemZCodeGenPassBuilder::addInstSelector(PassManagerWrapper &PMW) {
addMachineFunctionPass(SystemZISelDAGToDAGPass(getTM(), getOptLevel()), PMW);
if (getOptLevel() != CodeGenOptLevel::None) {
// TODO(boomanaiden154): Add SystemZLDCleanupPass
}
return Error::success();
}
void SystemZCodeGenPassBuilder::addILPOpts(PassManagerWrapper &PMW) {
addMachineFunctionPass(EarlyIfConverterPass(), PMW);
if (EnableMachineCombinerPass)
addMachineFunctionPass(MachineCombinerPass(), PMW);
}
void SystemZCodeGenPassBuilder::addPreRegAlloc(PassManagerWrapper &PMW) {
// TODO(boomanaiden154): Add SystemZCopyPhysRegsPass
}
void SystemZCodeGenPassBuilder::addPostRewrite(PassManagerWrapper &PMW) {
// TODO(boomanaiden154): Add SystemZPostRewritePass
}
void SystemZCodeGenPassBuilder::addPostRegAlloc(PassManagerWrapper &PMW) {
// PostRewrite needs to be run at -O0 also (in which case addPostRewrite()
// is not called).
if (getOptLevel() == CodeGenOptLevel::None) {
// TODO(boomanaiden154): Add SystemZPostRewritePass
}
}
void SystemZCodeGenPassBuilder::addPreSched2(PassManagerWrapper &PMW) {
if (getOptLevel() != CodeGenOptLevel::None) {
// TODO(boomanaiden154): Add IfConverter
}
}
void SystemZCodeGenPassBuilder::addPreEmitPass(PassManagerWrapper &PMW) {
// Do instruction shortening before compare elimination because some
// vector instructions will be shortened into opcodes that compare
// elimination recognizes.
if (getOptLevel() != CodeGenOptLevel::None) {
// TODO(boomanaiden154): Add SystemZShortenInstPass
}
// We eliminate comparisons here rather than earlier because some
// transformations can change the set of available CC values and we
// generally want those transformations to have priority. This is
// especially true in the commonest case where the result of the comparison
// is used by a single in-range branch instruction, since we will then
// be able to fuse the compare and the branch instead.
//
// For example, two-address NILF can sometimes be converted into
// three-address RISBLG. NILF produces a CC value that indicates whether
// the low word is zero, but RISBLG does not modify CC at all. On the
// other hand, 64-bit ANDs like NILL can sometimes be converted to RISBG.
// The CC value produced by NILL isn't useful for our purposes, but the
// value produced by RISBG can be used for any comparison with zero
// (not just equality). So there are some transformations that lose
// CC values (while still being worthwhile) and others that happen to make
// the CC result more useful than it was originally.
//
// Another reason is that we only want to use BRANCH ON COUNT in cases
// where we know that the count register is not going to be spilled.
//
// Doing it so late makes it more likely that a register will be reused
// between the comparison and the branch, but it isn't clear whether
// preventing that would be a win or not.
if (getOptLevel() != CodeGenOptLevel::None) {
// TODO(boomanaiden154): Add SystemZElimComparePass
}
// TODO(boomanaiden154): Add SystemZLongBranchPass
// Do final scheduling after all other optimizations, to get an
// optimal input for the decoder (branch relaxation must happen
// after block placement).
if (getOptLevel() != CodeGenOptLevel::None)
addMachineFunctionPass(PostMachineSchedulerPass(&getTM()), PMW);
}
void SystemZCodeGenPassBuilder::addAsmPrinterBegin(PassManagerWrapper &PMW) {
// TODO(boomanaiden154): Add SystemZAsmPrinterBegin
}
void SystemZCodeGenPassBuilder::addAsmPrinter(PassManagerWrapper &PMW) {
// TODO(boomanaiden154): Add SystemZAsmPrinter
}
void SystemZCodeGenPassBuilder::addAsmPrinterEnd(PassManagerWrapper &PMW) {
// TODO(boomanaiden154): Add SystemZAsmPrinterEnd
}
} // namespace
void SystemZTargetMachine::registerPassBuilderCallbacks(PassBuilder &PB){
#define GET_PASS_REGISTRY "SystemZPassRegistry.def"
#include "llvm/Passes/TargetPassRegistry.inc"
}
Error SystemZTargetMachine::buildCodeGenPipeline(
ModulePassManager &MPM, ModuleAnalysisManager &MAM, raw_pwrite_stream &Out,
raw_pwrite_stream *DwoOut, CodeGenFileType FileType,
const CGPassBuilderOption &Opt, MCContext &Ctx,
PassInstrumentationCallbacks *PIC) {
auto CGPB = SystemZCodeGenPassBuilder(*this, Opt, PIC);
return CGPB.buildPipeline(MPM, MAM, Out, DwoOut, FileType, Ctx);
}