
This fixes what I consider to be an API flaw I've tripped over multiple times. The point this is constructed isn't well defined, so depending on where this is first called, you can conclude different information based on the MachineFunction. For example, the AMDGPU implementation inspected the MachineFrameInfo on construction for the stack objects and if the frame has calls. This kind of worked in SelectionDAG which visited all allocas up front, but broke in GlobalISel which hasn't visited any of the IR when arguments are lowered. I've run into similar problems before with the MIR parser and trying to make use of other MachineFunction fields, so I think it's best to just categorically disallow dependency on the MachineFunction state in the constructor and to always construct this at the same time as the MachineFunction itself. A missing feature I still could use is a way to access an custom analysis pass on the IR here.
150 lines
5.2 KiB
C++
150 lines
5.2 KiB
C++
//===-- AMDGPUTargetMachine.h - AMDGPU TargetMachine Interface --*- C++ -*-===//
|
|
//
|
|
// 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
/// \file
|
|
/// The AMDGPU TargetMachine interface definition for hw codegen targets.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_LIB_TARGET_AMDGPU_AMDGPUTARGETMACHINE_H
|
|
#define LLVM_LIB_TARGET_AMDGPU_AMDGPUTARGETMACHINE_H
|
|
|
|
#include "GCNSubtarget.h"
|
|
#include "llvm/CodeGen/TargetPassConfig.h"
|
|
#include "llvm/Target/TargetMachine.h"
|
|
#include <optional>
|
|
#include <utility>
|
|
|
|
namespace llvm {
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// AMDGPU Target Machine (R600+)
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
class AMDGPUTargetMachine : public LLVMTargetMachine {
|
|
protected:
|
|
std::unique_ptr<TargetLoweringObjectFile> TLOF;
|
|
|
|
StringRef getGPUName(const Function &F) const;
|
|
StringRef getFeatureString(const Function &F) const;
|
|
|
|
public:
|
|
static bool EnableLateStructurizeCFG;
|
|
static bool EnableFunctionCalls;
|
|
static bool EnableLowerModuleLDS;
|
|
|
|
AMDGPUTargetMachine(const Target &T, const Triple &TT, StringRef CPU,
|
|
StringRef FS, TargetOptions Options,
|
|
std::optional<Reloc::Model> RM,
|
|
std::optional<CodeModel::Model> CM, CodeGenOpt::Level OL);
|
|
~AMDGPUTargetMachine() override;
|
|
|
|
const TargetSubtargetInfo *getSubtargetImpl() const;
|
|
const TargetSubtargetInfo *getSubtargetImpl(const Function &) const override = 0;
|
|
|
|
TargetLoweringObjectFile *getObjFileLowering() const override {
|
|
return TLOF.get();
|
|
}
|
|
|
|
void registerPassBuilderCallbacks(PassBuilder &PB) override;
|
|
void registerDefaultAliasAnalyses(AAManager &) override;
|
|
|
|
/// Get the integer value of a null pointer in the given address space.
|
|
static int64_t getNullPointerValue(unsigned AddrSpace);
|
|
|
|
bool isNoopAddrSpaceCast(unsigned SrcAS, unsigned DestAS) const override;
|
|
|
|
unsigned getAssumedAddrSpace(const Value *V) const override;
|
|
|
|
std::pair<const Value *, unsigned>
|
|
getPredicatedAddrSpace(const Value *V) const override;
|
|
|
|
unsigned getAddressSpaceForPseudoSourceKind(unsigned Kind) const override;
|
|
};
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// GCN Target Machine (SI+)
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
class GCNTargetMachine final : public AMDGPUTargetMachine {
|
|
private:
|
|
mutable StringMap<std::unique_ptr<GCNSubtarget>> SubtargetMap;
|
|
|
|
public:
|
|
GCNTargetMachine(const Target &T, const Triple &TT, StringRef CPU,
|
|
StringRef FS, TargetOptions Options,
|
|
std::optional<Reloc::Model> RM,
|
|
std::optional<CodeModel::Model> CM, CodeGenOpt::Level OL,
|
|
bool JIT);
|
|
|
|
TargetPassConfig *createPassConfig(PassManagerBase &PM) override;
|
|
|
|
const TargetSubtargetInfo *getSubtargetImpl(const Function &) const override;
|
|
|
|
TargetTransformInfo getTargetTransformInfo(const Function &F) const override;
|
|
|
|
bool useIPRA() const override {
|
|
return true;
|
|
}
|
|
|
|
MachineFunctionInfo *
|
|
createMachineFunctionInfo(BumpPtrAllocator &Allocator, const Function &F,
|
|
const TargetSubtargetInfo *STI) const override;
|
|
|
|
yaml::MachineFunctionInfo *createDefaultFuncInfoYAML() const override;
|
|
yaml::MachineFunctionInfo *
|
|
convertFuncInfoToYAML(const MachineFunction &MF) const override;
|
|
bool parseMachineFunctionInfo(const yaml::MachineFunctionInfo &,
|
|
PerFunctionMIParsingState &PFS,
|
|
SMDiagnostic &Error,
|
|
SMRange &SourceRange) const override;
|
|
};
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// AMDGPU Pass Setup
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
class AMDGPUPassConfig : public TargetPassConfig {
|
|
public:
|
|
AMDGPUPassConfig(LLVMTargetMachine &TM, PassManagerBase &PM);
|
|
|
|
AMDGPUTargetMachine &getAMDGPUTargetMachine() const {
|
|
return getTM<AMDGPUTargetMachine>();
|
|
}
|
|
|
|
ScheduleDAGInstrs *
|
|
createMachineScheduler(MachineSchedContext *C) const override;
|
|
|
|
void addEarlyCSEOrGVNPass();
|
|
void addStraightLineScalarOptimizationPasses();
|
|
void addIRPasses() override;
|
|
void addCodeGenPrepare() override;
|
|
bool addPreISel() override;
|
|
bool addInstSelector() override;
|
|
bool addGCPasses() override;
|
|
|
|
std::unique_ptr<CSEConfigBase> getCSEConfig() const override;
|
|
|
|
/// Check if a pass is enabled given \p Opt option. The option always
|
|
/// overrides defaults if explicitly used. Otherwise its default will
|
|
/// be used given that a pass shall work at an optimization \p Level
|
|
/// minimum.
|
|
bool isPassEnabled(const cl::opt<bool> &Opt,
|
|
CodeGenOpt::Level Level = CodeGenOpt::Default) const {
|
|
if (Opt.getNumOccurrences())
|
|
return Opt;
|
|
if (TM->getOptLevel() < Level)
|
|
return false;
|
|
return Opt;
|
|
}
|
|
};
|
|
|
|
} // end namespace llvm
|
|
|
|
#endif // LLVM_LIB_TARGET_AMDGPU_AMDGPUTARGETMACHINE_H
|