1 //===-- R600TargetMachine.cpp - TargetMachine for hw codegen targets-------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
10 /// The AMDGPU-R600 target machine contains all of the hardware specific
11 /// information needed to emit code for R600 GPUs.
13 //===----------------------------------------------------------------------===//
15 #include "R600TargetMachine.h"
16 #include "AMDGPUTargetMachine.h"
18 #include "R600CodeGenPassBuilder.h"
19 #include "R600MachineScheduler.h"
20 #include "R600TargetTransformInfo.h"
21 #include "llvm/Transforms/Scalar.h"
27 EnableR600StructurizeCFG("r600-ir-structurize",
28 cl::desc("Use StructurizeCFG IR pass"),
31 static cl::opt
<bool> EnableR600IfConvert("r600-if-convert",
32 cl::desc("Use if conversion pass"),
33 cl::ReallyHidden
, cl::init(true));
35 static cl::opt
<bool, true> EnableAMDGPUFunctionCallsOpt(
36 "amdgpu-function-calls", cl::desc("Enable AMDGPU function call support"),
37 cl::location(AMDGPUTargetMachine::EnableFunctionCalls
), cl::init(true),
40 static ScheduleDAGInstrs
*createR600MachineScheduler(MachineSchedContext
*C
) {
41 return new ScheduleDAGMILive(C
, std::make_unique
<R600SchedStrategy
>());
44 static MachineSchedRegistry
R600SchedRegistry("r600",
45 "Run R600's custom scheduler",
46 createR600MachineScheduler
);
48 //===----------------------------------------------------------------------===//
49 // R600 Target Machine (R600 -> Cayman)
50 //===----------------------------------------------------------------------===//
52 R600TargetMachine::R600TargetMachine(const Target
&T
, const Triple
&TT
,
53 StringRef CPU
, StringRef FS
,
54 const TargetOptions
&Options
,
55 std::optional
<Reloc::Model
> RM
,
56 std::optional
<CodeModel::Model
> CM
,
57 CodeGenOptLevel OL
, bool JIT
)
58 : AMDGPUTargetMachine(T
, TT
, CPU
, FS
, Options
, RM
, CM
, OL
) {
59 setRequiresStructuredCFG(true);
61 // Override the default since calls aren't supported for r600.
62 if (EnableFunctionCalls
&&
63 EnableAMDGPUFunctionCallsOpt
.getNumOccurrences() == 0)
64 EnableFunctionCalls
= false;
67 const TargetSubtargetInfo
*
68 R600TargetMachine::getSubtargetImpl(const Function
&F
) const {
69 StringRef GPU
= getGPUName(F
);
70 StringRef FS
= getFeatureString(F
);
72 SmallString
<128> SubtargetKey(GPU
);
73 SubtargetKey
.append(FS
);
75 auto &I
= SubtargetMap
[SubtargetKey
];
77 // This needs to be done before we create a new subtarget since any
78 // creation will depend on the TM and the code generation flags on the
79 // function that reside in TargetOptions.
80 resetTargetOptions(F
);
81 I
= std::make_unique
<R600Subtarget
>(TargetTriple
, GPU
, FS
, *this);
88 R600TargetMachine::getTargetTransformInfo(const Function
&F
) const {
89 return TargetTransformInfo(R600TTIImpl(this, F
));
93 class R600PassConfig final
: public AMDGPUPassConfig
{
95 R600PassConfig(LLVMTargetMachine
&TM
, PassManagerBase
&PM
)
96 : AMDGPUPassConfig(TM
, PM
) {}
99 createMachineScheduler(MachineSchedContext
*C
) const override
{
100 return createR600MachineScheduler(C
);
103 bool addPreISel() override
;
104 bool addInstSelector() override
;
105 void addPreRegAlloc() override
;
106 void addPreSched2() override
;
107 void addPreEmitPass() override
;
111 //===----------------------------------------------------------------------===//
113 //===----------------------------------------------------------------------===//
115 bool R600PassConfig::addPreISel() {
116 AMDGPUPassConfig::addPreISel();
118 if (EnableR600StructurizeCFG
)
119 addPass(createStructurizeCFGPass());
123 bool R600PassConfig::addInstSelector() {
124 addPass(createR600ISelDag(getAMDGPUTargetMachine(), getOptLevel()));
128 void R600PassConfig::addPreRegAlloc() { addPass(createR600VectorRegMerger()); }
130 void R600PassConfig::addPreSched2() {
131 addPass(createR600EmitClauseMarkers());
132 if (EnableR600IfConvert
)
133 addPass(&IfConverterID
);
134 addPass(createR600ClauseMergePass());
137 void R600PassConfig::addPreEmitPass() {
138 addPass(createR600MachineCFGStructurizerPass());
139 addPass(createR600ExpandSpecialInstrsPass());
140 addPass(&FinalizeMachineBundlesID
);
141 addPass(createR600Packetizer());
142 addPass(createR600ControlFlowFinalizer());
145 TargetPassConfig
*R600TargetMachine::createPassConfig(PassManagerBase
&PM
) {
146 return new R600PassConfig(*this, PM
);
149 Error
R600TargetMachine::buildCodeGenPipeline(
150 ModulePassManager
&MPM
, raw_pwrite_stream
&Out
, raw_pwrite_stream
*DwoOut
,
151 CodeGenFileType FileType
, const CGPassBuilderOption
&Opts
,
152 PassInstrumentationCallbacks
*PIC
) {
153 R600CodeGenPassBuilder
CGPB(*this, Opts
, PIC
);
154 return CGPB
.buildPipeline(MPM
, Out
, DwoOut
, FileType
);