1 //===-- HexagonTargetMachine.cpp - Define TargetMachine for Hexagon -------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // Implements the info about Hexagon target spec.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "HexagonTargetMachine.h"
15 #include "Hexagon.h"
16 #include "HexagonISelLowering.h"
17 #include "HexagonMachineScheduler.h"
18 #include "HexagonTargetObjectFile.h"
19 #include "HexagonTargetTransformInfo.h"
20 #include "llvm/CodeGen/Passes.h"
21 #include "llvm/IR/LegacyPassManager.h"
22 #include "llvm/IR/Module.h"
23 #include "llvm/Support/CommandLine.h"
24 #include "llvm/Support/TargetRegistry.h"
25 #include "llvm/Transforms/Scalar.h"
26 
27 using namespace llvm;
28 
29 
30 static cl::opt<bool> EnableRDFOpt("rdf-opt", cl::Hidden, cl::ZeroOrMore,
31   cl::init(true), cl::desc("Enable RDF-based optimizations"));
32 
33 static cl::opt<bool> DisableHardwareLoops("disable-hexagon-hwloops",
34   cl::Hidden, cl::desc("Disable Hardware Loops for Hexagon target"));
35 
36 static cl::opt<bool> DisableAModeOpt("disable-hexagon-amodeopt",
37   cl::Hidden, cl::ZeroOrMore, cl::init(false),
38   cl::desc("Disable Hexagon Addressing Mode Optimization"));
39 
40 static cl::opt<bool> DisableHexagonCFGOpt("disable-hexagon-cfgopt",
41   cl::Hidden, cl::ZeroOrMore, cl::init(false),
42   cl::desc("Disable Hexagon CFG Optimization"));
43 
44 static cl::opt<bool> DisableStoreWidening("disable-store-widen",
45   cl::Hidden, cl::init(false), cl::desc("Disable store widening"));
46 
47 static cl::opt<bool> EnableExpandCondsets("hexagon-expand-condsets",
48   cl::init(true), cl::Hidden, cl::ZeroOrMore,
49   cl::desc("Early expansion of MUX"));
50 
51 static cl::opt<bool> EnableEarlyIf("hexagon-eif", cl::init(true), cl::Hidden,
52   cl::ZeroOrMore, cl::desc("Enable early if-conversion"));
53 
54 static cl::opt<bool> EnableGenInsert("hexagon-insert", cl::init(true),
55   cl::Hidden, cl::desc("Generate \"insert\" instructions"));
56 
57 static cl::opt<bool> EnableCommGEP("hexagon-commgep", cl::init(true),
58   cl::Hidden, cl::ZeroOrMore, cl::desc("Enable commoning of GEP instructions"));
59 
60 static cl::opt<bool> EnableGenExtract("hexagon-extract", cl::init(true),
61   cl::Hidden, cl::desc("Generate \"extract\" instructions"));
62 
63 static cl::opt<bool> EnableGenMux("hexagon-mux", cl::init(true), cl::Hidden,
64   cl::desc("Enable converting conditional transfers into MUX instructions"));
65 
66 static cl::opt<bool> EnableGenPred("hexagon-gen-pred", cl::init(true),
67   cl::Hidden, cl::desc("Enable conversion of arithmetic operations to "
68   "predicate instructions"));
69 
70 static cl::opt<bool> DisableHSDR("disable-hsdr", cl::init(false), cl::Hidden,
71   cl::desc("Disable splitting double registers"));
72 
73 static cl::opt<bool> EnableBitSimplify("hexagon-bit", cl::init(true),
74   cl::Hidden, cl::desc("Bit simplification"));
75 
76 static cl::opt<bool> EnableLoopResched("hexagon-loop-resched", cl::init(true),
77   cl::Hidden, cl::desc("Loop rescheduling"));
78 
79 /// HexagonTargetMachineModule - Note that this is used on hosts that
80 /// cannot link in a library unless there are references into the
81 /// library.  In particular, it seems that it is not possible to get
82 /// things to work on Win32 without this.  Though it is unused, do not
83 /// remove it.
84 extern "C" int HexagonTargetMachineModule;
85 int HexagonTargetMachineModule = 0;
86 
87 extern "C" void LLVMInitializeHexagonTarget() {
88   // Register the target.
89   RegisterTargetMachine<HexagonTargetMachine> X(TheHexagonTarget);
90 }
91 
92 static ScheduleDAGInstrs *createVLIWMachineSched(MachineSchedContext *C) {
93   return new VLIWMachineScheduler(C, make_unique<ConvergingVLIWScheduler>());
94 }
95 
96 static MachineSchedRegistry
97 SchedCustomRegistry("hexagon", "Run Hexagon's custom scheduler",
98                     createVLIWMachineSched);
99 
100 namespace llvm {
101   FunctionPass *createHexagonBitSimplify();
102   FunctionPass *createHexagonBranchRelaxation();
103   FunctionPass *createHexagonCallFrameInformation();
104   FunctionPass *createHexagonCFGOptimizer();
105   FunctionPass *createHexagonCommonGEP();
106   FunctionPass *createHexagonCopyToCombine();
107   FunctionPass *createHexagonEarlyIfConversion();
108   FunctionPass *createHexagonExpandCondsets();
109   FunctionPass *createHexagonFixupHwLoops();
110   FunctionPass *createHexagonGenExtract();
111   FunctionPass *createHexagonGenInsert();
112   FunctionPass *createHexagonGenMux();
113   FunctionPass *createHexagonGenPredicate();
114   FunctionPass *createHexagonHardwareLoops();
115   FunctionPass *createHexagonISelDag(HexagonTargetMachine &TM,
116                                      CodeGenOpt::Level OptLevel);
117   FunctionPass *createHexagonLoopRescheduling();
118   FunctionPass *createHexagonNewValueJump();
119   FunctionPass *createHexagonOptimizeSZextends();
120   FunctionPass *createHexagonOptAddrMode();
121   FunctionPass *createHexagonPacketizer();
122   FunctionPass *createHexagonPeephole();
123   FunctionPass *createHexagonRDFOpt();
124   FunctionPass *createHexagonSplitConst32AndConst64();
125   FunctionPass *createHexagonSplitDoubleRegs();
126   FunctionPass *createHexagonStoreWidening();
127 } // end namespace llvm;
128 
129 
130 HexagonTargetMachine::HexagonTargetMachine(const Target &T, const Triple &TT,
131                                            StringRef CPU, StringRef FS,
132                                            const TargetOptions &Options,
133                                            Reloc::Model RM, CodeModel::Model CM,
134                                            CodeGenOpt::Level OL)
135     // Specify the vector alignment explicitly. For v512x1, the calculated
136     // alignment would be 512*alignment(i1), which is 512 bytes, instead of
137     // the required minimum of 64 bytes.
138     : LLVMTargetMachine(T, "e-m:e-p:32:32:32-a:0-n16:32-"
139          "i64:64:64-i32:32:32-i16:16:16-i1:8:8-f32:32:32-f64:64:64-"
140          "v32:32:32-v64:64:64-v512:512:512-v1024:1024:1024-v2048:2048:2048",
141          TT, CPU, FS, Options, RM, CM, OL),
142       TLOF(make_unique<HexagonTargetObjectFile>()) {
143   initAsmInfo();
144 }
145 
146 const HexagonSubtarget *
147 HexagonTargetMachine::getSubtargetImpl(const Function &F) const {
148   AttributeSet FnAttrs = F.getAttributes();
149   Attribute CPUAttr =
150       FnAttrs.getAttribute(AttributeSet::FunctionIndex, "target-cpu");
151   Attribute FSAttr =
152       FnAttrs.getAttribute(AttributeSet::FunctionIndex, "target-features");
153 
154   std::string CPU = !CPUAttr.hasAttribute(Attribute::None)
155                         ? CPUAttr.getValueAsString().str()
156                         : TargetCPU;
157   std::string FS = !FSAttr.hasAttribute(Attribute::None)
158                        ? FSAttr.getValueAsString().str()
159                        : TargetFS;
160 
161   auto &I = SubtargetMap[CPU + FS];
162   if (!I) {
163     // This needs to be done before we create a new subtarget since any
164     // creation will depend on the TM and the code generation flags on the
165     // function that reside in TargetOptions.
166     resetTargetOptions(F);
167     I = llvm::make_unique<HexagonSubtarget>(TargetTriple, CPU, FS, *this);
168   }
169   return I.get();
170 }
171 
172 TargetIRAnalysis HexagonTargetMachine::getTargetIRAnalysis() {
173   return TargetIRAnalysis([this](const Function &F) {
174     return TargetTransformInfo(HexagonTTIImpl(this, F));
175   });
176 }
177 
178 
179 HexagonTargetMachine::~HexagonTargetMachine() {}
180 
181 namespace {
182 /// Hexagon Code Generator Pass Configuration Options.
183 class HexagonPassConfig : public TargetPassConfig {
184 public:
185   HexagonPassConfig(HexagonTargetMachine *TM, PassManagerBase &PM)
186     : TargetPassConfig(TM, PM) {
187     bool NoOpt = (TM->getOptLevel() == CodeGenOpt::None);
188     if (!NoOpt) {
189       if (EnableExpandCondsets) {
190         Pass *Exp = createHexagonExpandCondsets();
191         insertPass(&RegisterCoalescerID, IdentifyingPassPtr(Exp));
192       }
193     }
194   }
195 
196   HexagonTargetMachine &getHexagonTargetMachine() const {
197     return getTM<HexagonTargetMachine>();
198   }
199 
200   ScheduleDAGInstrs *
201   createMachineScheduler(MachineSchedContext *C) const override {
202     return createVLIWMachineSched(C);
203   }
204 
205   void addIRPasses() override;
206   bool addInstSelector() override;
207   void addPreRegAlloc() override;
208   void addPostRegAlloc() override;
209   void addPreSched2() override;
210   void addPreEmitPass() override;
211 };
212 } // namespace
213 
214 TargetPassConfig *HexagonTargetMachine::createPassConfig(PassManagerBase &PM) {
215   return new HexagonPassConfig(this, PM);
216 }
217 
218 void HexagonPassConfig::addIRPasses() {
219   TargetPassConfig::addIRPasses();
220   bool NoOpt = (getOptLevel() == CodeGenOpt::None);
221 
222   addPass(createAtomicExpandPass(TM));
223   if (!NoOpt) {
224     if (EnableCommGEP)
225       addPass(createHexagonCommonGEP());
226     // Replace certain combinations of shifts and ands with extracts.
227     if (EnableGenExtract)
228       addPass(createHexagonGenExtract());
229   }
230 }
231 
232 bool HexagonPassConfig::addInstSelector() {
233   HexagonTargetMachine &TM = getHexagonTargetMachine();
234   bool NoOpt = (getOptLevel() == CodeGenOpt::None);
235 
236   if (!NoOpt)
237     addPass(createHexagonOptimizeSZextends());
238 
239   addPass(createHexagonISelDag(TM, getOptLevel()));
240 
241   if (!NoOpt) {
242     // Create logical operations on predicate registers.
243     if (EnableGenPred)
244       addPass(createHexagonGenPredicate(), false);
245     // Rotate loops to expose bit-simplification opportunities.
246     if (EnableLoopResched)
247       addPass(createHexagonLoopRescheduling(), false);
248     // Split double registers.
249     if (!DisableHSDR)
250       addPass(createHexagonSplitDoubleRegs());
251     // Bit simplification.
252     if (EnableBitSimplify)
253       addPass(createHexagonBitSimplify(), false);
254     addPass(createHexagonPeephole());
255     printAndVerify("After hexagon peephole pass");
256     if (EnableGenInsert)
257       addPass(createHexagonGenInsert(), false);
258     if (EnableEarlyIf)
259       addPass(createHexagonEarlyIfConversion(), false);
260   }
261 
262   return false;
263 }
264 
265 void HexagonPassConfig::addPreRegAlloc() {
266   if (getOptLevel() != CodeGenOpt::None) {
267     if (!DisableStoreWidening)
268       addPass(createHexagonStoreWidening(), false);
269     if (!DisableHardwareLoops)
270       addPass(createHexagonHardwareLoops(), false);
271   }
272 }
273 
274 void HexagonPassConfig::addPostRegAlloc() {
275   if (getOptLevel() != CodeGenOpt::None) {
276     if (EnableRDFOpt)
277       addPass(createHexagonRDFOpt());
278     if (!DisableHexagonCFGOpt)
279       addPass(createHexagonCFGOptimizer(), false);
280     if (!DisableAModeOpt)
281       addPass(createHexagonOptAddrMode(), false);
282   }
283 }
284 
285 void HexagonPassConfig::addPreSched2() {
286   addPass(createHexagonCopyToCombine(), false);
287   if (getOptLevel() != CodeGenOpt::None)
288     addPass(&IfConverterID, false);
289   addPass(createHexagonSplitConst32AndConst64());
290 }
291 
292 void HexagonPassConfig::addPreEmitPass() {
293   bool NoOpt = (getOptLevel() == CodeGenOpt::None);
294 
295   if (!NoOpt)
296     addPass(createHexagonNewValueJump(), false);
297 
298   addPass(createHexagonBranchRelaxation(), false);
299 
300   // Create Packets.
301   if (!NoOpt) {
302     if (!DisableHardwareLoops)
303       addPass(createHexagonFixupHwLoops(), false);
304     // Generate MUX from pairs of conditional transfers.
305     if (EnableGenMux)
306       addPass(createHexagonGenMux(), false);
307 
308     addPass(createHexagonPacketizer(), false);
309   }
310 
311   // Add CFI instructions if necessary.
312   addPass(createHexagonCallFrameInformation(), false);
313 }
314