brintos

brintos / llvm-project-archived public Read only

0
0
Text · 17.4 KiB · d9824a3 Raw
468 lines · cpp
1//===-- HexagonTargetMachine.cpp - Define TargetMachine for Hexagon -------===//2//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-exception6//7//===----------------------------------------------------------------------===//8//9// Implements the info about Hexagon target spec.10//11//===----------------------------------------------------------------------===//12 13#include "HexagonTargetMachine.h"14#include "Hexagon.h"15#include "HexagonISelLowering.h"16#include "HexagonLoopIdiomRecognition.h"17#include "HexagonMachineFunctionInfo.h"18#include "HexagonMachineScheduler.h"19#include "HexagonTargetObjectFile.h"20#include "HexagonTargetTransformInfo.h"21#include "HexagonVectorLoopCarriedReuse.h"22#include "TargetInfo/HexagonTargetInfo.h"23#include "llvm/CodeGen/Passes.h"24#include "llvm/CodeGen/TargetPassConfig.h"25#include "llvm/CodeGen/VLIWMachineScheduler.h"26#include "llvm/MC/TargetRegistry.h"27#include "llvm/Passes/PassBuilder.h"28#include "llvm/Support/CommandLine.h"29#include "llvm/Support/Compiler.h"30#include "llvm/Transforms/Scalar.h"31#include <optional>32 33using namespace llvm;34 35static cl::opt<bool>36    EnableCExtOpt("hexagon-cext", cl::Hidden, cl::init(true),37                  cl::desc("Enable Hexagon constant-extender optimization"));38 39static cl::opt<bool> EnableRDFOpt("rdf-opt", cl::Hidden, cl::init(true),40                                  cl::desc("Enable RDF-based optimizations"));41 42cl::opt<unsigned> RDFFuncBlockLimit(43    "rdf-bb-limit", cl::Hidden, cl::init(1000),44    cl::desc("Basic block limit for a function for RDF optimizations"));45 46static cl::opt<bool>47    DisableHardwareLoops("disable-hexagon-hwloops", cl::Hidden,48                         cl::desc("Disable Hardware Loops for Hexagon target"));49 50static cl::opt<bool>51    DisableAModeOpt("disable-hexagon-amodeopt", cl::Hidden,52                    cl::desc("Disable Hexagon Addressing Mode Optimization"));53 54static cl::opt<bool>55    DisableHexagonCFGOpt("disable-hexagon-cfgopt", cl::Hidden,56                         cl::desc("Disable Hexagon CFG Optimization"));57 58static cl::opt<bool>59    DisableHCP("disable-hcp", cl::Hidden,60               cl::desc("Disable Hexagon constant propagation"));61 62static cl::opt<bool> DisableHexagonMask(63    "disable-mask", cl::Hidden,64    cl::desc("Disable Hexagon specific Mask generation pass"));65 66static cl::opt<bool> DisableStoreWidening("disable-store-widen", cl::Hidden,67                                          cl::init(false),68                                          cl::desc("Disable store widening"));69 70static cl::opt<bool> DisableLoadWidening("disable-load-widen", cl::Hidden,71                                         cl::desc("Disable load widening"));72 73static cl::opt<bool> EnableExpandCondsets("hexagon-expand-condsets",74                                          cl::init(true), cl::Hidden,75                                          cl::desc("Early expansion of MUX"));76 77static cl::opt<bool> EnableTfrCleanup("hexagon-tfr-cleanup", cl::init(true),78                                      cl::Hidden,79                                      cl::desc("Cleanup of TFRs/COPYs"));80 81static cl::opt<bool> EnableEarlyIf("hexagon-eif", cl::init(true), cl::Hidden,82                                   cl::desc("Enable early if-conversion"));83 84static cl::opt<bool> EnableCopyHoist("hexagon-copy-hoist", cl::init(true),85                                     cl::Hidden, cl::ZeroOrMore,86                                     cl::desc("Enable Hexagon copy hoisting"));87 88static cl::opt<bool>89    EnableGenInsert("hexagon-insert", cl::init(true), cl::Hidden,90                    cl::desc("Generate \"insert\" instructions"));91 92static cl::opt<bool>93    EnableCommGEP("hexagon-commgep", cl::init(true), cl::Hidden,94                  cl::desc("Enable commoning of GEP instructions"));95 96static cl::opt<bool>97    EnableGenExtract("hexagon-extract", cl::init(true), cl::Hidden,98                     cl::desc("Generate \"extract\" instructions"));99 100static cl::opt<bool> EnableGenMux(101    "hexagon-mux", cl::init(true), cl::Hidden,102    cl::desc("Enable converting conditional transfers into MUX instructions"));103 104static cl::opt<bool>105    EnableGenPred("hexagon-gen-pred", cl::init(true), cl::Hidden,106                  cl::desc("Enable conversion of arithmetic operations to "107                           "predicate instructions"));108 109static cl::opt<bool>110    EnableLoopPrefetch("hexagon-loop-prefetch", cl::Hidden,111                       cl::desc("Enable loop data prefetch on Hexagon"));112 113static cl::opt<bool>114    DisableHSDR("disable-hsdr", cl::init(false), cl::Hidden,115                cl::desc("Disable splitting double registers"));116 117static cl::opt<bool>118    EnableGenMemAbs("hexagon-mem-abs", cl::init(true), cl::Hidden,119                    cl::desc("Generate absolute set instructions"));120 121static cl::opt<bool> EnableBitSimplify("hexagon-bit", cl::init(true),122                                       cl::Hidden,123                                       cl::desc("Bit simplification"));124 125static cl::opt<bool> EnableLoopResched("hexagon-loop-resched", cl::init(true),126                                       cl::Hidden,127                                       cl::desc("Loop rescheduling"));128 129static cl::opt<bool> HexagonNoOpt("hexagon-noopt", cl::init(false), cl::Hidden,130                                  cl::desc("Disable backend optimizations"));131 132static cl::opt<bool>133    EnableVectorPrint("enable-hexagon-vector-print", cl::Hidden,134                      cl::desc("Enable Hexagon Vector print instr pass"));135 136static cl::opt<bool>137    EnableVExtractOpt("hexagon-opt-vextract", cl::Hidden, cl::init(true),138                      cl::desc("Enable vextract optimization"));139 140static cl::opt<bool>141    EnableVectorCombine("hexagon-vector-combine", cl::Hidden, cl::init(true),142                        cl::desc("Enable HVX vector combining"));143 144static cl::opt<bool> EnableInitialCFGCleanup(145    "hexagon-initial-cfg-cleanup", cl::Hidden, cl::init(true),146    cl::desc("Simplify the CFG after atomic expansion pass"));147 148static cl::opt<bool> EnableInstSimplify("hexagon-instsimplify", cl::Hidden,149                                        cl::init(true),150                                        cl::desc("Enable instsimplify"));151 152/// HexagonTargetMachineModule - Note that this is used on hosts that153/// cannot link in a library unless there are references into the154/// library.  In particular, it seems that it is not possible to get155/// things to work on Win32 without this.  Though it is unused, do not156/// remove it.157extern "C" int HexagonTargetMachineModule;158int HexagonTargetMachineModule = 0;159 160static ScheduleDAGInstrs *createVLIWMachineSched(MachineSchedContext *C) {161  ScheduleDAGMILive *DAG = new VLIWMachineScheduler(162      C, std::make_unique<HexagonConvergingVLIWScheduler>());163  DAG->addMutation(std::make_unique<HexagonSubtarget::UsrOverflowMutation>());164  DAG->addMutation(std::make_unique<HexagonSubtarget::HVXMemLatencyMutation>());165  DAG->addMutation(std::make_unique<HexagonSubtarget::CallMutation>());166  DAG->addMutation(createCopyConstrainDAGMutation(DAG->TII, DAG->TRI));167  return DAG;168}169 170static MachineSchedRegistry171    SchedCustomRegistry("hexagon", "Run Hexagon's custom scheduler",172                        createVLIWMachineSched);173 174static Reloc::Model getEffectiveRelocModel(std::optional<Reloc::Model> RM) {175  return RM.value_or(Reloc::Static);176}177 178extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void179LLVMInitializeHexagonTarget() {180  // Register the target.181  RegisterTargetMachine<HexagonTargetMachine> X(getTheHexagonTarget());182 183  PassRegistry &PR = *PassRegistry::getPassRegistry();184  initializeHexagonAsmPrinterPass(PR);185  initializeHexagonBitSimplifyPass(PR);186  initializeHexagonConstExtendersPass(PR);187  initializeHexagonConstPropagationPass(PR);188  initializeHexagonCopyToCombinePass(PR);189  initializeHexagonEarlyIfConversionPass(PR);190  initializeHexagonGenMemAbsolutePass(PR);191  initializeHexagonGenMuxPass(PR);192  initializeHexagonHardwareLoopsPass(PR);193  initializeHexagonLoopIdiomRecognizeLegacyPassPass(PR);194  initializeHexagonNewValueJumpPass(PR);195  initializeHexagonOptAddrModePass(PR);196  initializeHexagonPacketizerPass(PR);197  initializeHexagonRDFOptPass(PR);198  initializeHexagonSplitDoubleRegsPass(PR);199  initializeHexagonVectorCombineLegacyPass(PR);200  initializeHexagonVectorLoopCarriedReuseLegacyPassPass(PR);201  initializeHexagonVExtractPass(PR);202  initializeHexagonDAGToDAGISelLegacyPass(PR);203  initializeHexagonLoopReschedulingPass(PR);204  initializeHexagonBranchRelaxationPass(PR);205  initializeHexagonCFGOptimizerPass(PR);206  initializeHexagonCommonGEPPass(PR);207  initializeHexagonCopyHoistingPass(PR);208  initializeHexagonExpandCondsetsPass(PR);209  initializeHexagonLoopAlignPass(PR);210  initializeHexagonTfrCleanupPass(PR);211  initializeHexagonFixupHwLoopsPass(PR);212  initializeHexagonCallFrameInformationPass(PR);213  initializeHexagonGenExtractPass(PR);214  initializeHexagonGenInsertPass(PR);215  initializeHexagonGenPredicatePass(PR);216  initializeHexagonLoadWideningPass(PR);217  initializeHexagonStoreWideningPass(PR);218  initializeHexagonMaskPass(PR);219  initializeHexagonOptimizeSZextendsPass(PR);220  initializeHexagonPeepholePass(PR);221  initializeHexagonSplitConst32AndConst64Pass(PR);222  initializeHexagonVectorPrintPass(PR);223  initializeHexagonQFPOptimizerPass(PR);224}225 226HexagonTargetMachine::HexagonTargetMachine(const Target &T, const Triple &TT,227                                           StringRef CPU, StringRef FS,228                                           const TargetOptions &Options,229                                           std::optional<Reloc::Model> RM,230                                           std::optional<CodeModel::Model> CM,231                                           CodeGenOptLevel OL, bool JIT)232    // Specify the vector alignment explicitly. For v512x1, the calculated233    // alignment would be 512*alignment(i1), which is 512 bytes, instead of234    // the required minimum of 64 bytes.235    : CodeGenTargetMachineImpl(T, TT.computeDataLayout(), TT, CPU, FS, Options,236                               getEffectiveRelocModel(RM),237                               getEffectiveCodeModel(CM, CodeModel::Small),238                               (HexagonNoOpt ? CodeGenOptLevel::None : OL)),239      TLOF(std::make_unique<HexagonTargetObjectFile>()),240      Subtarget(Triple(TT), CPU, FS, *this) {241  initAsmInfo();242}243 244const HexagonSubtarget *245HexagonTargetMachine::getSubtargetImpl(const Function &F) const {246  AttributeList FnAttrs = F.getAttributes();247  Attribute CPUAttr = FnAttrs.getFnAttr("target-cpu");248  Attribute FSAttr = FnAttrs.getFnAttr("target-features");249 250  std::string CPU =251      CPUAttr.isValid() ? CPUAttr.getValueAsString().str() : TargetCPU;252  std::string FS =253      FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS;254 255  auto &I = SubtargetMap[CPU + FS];256  if (!I) {257    // This needs to be done before we create a new subtarget since any258    // creation will depend on the TM and the code generation flags on the259    // function that reside in TargetOptions.260    resetTargetOptions(F);261    I = std::make_unique<HexagonSubtarget>(TargetTriple, CPU, FS, *this);262  }263  return I.get();264}265 266void HexagonTargetMachine::registerPassBuilderCallbacks(PassBuilder &PB) {267#define GET_PASS_REGISTRY "HexagonPassRegistry.def"268#include "llvm/Passes/TargetPassRegistry.inc"269 270  PB.registerLateLoopOptimizationsEPCallback(271      [=](LoopPassManager &LPM, OptimizationLevel Level) {272        LPM.addPass(HexagonLoopIdiomRecognitionPass());273      });274  PB.registerLoopOptimizerEndEPCallback(275      [=](LoopPassManager &LPM, OptimizationLevel Level) {276        LPM.addPass(HexagonVectorLoopCarriedReusePass());277      });278}279 280TargetTransformInfo281HexagonTargetMachine::getTargetTransformInfo(const Function &F) const {282  return TargetTransformInfo(std::make_unique<HexagonTTIImpl>(this, F));283}284 285MachineFunctionInfo *HexagonTargetMachine::createMachineFunctionInfo(286    BumpPtrAllocator &Allocator, const Function &F,287    const TargetSubtargetInfo *STI) const {288  return HexagonMachineFunctionInfo::create<HexagonMachineFunctionInfo>(289      Allocator, F, STI);290}291 292HexagonTargetMachine::~HexagonTargetMachine() = default;293 294ScheduleDAGInstrs *295HexagonTargetMachine::createMachineScheduler(MachineSchedContext *C) const {296  return createVLIWMachineSched(C);297}298 299namespace {300/// Hexagon Code Generator Pass Configuration Options.301class HexagonPassConfig : public TargetPassConfig {302public:303  HexagonPassConfig(HexagonTargetMachine &TM, PassManagerBase &PM)304      : TargetPassConfig(TM, PM) {}305 306  HexagonTargetMachine &getHexagonTargetMachine() const {307    return getTM<HexagonTargetMachine>();308  }309 310  void addIRPasses() override;311  bool addInstSelector() override;312  void addPreRegAlloc() override;313  void addPostRegAlloc() override;314  void addPreSched2() override;315  void addPreEmitPass() override;316};317} // namespace318 319TargetPassConfig *HexagonTargetMachine::createPassConfig(PassManagerBase &PM) {320  return new HexagonPassConfig(*this, PM);321}322 323void HexagonPassConfig::addIRPasses() {324  TargetPassConfig::addIRPasses();325  bool NoOpt = (getOptLevel() == CodeGenOptLevel::None);326 327  if (!NoOpt) {328    if (EnableInstSimplify)329      addPass(createInstSimplifyLegacyPass());330    addPass(createDeadCodeEliminationPass());331  }332 333  addPass(createAtomicExpandLegacyPass());334 335  if (!NoOpt) {336    if (EnableInitialCFGCleanup)337      addPass(createCFGSimplificationPass(SimplifyCFGOptions()338                                              .forwardSwitchCondToPhi(true)339                                              .convertSwitchRangeToICmp(true)340                                              .convertSwitchToLookupTable(true)341                                              .needCanonicalLoops(false)342                                              .hoistCommonInsts(true)343                                              .sinkCommonInsts(true)));344    if (EnableLoopPrefetch)345      addPass(createLoopDataPrefetchPass());346    if (EnableVectorCombine)347      addPass(createHexagonVectorCombineLegacyPass());348    if (EnableCommGEP)349      addPass(createHexagonCommonGEP());350    // Replace certain combinations of shifts and ands with extracts.351    if (EnableGenExtract)352      addPass(createHexagonGenExtract());353  }354}355 356bool HexagonPassConfig::addInstSelector() {357  HexagonTargetMachine &TM = getHexagonTargetMachine();358  bool NoOpt = (getOptLevel() == CodeGenOptLevel::None);359 360  if (!NoOpt)361    addPass(createHexagonOptimizeSZextends());362 363  addPass(createHexagonISelDag(TM, getOptLevel()));364 365  if (!NoOpt) {366    if (EnableVExtractOpt)367      addPass(createHexagonVExtract());368    // Create logical operations on predicate registers.369    if (EnableGenPred)370      addPass(createHexagonGenPredicate());371    // Rotate loops to expose bit-simplification opportunities.372    if (EnableLoopResched)373      addPass(createHexagonLoopRescheduling());374    // Split double registers.375    if (!DisableHSDR)376      addPass(createHexagonSplitDoubleRegs());377    // Bit simplification.378    if (EnableBitSimplify)379      addPass(createHexagonBitSimplify());380    addPass(createHexagonPeephole());381    // Constant propagation.382    if (!DisableHCP) {383      addPass(createHexagonConstPropagationPass());384      addPass(&UnreachableMachineBlockElimID);385    }386    if (EnableGenInsert)387      addPass(createHexagonGenInsert());388    if (EnableEarlyIf)389      addPass(createHexagonEarlyIfConversion());390    addPass(createHexagonQFPOptimizer());391  }392 393  return false;394}395 396void HexagonPassConfig::addPreRegAlloc() {397  if (getOptLevel() != CodeGenOptLevel::None) {398    if (EnableCExtOpt)399      addPass(createHexagonConstExtenders());400    if (EnableExpandCondsets)401      insertPass(&RegisterCoalescerID, &HexagonExpandCondsetsID);402    if (EnableCopyHoist)403      insertPass(&RegisterCoalescerID, &HexagonCopyHoistingID);404    if (EnableTfrCleanup)405      insertPass(&VirtRegRewriterID, &HexagonTfrCleanupID);406    if (!DisableStoreWidening)407      addPass(createHexagonStoreWidening());408    if (!DisableLoadWidening)409      addPass(createHexagonLoadWidening());410    if (EnableGenMemAbs)411      addPass(createHexagonGenMemAbsolute());412    if (!DisableHardwareLoops)413      addPass(createHexagonHardwareLoops());414  }415  if (TM->getOptLevel() >= CodeGenOptLevel::Default)416    addPass(&MachinePipelinerID);417}418 419void HexagonPassConfig::addPostRegAlloc() {420  if (getOptLevel() != CodeGenOptLevel::None) {421    if (EnableRDFOpt)422      addPass(createHexagonRDFOpt());423    if (!DisableHexagonCFGOpt)424      addPass(createHexagonCFGOptimizer());425    if (!DisableAModeOpt)426      addPass(createHexagonOptAddrMode());427  }428}429 430void HexagonPassConfig::addPreSched2() {431  bool NoOpt = (getOptLevel() == CodeGenOptLevel::None);432  addPass(createHexagonCopyToCombine());433  if (getOptLevel() != CodeGenOptLevel::None)434    addPass(&IfConverterID);435  addPass(createHexagonSplitConst32AndConst64());436  if (!NoOpt && !DisableHexagonMask)437    addPass(createHexagonMask());438}439 440void HexagonPassConfig::addPreEmitPass() {441  bool NoOpt = (getOptLevel() == CodeGenOptLevel::None);442 443  if (!NoOpt)444    addPass(createHexagonNewValueJump());445 446  addPass(createHexagonBranchRelaxation());447 448  if (!NoOpt) {449    if (!DisableHardwareLoops)450      addPass(createHexagonFixupHwLoops());451    // Generate MUX from pairs of conditional transfers.452    if (EnableGenMux)453      addPass(createHexagonGenMux());454  }455 456  // Packetization is mandatory: it handles gather/scatter at all opt levels.457  addPass(createHexagonPacketizer(NoOpt));458 459  if (!NoOpt)460    addPass(createHexagonLoopAlign());461 462  if (EnableVectorPrint)463    addPass(createHexagonVectorPrint());464 465  // Add CFI instructions if necessary.466  addPass(createHexagonCallFrameInformation());467}468