Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[AIEX] NFC : Refactor TargetMachine & PassConfig code #179

Merged
merged 1 commit into from
Sep 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions llvm/lib/Target/AIE/AIE2TargetMachine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,13 +85,18 @@ AIE2TargetMachine::AIE2TargetMachine(const Target &T, const Triple &TT,
}

// AIE2 Pass Setup
class AIE2PassConfig final : public AIEPassConfig {
class AIE2PassConfig final : public AIEBasePassConfig {
public:
AIE2PassConfig(LLVMTargetMachine &TM, PassManagerBase &PM)
: AIEPassConfig(TM, PM) {
: AIEBasePassConfig(TM, PM) {
if (!EnableSubregRenaming)
disablePass(&RenameIndependentSubregsID);
}

AIE2TargetMachine &getAIETargetMachine() const {
return getTM<AIE2TargetMachine>();
}

bool addPreISel() override;
void addPreEmitPass() override;
bool addInstSelector() override;
Expand Down
7 changes: 1 addition & 6 deletions llvm/lib/Target/AIE/AIE2TargetMachine.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,8 @@
#define LLVM_LIB_TARGET_AIE_AIE2TARGETMACHINE_H

#include "AIE2Subtarget.h"
#include "AIETargetMachine.h"
#include "AIEBaseTargetMachine.h"
#include "MCTargetDesc/AIE2MCTargetDesc.h"
#include "llvm/CodeGen/SelectionDAGTargetInfo.h"
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/Target/TargetMachine.h"
#include <optional>

namespace llvm {

Expand Down
284 changes: 284 additions & 0 deletions llvm/lib/Target/AIE/AIEBaseTargetMachine.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,284 @@
//===-- AIEBaseTargetMachine.cpp - AIE Target Machine -----------*- C++ -*-===//
//
// This file is licensed 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
//
// (c) Copyright 2024 Advanced Micro Devices, Inc. or its affiliates
//
//===----------------------------------------------------------------------===//
//
// This file contains common implementation of TargetMachine and
// TargetPassConfig code between AIE versions.
//
//===----------------------------------------------------------------------===//

#include "AIEBaseTargetMachine.h"
#include "AIE.h"
#include "AIEBaseAliasAnalysis.h"
#include "AIEMachineFunctionInfo.h"
#include "AIEMachineScheduler.h"
#include "AIETargetObjectFile.h"
#include "TargetInfo/AIETargetInfo.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/CodeGen/CSEConfigBase.h"
#include "llvm/CodeGen/GlobalISel/CSEInfo.h"
#include "llvm/CodeGen/GlobalISel/IRTranslator.h"
#include "llvm/CodeGen/GlobalISel/InstructionSelect.h"
#include "llvm/CodeGen/GlobalISel/Legalizer.h"
#include "llvm/CodeGen/GlobalISel/RegBankSelect.h"
#include "llvm/CodeGen/MIRParser/MIParser.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/InitializePasses.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/PassRegistry.h"
#include "llvm/Passes/PassBuilder.h"
#include "llvm/Support/CodeGen.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Transforms/IPO/GlobalDCE.h"
#include "llvm/Transforms/IPO/Internalize.h"
#include "llvm/Transforms/Scalar.h"

using namespace llvm;

static cl::opt<bool>
EnableCustomAliasAnalysisOpt("aie-enable-alias-analysis",
cl::desc("Enable AIE alias analysis pass"),
cl::init(true), cl::Hidden);

static cl::opt<bool>
EnableTailMergingOpt("aie-enable-tail-merge",
cl::desc("Enable tail merging for AIE."),
cl::init(false), cl::Hidden);

// Option to run internalize pass.
static cl::opt<bool> InternalizeSymbols(
"aie-internalize-symbols",
cl::desc("Enable elimination of non-kernel functions and unused globals"),
cl::init(false), cl::Hidden);

// Option to skip the functions we don't want to internalize.
static cl::list<std::string>
FunctionSkipList("aie-internalize-skip-functions",
cl::desc("List of function names to skip internalization"),
cl::Hidden, cl::list_init<std::string>({"main"}),
cl::CommaSeparated);

static StringRef computeDataLayout(const Triple &TT) {
return "e-m:e-p:20:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-f32:32:32-i64:32-"
"f64:32-a:0:32-n32";
}

static Reloc::Model getEffectiveRelocModel(const Triple &TT,
std::optional<Reloc::Model> RM) {
if (!RM.has_value())
return Reloc::Static;
// AIE does not support PIC code. If PIC code is asked for then just ignore
// it. The main user of this is compiling the builtin library, which asks for
// PIC.
if (*RM == Reloc::PIC_)
return Reloc::Static;
return *RM;
}

AIEBaseTargetMachine::AIEBaseTargetMachine(const Target &T, const Triple &TT,
StringRef CPU, StringRef FS,
const TargetOptions &Options,
std::optional<Reloc::Model> RM,
std::optional<CodeModel::Model> CM,
CodeGenOptLevel OL, bool JIT)
: LLVMTargetMachine(T, computeDataLayout(TT), TT, CPU, FS, Options,
getEffectiveRelocModel(TT, RM),
getEffectiveCodeModel(CM, CodeModel::Small), OL),
TLOF(std::make_unique<AIEELFTargetObjectFile>()) {
initAsmInfo();
EnableCustomAliasAnalysis = EnableCustomAliasAnalysisOpt;
}

yaml::MachineFunctionInfo *
AIEBaseTargetMachine::createDefaultFuncInfoYAML() const {
return new yaml::AIEMachineFunctionInfo();
}

yaml::MachineFunctionInfo *
AIEBaseTargetMachine::convertFuncInfoToYAML(const MachineFunction &MF) const {
const auto *MFI = MF.getInfo<AIEMachineFunctionInfo>();
return new yaml::AIEMachineFunctionInfo(*MFI);
}

bool AIEBaseTargetMachine::parseMachineFunctionInfo(
const yaml::MachineFunctionInfo &MFI, PerFunctionMIParsingState &PFS,
SMDiagnostic &Error, SMRange &SourceRange) const {
const auto &YamlMFI =
reinterpret_cast<const yaml::AIEMachineFunctionInfo &>(MFI);
MachineFunction &MF = PFS.MF;
MF.getInfo<AIEMachineFunctionInfo>()->initializeBaseYamlFields(YamlMFI);
return false;
}

MachineFunctionInfo *AIEBaseTargetMachine::createMachineFunctionInfo(
BumpPtrAllocator &Allocator, const Function &F,
const TargetSubtargetInfo *STI) const {
return new (Allocator.Allocate<AIEMachineFunctionInfo>())
AIEMachineFunctionInfo(F, STI, *this);
}

bool AIEBaseTargetMachine::isNoopAddrSpaceCast(unsigned SrcAS,
unsigned DestAS) const {
// AIE address space is used for bank annotation only.
// aie-addrspace-flattening pass retyped pointer with a AS to default AS.
return true;
}

void AIEBaseTargetMachine::registerDefaultAliasAnalyses(AAManager &AAM) {
if (EnableCustomAliasAnalysis)
AAM.registerFunctionAnalysis<AIEBaseAA>();
}

/// Predicate for Internalize pass.
/// Preserve functions that can be an entry point or that have uses within the
/// Module.
static bool mustPreserveGV(const GlobalValue &GV) {
if (const Function *F = dyn_cast<Function>(&GV)) {
bool Skip = llvm::any_of(FunctionSkipList, [&](const std::string &Name) {
return F->getName().equals(Name);
});
return F->isDeclaration() || Skip;
}

GV.removeDeadConstantUsers();
return !GV.use_empty();
}

void AIEBaseTargetMachine::registerPassBuilderCallbacks(
PassBuilder &PB, bool PopulateClassToPassNames) {
if (EnableCustomAliasAnalysis) {
PB.registerAnalysisRegistrationCallback([](FunctionAnalysisManager &FAM) {
FAM.registerPass([&] { return AIEBaseAA(); });
});
PB.registerParseAACallback([](StringRef AAName, AAManager &AAM) {
if (AAName == "aie-aa") {
AAM.registerFunctionAnalysis<AIEBaseAA>();
return true;
}
return false;
});
}

if (InternalizeSymbols) {
PB.registerPipelineEarlySimplificationEPCallback(
[](ModulePassManager &PM, OptimizationLevel) {
if (InternalizeSymbols) {
PM.addPass(InternalizePass(mustPreserveGV));
PM.addPass(GlobalDCEPass());
}
});
}
}

AIEBasePassConfig::AIEBasePassConfig(LLVMTargetMachine &TM, PassManagerBase &PM)
: TargetPassConfig(TM, PM) {
EnableTailMerge = EnableTailMergingOpt;
EnableCustomAliasAnalysis = EnableCustomAliasAnalysisOpt;
}

void AIEBasePassConfig::addIRPasses() {
// Always expand atomic operations, we don't deal with atomicrmw or cmpxchg
// ourselves.
addPass(createAtomicExpandLegacyPass());

if (TM->getOptLevel() > CodeGenOptLevel::None) {
if (EnableCustomAliasAnalysis) {
addPass(createAIEBaseAAWrapperPass());
addPass(
createExternalAAWrapperPass([](Pass &P, Function &, AAResults &AAR) {
if (auto *WrapperPass =
P.getAnalysisIfAvailable<AIEBaseAAWrapperPass>())
AAR.addAAResult(WrapperPass->getResult());
}));
}
}
if (TM->getOptLevel() > CodeGenOptLevel::None)
addPass(createInferAddressSpacesPass());
TargetPassConfig::addIRPasses();
}

void AIEBasePassConfig::addMachineLateOptimization() {
TargetPassConfig::addMachineLateOptimization();
// Run MachineCopyPropagation again, but take into account
// architecture-specific mov operations using isMoveReg (see isCopyInstrImpl
// hook)
addPass(createMachineCopyPropagationPass(true));
}

bool AIEBasePassConfig::addIRTranslator() {
addPass(new IRTranslator(getOptLevel()));
return false;
}

bool AIEBasePassConfig::addLegalizeMachineIR() {
addPass(new Legalizer());
return false;
}

bool AIEBasePassConfig::addRegBankSelect() {
addPass(new RegBankSelect());
return false;
}

bool AIEBasePassConfig::addGlobalInstructionSelect() {
addPass(new InstructionSelect(getOptLevel()));
return false;
}

bool AIEBasePassConfig::addInstSelector() { return false; }

void AIEBasePassConfig::addPreEmitPass() {}

void AIEBasePassConfig::addPreEmitPass2() {}

void AIEBasePassConfig::addPreRegAlloc() {}

void AIEBasePassConfig::addPreSched2() {
// PostRAScheduler is required to insert NoOps for correctness.
// We always run it, independently of the Opt level.
addPass(&PostRASchedulerID);
// After scheduling, create the bundles from the BundleWithPred flags
addPass(&FinalizeMachineBundlesID);
}

ScheduleDAGInstrs *
AIEBasePassConfig::createPostMachineScheduler(MachineSchedContext *C) const {
ScheduleDAGMI *DAG =
new AIEScheduleDAGMI(C, std::make_unique<AIEPostRASchedStrategy>(C),
/* RemoveKillFlags=*/true);
for (auto &Mutation :
AIEBaseSubtarget::getPostRAMutationsImpl(TM->getTargetTriple()))
DAG->addMutation(std::move(Mutation));
return DAG;
}

ScheduleDAGInstrs *
AIEBasePassConfig::createMachineScheduler(MachineSchedContext *C) const {
ScheduleDAGMILive *DAG =
new AIEScheduleDAGMILive(C, std::make_unique<AIEPreRASchedStrategy>(C));
DAG->addMutation(createCopyConstrainDAGMutation(DAG->TII, DAG->TRI));

for (auto &Mutation :
AIEBaseSubtarget::getPreRAMutationsImpl(TM->getTargetTriple()))
DAG->addMutation(std::move(Mutation));
return DAG;
}

std::unique_ptr<CSEConfigBase> AIEBasePassConfig::getCSEConfig() const {
// We don't want CSE to run at -O0, as it introduces constrained register
// operands (r27) that RegAllocFast is not able to resolve.
if (TM->getOptLevel() == CodeGenOptLevel::None)
return std::make_unique<CSEConfigBase>();
return getStandardCSEConfigForOpt(TM->getOptLevel());
}
Loading
Loading