1 //===- TargetSubtargetInfo.cpp - General Target Information ----------------==//
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 /// \file This file describes the general parts of a Subtarget.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "llvm/Target/TargetSubtargetInfo.h"
15 #include "llvm/ADT/Optional.h"
16 #include "llvm/CodeGen/MachineInstr.h"
17 #include "llvm/CodeGen/TargetSchedule.h"
18 #include "llvm/MC/MCInst.h"
19 #include "llvm/Support/Format.h"
20 #include "llvm/Support/raw_ostream.h"
21 #include "llvm/Target/TargetInstrInfo.h"
22 #include <string>
23 
24 using namespace llvm;
25 
26 TargetSubtargetInfo::TargetSubtargetInfo(
27     const Triple &TT, StringRef CPU, StringRef FS,
28     ArrayRef<SubtargetFeatureKV> PF, ArrayRef<SubtargetFeatureKV> PD,
29     const SubtargetInfoKV *ProcSched, const MCWriteProcResEntry *WPR,
30     const MCWriteLatencyEntry *WL, const MCReadAdvanceEntry *RA,
31     const InstrStage *IS, const unsigned *OC, const unsigned *FP)
32     : MCSubtargetInfo(TT, CPU, FS, PF, PD, ProcSched, WPR, WL, RA, IS, OC, FP) {
33 }
34 
35 TargetSubtargetInfo::~TargetSubtargetInfo() = default;
36 
37 bool TargetSubtargetInfo::enableAtomicExpand() const {
38   return true;
39 }
40 
41 bool TargetSubtargetInfo::enableMachineScheduler() const {
42   return false;
43 }
44 
45 bool TargetSubtargetInfo::enableJoinGlobalCopies() const {
46   return enableMachineScheduler();
47 }
48 
49 bool TargetSubtargetInfo::enableRALocalReassignment(
50     CodeGenOpt::Level OptLevel) const {
51   return true;
52 }
53 
54 bool TargetSubtargetInfo::enablePostRAScheduler() const {
55   return getSchedModel().PostRAScheduler;
56 }
57 
58 bool TargetSubtargetInfo::useAA() const {
59   return false;
60 }
61 
62 static std::string createSchedInfoStr(unsigned Latency,
63                                      Optional<double> RThroughput) {
64   static const char *SchedPrefix = " sched: [";
65   std::string Comment;
66   raw_string_ostream CS(Comment);
67   if (Latency > 0 && RThroughput.hasValue())
68     CS << SchedPrefix << Latency << format(":%2.2f", RThroughput.getValue())
69        << "]";
70   else if (Latency > 0)
71     CS << SchedPrefix << Latency << ":?]";
72   else if (RThroughput.hasValue())
73     CS << SchedPrefix << "?:" << RThroughput.getValue() << "]";
74   CS.flush();
75   return Comment;
76 }
77 
78 /// Returns string representation of scheduler comment
79 std::string TargetSubtargetInfo::getSchedInfoStr(const MachineInstr &MI) const {
80   if (MI.isPseudo() || MI.isTerminator())
81     return std::string();
82   // We don't cache TSchedModel because it depends on TargetInstrInfo
83   // that could be changed during the compilation
84   TargetSchedModel TSchedModel;
85   TSchedModel.init(getSchedModel(), this, getInstrInfo());
86   unsigned Latency = TSchedModel.computeInstrLatency(&MI);
87   Optional<double> RThroughput = TSchedModel.computeInstrRThroughput(&MI);
88   return createSchedInfoStr(Latency, RThroughput);
89 }
90 
91 /// Returns string representation of scheduler comment
92 std::string TargetSubtargetInfo::getSchedInfoStr(MCInst const &MCI) const {
93   // We don't cache TSchedModel because it depends on TargetInstrInfo
94   // that could be changed during the compilation
95   TargetSchedModel TSchedModel;
96   TSchedModel.init(getSchedModel(), this, getInstrInfo());
97   unsigned Latency;
98   if (TSchedModel.hasInstrSchedModel())
99     Latency = TSchedModel.computeInstrLatency(MCI.getOpcode());
100   else if (TSchedModel.hasInstrItineraries()) {
101     auto *ItinData = TSchedModel.getInstrItineraries();
102     Latency = ItinData->getStageLatency(
103         getInstrInfo()->get(MCI.getOpcode()).getSchedClass());
104   } else
105     return std::string();
106   Optional<double> RThroughput =
107       TSchedModel.computeInstrRThroughput(MCI.getOpcode());
108   return createSchedInfoStr(Latency, RThroughput);
109 }
110