1f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//===-- AMDGPUTargetMachine.cpp - TargetMachine for hw codegen targets-----===//
2f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//
3f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//                     The LLVM Compiler Infrastructure
4f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//
5f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// This file is distributed under the University of Illinois Open Source
6f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// License. See LICENSE.TXT for details.
7f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//
8f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//===----------------------------------------------------------------------===//
9f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//
10f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard/// \file
11f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard/// \brief The AMDGPU target machine contains all of the hardware specific
12f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard/// information  needed to emit code for R600 and SI GPUs.
13f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//
14f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//===----------------------------------------------------------------------===//
15f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
16f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "AMDGPUTargetMachine.h"
17f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "AMDGPU.h"
18f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "R600ISelLowering.h"
19f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "R600InstrInfo.h"
2062f38ca141f87ff3ed9334fbe6a5e1c45d40ca86Vincent Lejeune#include "R600MachineScheduler.h"
21f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "SIISelLowering.h"
22f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "SIInstrInfo.h"
23f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "llvm/Analysis/Passes.h"
24f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "llvm/Analysis/Verifier.h"
25f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "llvm/CodeGen/MachineFunctionAnalysis.h"
26f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "llvm/CodeGen/MachineModuleInfo.h"
27f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "llvm/CodeGen/Passes.h"
28f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "llvm/MC/MCAsmInfo.h"
29f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "llvm/PassManager.h"
30f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "llvm/Support/TargetRegistry.h"
31f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "llvm/Support/raw_os_ostream.h"
32f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "llvm/Transforms/IPO.h"
33f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "llvm/Transforms/Scalar.h"
34f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include <llvm/CodeGen/Passes.h>
35f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
36f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardusing namespace llvm;
37f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
38f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardextern "C" void LLVMInitializeR600Target() {
39f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  // Register the target
40f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  RegisterTargetMachine<AMDGPUTargetMachine> X(TheAMDGPUTarget);
41f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard}
42f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
4362f38ca141f87ff3ed9334fbe6a5e1c45d40ca86Vincent Lejeunestatic ScheduleDAGInstrs *createR600MachineScheduler(MachineSchedContext *C) {
4462f38ca141f87ff3ed9334fbe6a5e1c45d40ca86Vincent Lejeune  return new ScheduleDAGMI(C, new R600SchedStrategy());
4562f38ca141f87ff3ed9334fbe6a5e1c45d40ca86Vincent Lejeune}
4662f38ca141f87ff3ed9334fbe6a5e1c45d40ca86Vincent Lejeune
4762f38ca141f87ff3ed9334fbe6a5e1c45d40ca86Vincent Lejeunestatic MachineSchedRegistry
4862f38ca141f87ff3ed9334fbe6a5e1c45d40ca86Vincent LejeuneSchedCustomRegistry("r600", "Run R600's custom scheduler",
4962f38ca141f87ff3ed9334fbe6a5e1c45d40ca86Vincent Lejeune                    createR600MachineScheduler);
5062f38ca141f87ff3ed9334fbe6a5e1c45d40ca86Vincent Lejeune
51f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardAMDGPUTargetMachine::AMDGPUTargetMachine(const Target &T, StringRef TT,
52f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    StringRef CPU, StringRef FS,
53f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  TargetOptions Options,
54f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  Reloc::Model RM, CodeModel::Model CM,
55f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  CodeGenOpt::Level OptLevel
56f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard)
57f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard:
58f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OptLevel),
59f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  Subtarget(TT, CPU, FS),
60f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  Layout(Subtarget.getDataLayout()),
613ff0abfaabc2c7f604d490be587b9c27e7c91ac0Tom Stellard  FrameLowering(TargetFrameLowering::StackGrowsUp, 16 // Stack Alignment
623ff0abfaabc2c7f604d490be587b9c27e7c91ac0Tom Stellard                                                 , 0),
63f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  IntrinsicInfo(this),
64f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  InstrItins(&Subtarget.getInstrItineraryData()) {
65f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  // TLInfo uses InstrInfo so it must be initialized after.
663ff0abfaabc2c7f604d490be587b9c27e7c91ac0Tom Stellard  if (Subtarget.getGeneration() <= AMDGPUSubtarget::NORTHERN_ISLANDS) {
675110102f9f7e7ddcd74d3bce1e5de3f898ba5e7fRafael Espindola    InstrInfo.reset(new R600InstrInfo(*this));
685110102f9f7e7ddcd74d3bce1e5de3f898ba5e7fRafael Espindola    TLInfo.reset(new R600TargetLowering(*this));
69f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  } else {
705110102f9f7e7ddcd74d3bce1e5de3f898ba5e7fRafael Espindola    InstrInfo.reset(new SIInstrInfo(*this));
715110102f9f7e7ddcd74d3bce1e5de3f898ba5e7fRafael Espindola    TLInfo.reset(new SITargetLowering(*this));
72f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  }
734a971705bc6030dc2e4338b3cd5cffa2e0f88b7bRafael Espindola  initAsmInfo();
74f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard}
75f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
76f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardAMDGPUTargetMachine::~AMDGPUTargetMachine() {
77f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard}
78f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
79f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardnamespace {
80f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardclass AMDGPUPassConfig : public TargetPassConfig {
81f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardpublic:
82f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  AMDGPUPassConfig(AMDGPUTargetMachine *TM, PassManagerBase &PM)
8362f38ca141f87ff3ed9334fbe6a5e1c45d40ca86Vincent Lejeune    : TargetPassConfig(TM, PM) {
8462f38ca141f87ff3ed9334fbe6a5e1c45d40ca86Vincent Lejeune    const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>();
853ff0abfaabc2c7f604d490be587b9c27e7c91ac0Tom Stellard    if (ST.getGeneration() <= AMDGPUSubtarget::NORTHERN_ISLANDS) {
8662f38ca141f87ff3ed9334fbe6a5e1c45d40ca86Vincent Lejeune      enablePass(&MachineSchedulerID);
8762f38ca141f87ff3ed9334fbe6a5e1c45d40ca86Vincent Lejeune      MachineSchedRegistry::setDefault(createR600MachineScheduler);
8862f38ca141f87ff3ed9334fbe6a5e1c45d40ca86Vincent Lejeune    }
8962f38ca141f87ff3ed9334fbe6a5e1c45d40ca86Vincent Lejeune  }
90f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
91f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  AMDGPUTargetMachine &getAMDGPUTargetMachine() const {
92f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    return getTM<AMDGPUTargetMachine>();
93f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  }
94f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  virtual bool addPreISel();
95f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  virtual bool addInstSelector();
96f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  virtual bool addPreRegAlloc();
97f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  virtual bool addPostRegAlloc();
98f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  virtual bool addPreSched2();
99f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  virtual bool addPreEmitPass();
100f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard};
101f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} // End of anonymous namespace
102f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
103f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardTargetPassConfig *AMDGPUTargetMachine::createPassConfig(PassManagerBase &PM) {
104f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  return new AMDGPUPassConfig(this, PM);
105f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard}
106f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
10757e6b2d1f3de0bf459e96f7038e692d624f7e580Tom Stellard//===----------------------------------------------------------------------===//
10857e6b2d1f3de0bf459e96f7038e692d624f7e580Tom Stellard// AMDGPU Analysis Pass Setup
10957e6b2d1f3de0bf459e96f7038e692d624f7e580Tom Stellard//===----------------------------------------------------------------------===//
11057e6b2d1f3de0bf459e96f7038e692d624f7e580Tom Stellard
11157e6b2d1f3de0bf459e96f7038e692d624f7e580Tom Stellardvoid AMDGPUTargetMachine::addAnalysisPasses(PassManagerBase &PM) {
11257e6b2d1f3de0bf459e96f7038e692d624f7e580Tom Stellard  // Add first the target-independent BasicTTI pass, then our AMDGPU pass. This
11357e6b2d1f3de0bf459e96f7038e692d624f7e580Tom Stellard  // allows the AMDGPU pass to delegate to the target independent layer when
11457e6b2d1f3de0bf459e96f7038e692d624f7e580Tom Stellard  // appropriate.
11557e6b2d1f3de0bf459e96f7038e692d624f7e580Tom Stellard  PM.add(createBasicTargetTransformInfoPass(this));
11657e6b2d1f3de0bf459e96f7038e692d624f7e580Tom Stellard  PM.add(createAMDGPUTargetTransformInfoPass(this));
11757e6b2d1f3de0bf459e96f7038e692d624f7e580Tom Stellard}
11857e6b2d1f3de0bf459e96f7038e692d624f7e580Tom Stellard
119f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool
120f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardAMDGPUPassConfig::addPreISel() {
1216b7d99d47321ebb478b22afd2e317fe89d2149dbTom Stellard  const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>();
12201d7203ef8316fdd71c3cec59f8e68fb869e0dbfTom Stellard  addPass(createFlattenCFGPass());
1233ff0abfaabc2c7f604d490be587b9c27e7c91ac0Tom Stellard  if (ST.getGeneration() > AMDGPUSubtarget::NORTHERN_ISLANDS) {
124ad966ea7a81a538425d5319f6d8568e460639e54Matt Arsenault    addPass(createStructurizeCFGPass());
1256b7d99d47321ebb478b22afd2e317fe89d2149dbTom Stellard    addPass(createSIAnnotateControlFlowPass());
126d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune  } else {
127d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    addPass(createR600TextureIntrinsicsReplacer());
1286b7d99d47321ebb478b22afd2e317fe89d2149dbTom Stellard  }
129f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  return false;
130f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard}
131f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
132f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool AMDGPUPassConfig::addInstSelector() {
133f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  addPass(createAMDGPUISelDag(getAMDGPUTargetMachine()));
134c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard
135c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard  const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>();
1363ff0abfaabc2c7f604d490be587b9c27e7c91ac0Tom Stellard  if (ST.getGeneration() <= AMDGPUSubtarget::NORTHERN_ISLANDS) {
137c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard    // This callbacks this pass uses are not implemented yet on SI.
138c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard    addPass(createAMDGPUIndirectAddressingPass(*TM));
139c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard  }
140f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  return false;
141f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard}
142f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
143f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool AMDGPUPassConfig::addPreRegAlloc() {
144f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  addPass(createAMDGPUConvertToISAPass(*TM));
145f3d6e32c09ac73b49628f5ec7066af5eca2737b5Vincent Lejeune  const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>();
1463ff0abfaabc2c7f604d490be587b9c27e7c91ac0Tom Stellard
1473ff0abfaabc2c7f604d490be587b9c27e7c91ac0Tom Stellard  if (ST.getGeneration() <= AMDGPUSubtarget::NORTHERN_ISLANDS) {
148f3d6e32c09ac73b49628f5ec7066af5eca2737b5Vincent Lejeune    addPass(createR600VectorRegMerger(*TM));
1493492eefa4b2509c87598678a6977074a3f6a50e6Tom Stellard  } else {
1503492eefa4b2509c87598678a6977074a3f6a50e6Tom Stellard    addPass(createSIFixSGPRCopiesPass(*TM));
151f3d6e32c09ac73b49628f5ec7066af5eca2737b5Vincent Lejeune  }
152f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  return false;
153f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard}
154f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
155f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool AMDGPUPassConfig::addPostRegAlloc() {
15682d3d4524f2595b2dce617e963b6d67876b4f9baTom Stellard  const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>();
15782d3d4524f2595b2dce617e963b6d67876b4f9baTom Stellard
1583ff0abfaabc2c7f604d490be587b9c27e7c91ac0Tom Stellard  if (ST.getGeneration() > AMDGPUSubtarget::NORTHERN_ISLANDS) {
15982d3d4524f2595b2dce617e963b6d67876b4f9baTom Stellard    addPass(createSIInsertWaits(*TM));
16082d3d4524f2595b2dce617e963b6d67876b4f9baTom Stellard  }
161f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  return false;
162f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard}
163f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
164f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool AMDGPUPassConfig::addPreSched2() {
165f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune  const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>();
166f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
167f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune  if (ST.getGeneration() <= AMDGPUSubtarget::NORTHERN_ISLANDS) {
168f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune    addPass(createR600EmitClauseMarkers(*TM));
169f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune  }
170f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  addPass(&IfConverterID);
171f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  return false;
172f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard}
173f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
174f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool AMDGPUPassConfig::addPreEmitPass() {
175f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>();
1763ff0abfaabc2c7f604d490be587b9c27e7c91ac0Tom Stellard  if (ST.getGeneration() <= AMDGPUSubtarget::NORTHERN_ISLANDS) {
1776b7d99d47321ebb478b22afd2e317fe89d2149dbTom Stellard    addPass(createAMDGPUCFGStructurizerPass(*TM));
178f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    addPass(createR600ExpandSpecialInstrsPass(*TM));
179f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    addPass(&FinalizeMachineBundlesID);
18025f259cde28860ea76c2f5628010968945a28edbVincent Lejeune    addPass(createR600Packetizer(*TM));
18125f259cde28860ea76c2f5628010968945a28edbVincent Lejeune    addPass(createR600ControlFlowFinalizer(*TM));
182f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  } else {
183f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    addPass(createSILowerControlFlowPass(*TM));
184f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  }
185f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
186f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  return false;
187f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard}
188f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
189