1edd7eaddSDimitry Andric //===- TargetSubtargetInfo.cpp - General Target Information ----------------==//
2d88c1a5aSDimitry Andric //
3d88c1a5aSDimitry Andric //                     The LLVM Compiler Infrastructure
4d88c1a5aSDimitry Andric //
5d88c1a5aSDimitry Andric // This file is distributed under the University of Illinois Open Source
6d88c1a5aSDimitry Andric // License. See LICENSE.TXT for details.
7d88c1a5aSDimitry Andric //
8d88c1a5aSDimitry Andric //===----------------------------------------------------------------------===//
9d88c1a5aSDimitry Andric //
10d88c1a5aSDimitry Andric /// \file This file describes the general parts of a Subtarget.
11d88c1a5aSDimitry Andric //
12d88c1a5aSDimitry Andric //===----------------------------------------------------------------------===//
13d88c1a5aSDimitry Andric 
142cab237bSDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h"
15edd7eaddSDimitry Andric #include "llvm/ADT/Optional.h"
167a7e6055SDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
172cab237bSDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h"
187a7e6055SDimitry Andric #include "llvm/CodeGen/TargetSchedule.h"
19edd7eaddSDimitry Andric #include "llvm/MC/MCInst.h"
20edd7eaddSDimitry Andric #include "llvm/Support/Format.h"
217a7e6055SDimitry Andric #include "llvm/Support/raw_ostream.h"
22edd7eaddSDimitry Andric #include <string>
23edd7eaddSDimitry Andric 
24d88c1a5aSDimitry Andric using namespace llvm;
25d88c1a5aSDimitry Andric 
TargetSubtargetInfo(const Triple & TT,StringRef CPU,StringRef FS,ArrayRef<SubtargetFeatureKV> PF,ArrayRef<SubtargetFeatureKV> PD,const SubtargetInfoKV * ProcSched,const MCWriteProcResEntry * WPR,const MCWriteLatencyEntry * WL,const MCReadAdvanceEntry * RA,const InstrStage * IS,const unsigned * OC,const unsigned * FP)26d88c1a5aSDimitry Andric TargetSubtargetInfo::TargetSubtargetInfo(
27d88c1a5aSDimitry Andric     const Triple &TT, StringRef CPU, StringRef FS,
28d88c1a5aSDimitry Andric     ArrayRef<SubtargetFeatureKV> PF, ArrayRef<SubtargetFeatureKV> PD,
29d88c1a5aSDimitry Andric     const SubtargetInfoKV *ProcSched, const MCWriteProcResEntry *WPR,
30d88c1a5aSDimitry Andric     const MCWriteLatencyEntry *WL, const MCReadAdvanceEntry *RA,
31d88c1a5aSDimitry Andric     const InstrStage *IS, const unsigned *OC, const unsigned *FP)
32d88c1a5aSDimitry Andric     : MCSubtargetInfo(TT, CPU, FS, PF, PD, ProcSched, WPR, WL, RA, IS, OC, FP) {
33d88c1a5aSDimitry Andric }
34d88c1a5aSDimitry Andric 
35edd7eaddSDimitry Andric TargetSubtargetInfo::~TargetSubtargetInfo() = default;
36d88c1a5aSDimitry Andric 
enableAtomicExpand() const37d88c1a5aSDimitry Andric bool TargetSubtargetInfo::enableAtomicExpand() const {
38d88c1a5aSDimitry Andric   return true;
39d88c1a5aSDimitry Andric }
40d88c1a5aSDimitry Andric 
enableIndirectBrExpand() const4107577dfeSDimitry Andric bool TargetSubtargetInfo::enableIndirectBrExpand() const {
4207577dfeSDimitry Andric   return false;
4307577dfeSDimitry Andric }
4407577dfeSDimitry Andric 
enableMachineScheduler() const45d88c1a5aSDimitry Andric bool TargetSubtargetInfo::enableMachineScheduler() const {
46d88c1a5aSDimitry Andric   return false;
47d88c1a5aSDimitry Andric }
48d88c1a5aSDimitry Andric 
enableJoinGlobalCopies() const49d88c1a5aSDimitry Andric bool TargetSubtargetInfo::enableJoinGlobalCopies() const {
50d88c1a5aSDimitry Andric   return enableMachineScheduler();
51d88c1a5aSDimitry Andric }
52d88c1a5aSDimitry Andric 
enableRALocalReassignment(CodeGenOpt::Level OptLevel) const53d88c1a5aSDimitry Andric bool TargetSubtargetInfo::enableRALocalReassignment(
54d88c1a5aSDimitry Andric     CodeGenOpt::Level OptLevel) const {
55d88c1a5aSDimitry Andric   return true;
56d88c1a5aSDimitry Andric }
57d88c1a5aSDimitry Andric 
enableAdvancedRASplitCost() const582cab237bSDimitry Andric bool TargetSubtargetInfo::enableAdvancedRASplitCost() const {
592cab237bSDimitry Andric   return false;
602cab237bSDimitry Andric }
612cab237bSDimitry Andric 
enablePostRAScheduler() const62d88c1a5aSDimitry Andric bool TargetSubtargetInfo::enablePostRAScheduler() const {
63d88c1a5aSDimitry Andric   return getSchedModel().PostRAScheduler;
64d88c1a5aSDimitry Andric }
65d88c1a5aSDimitry Andric 
useAA() const66d88c1a5aSDimitry Andric bool TargetSubtargetInfo::useAA() const {
67d88c1a5aSDimitry Andric   return false;
68d88c1a5aSDimitry Andric }
697a7e6055SDimitry Andric 
createSchedInfoStr(unsigned Latency,double RThroughput)70*4ba319b5SDimitry Andric static std::string createSchedInfoStr(unsigned Latency, double RThroughput) {
717a7e6055SDimitry Andric   static const char *SchedPrefix = " sched: [";
727a7e6055SDimitry Andric   std::string Comment;
737a7e6055SDimitry Andric   raw_string_ostream CS(Comment);
74*4ba319b5SDimitry Andric   if (RThroughput != 0.0)
75*4ba319b5SDimitry Andric     CS << SchedPrefix << Latency << format(":%2.2f", RThroughput)
767a7e6055SDimitry Andric        << "]";
77*4ba319b5SDimitry Andric   else
787a7e6055SDimitry Andric     CS << SchedPrefix << Latency << ":?]";
797a7e6055SDimitry Andric   CS.flush();
807a7e6055SDimitry Andric   return Comment;
817a7e6055SDimitry Andric }
827a7e6055SDimitry Andric 
837a7e6055SDimitry Andric /// Returns string representation of scheduler comment
getSchedInfoStr(const MachineInstr & MI) const847a7e6055SDimitry Andric std::string TargetSubtargetInfo::getSchedInfoStr(const MachineInstr &MI) const {
857a7e6055SDimitry Andric   if (MI.isPseudo() || MI.isTerminator())
867a7e6055SDimitry Andric     return std::string();
877a7e6055SDimitry Andric   // We don't cache TSchedModel because it depends on TargetInstrInfo
887a7e6055SDimitry Andric   // that could be changed during the compilation
897a7e6055SDimitry Andric   TargetSchedModel TSchedModel;
90*4ba319b5SDimitry Andric   TSchedModel.init(this);
917a7e6055SDimitry Andric   unsigned Latency = TSchedModel.computeInstrLatency(&MI);
92*4ba319b5SDimitry Andric   double RThroughput = TSchedModel.computeReciprocalThroughput(&MI);
937a7e6055SDimitry Andric   return createSchedInfoStr(Latency, RThroughput);
947a7e6055SDimitry Andric }
957a7e6055SDimitry Andric 
967a7e6055SDimitry Andric /// Returns string representation of scheduler comment
getSchedInfoStr(MCInst const & MCI) const977a7e6055SDimitry Andric std::string TargetSubtargetInfo::getSchedInfoStr(MCInst const &MCI) const {
987a7e6055SDimitry Andric   // We don't cache TSchedModel because it depends on TargetInstrInfo
997a7e6055SDimitry Andric   // that could be changed during the compilation
1007a7e6055SDimitry Andric   TargetSchedModel TSchedModel;
101*4ba319b5SDimitry Andric   TSchedModel.init(this);
1022cab237bSDimitry Andric   unsigned Latency;
1032cab237bSDimitry Andric   if (TSchedModel.hasInstrSchedModel())
104*4ba319b5SDimitry Andric     Latency = TSchedModel.computeInstrLatency(MCI);
1052cab237bSDimitry Andric   else if (TSchedModel.hasInstrItineraries()) {
1062cab237bSDimitry Andric     auto *ItinData = TSchedModel.getInstrItineraries();
1072cab237bSDimitry Andric     Latency = ItinData->getStageLatency(
1082cab237bSDimitry Andric         getInstrInfo()->get(MCI.getOpcode()).getSchedClass());
1092cab237bSDimitry Andric   } else
1107a7e6055SDimitry Andric     return std::string();
111*4ba319b5SDimitry Andric   double RThroughput = TSchedModel.computeReciprocalThroughput(MCI);
1127a7e6055SDimitry Andric   return createSchedInfoStr(Latency, RThroughput);
1137a7e6055SDimitry Andric }
114*4ba319b5SDimitry Andric 
mirFileLoaded(MachineFunction & MF) const115*4ba319b5SDimitry Andric void TargetSubtargetInfo::mirFileLoaded(MachineFunction &MF) const {
116*4ba319b5SDimitry Andric }
117