brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.1 KiB · 85e022a Raw
270 lines · cpp
1//===-- PowerPCSubtarget.cpp - PPC Subtarget Information ------------------===//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// This file implements the PPC specific subclass of TargetSubtargetInfo.10//11//===----------------------------------------------------------------------===//12 13#include "PPCSubtarget.h"14#include "GISel/PPCCallLowering.h"15#include "GISel/PPCLegalizerInfo.h"16#include "GISel/PPCRegisterBankInfo.h"17#include "PPC.h"18#include "PPCRegisterInfo.h"19#include "PPCSelectionDAGInfo.h"20#include "PPCTargetMachine.h"21#include "llvm/CodeGen/GlobalISel/InstructionSelect.h"22#include "llvm/CodeGen/GlobalISel/InstructionSelector.h"23#include "llvm/CodeGen/MachineFunction.h"24#include "llvm/CodeGen/MachineScheduler.h"25#include "llvm/IR/GlobalAlias.h"26#include "llvm/IR/GlobalValue.h"27#include "llvm/IR/GlobalVariable.h"28#include "llvm/MC/TargetRegistry.h"29#include "llvm/Support/CommandLine.h"30#include "llvm/Target/TargetMachine.h"31#include "llvm/TargetParser/PPCTargetParser.h"32#include <cstdlib>33 34using namespace llvm;35 36#define DEBUG_TYPE "ppc-subtarget"37 38#define GET_SUBTARGETINFO_TARGET_DESC39#define GET_SUBTARGETINFO_CTOR40#include "PPCGenSubtargetInfo.inc"41 42static cl::opt<bool>43    EnableMachinePipeliner("ppc-enable-pipeliner",44                           cl::desc("Enable Machine Pipeliner for PPC"),45                           cl::init(false), cl::Hidden);46 47PPCSubtarget &PPCSubtarget::initializeSubtargetDependencies(StringRef CPU,48                                                            StringRef TuneCPU,49                                                            StringRef FS) {50  initializeEnvironment();51  initSubtargetFeatures(CPU, TuneCPU, FS);52  return *this;53}54 55PPCSubtarget::PPCSubtarget(const Triple &TT, StringRef CPU, StringRef TuneCPU,56                           StringRef FS, const PPCTargetMachine &TM)57    : PPCGenSubtargetInfo(TT, CPU, TuneCPU, FS), TM(TM),58      FrameLowering(initializeSubtargetDependencies(CPU, TuneCPU, FS)),59      InstrInfo(*this), TLInfo(TM, *this) {60  TSInfo = std::make_unique<PPCSelectionDAGInfo>();61 62  CallLoweringInfo.reset(new PPCCallLowering(*getTargetLowering()));63  Legalizer.reset(new PPCLegalizerInfo(*this));64  auto *RBI = new PPCRegisterBankInfo(*getRegisterInfo());65  RegBankInfo.reset(RBI);66 67  InstSelector.reset(createPPCInstructionSelector(TM, *this, *RBI));68}69 70PPCSubtarget::~PPCSubtarget() = default;71 72const SelectionDAGTargetInfo *PPCSubtarget::getSelectionDAGInfo() const {73  return TSInfo.get();74}75 76void PPCSubtarget::initializeEnvironment() {77  StackAlignment = Align(16);78  CPUDirective = PPC::DIR_NONE;79  HasPOPCNTD = POPCNTD_Unavailable;80}81 82void PPCSubtarget::initSubtargetFeatures(StringRef CPU, StringRef TuneCPU,83                                         StringRef FS) {84  // Determine default and user specified characteristics85  std::string CPUName = std::string(CPU);86  if (CPUName.empty() || CPU == "generic") {87    if (getTargetTriple().getSubArch() == Triple::PPCSubArch_spe)88      CPUName = "e500";89    else90      CPUName = std::string(PPC::getNormalizedPPCTargetCPU(getTargetTriple()));91  }92 93  // Determine the CPU to schedule for.94  if (TuneCPU.empty()) TuneCPU = CPUName;95 96  // Initialize scheduling itinerary for the specified CPU.97  InstrItins = getInstrItineraryForCPU(CPUName);98 99  // Parse features string.100  ParseSubtargetFeatures(CPUName, TuneCPU, FS);101 102  // If the user requested use of 64-bit regs, but the cpu selected doesn't103  // support it, ignore.104  if (IsPPC64 && has64BitSupport())105    Use64BitRegs = true;106 107  if (getTargetTriple().isPPC32SecurePlt())108    IsSecurePlt = true;109 110  if (HasSPE && IsPPC64)111    report_fatal_error( "SPE is only supported for 32-bit targets.\n", false);112  if (HasSPE && (HasAltivec || HasVSX || HasFPU))113    report_fatal_error(114        "SPE and traditional floating point cannot both be enabled.\n", false);115 116  // If not SPE, set standard FPU117  if (!HasSPE)118    HasFPU = true;119 120  StackAlignment = getPlatformStackAlignment();121 122  // Determine endianness.123  IsLittleEndian = TM.isLittleEndian();124 125  if (HasAIXSmallLocalExecTLS || HasAIXSmallLocalDynamicTLS) {126    if (!getTargetTriple().isOSAIX() || !IsPPC64)127      report_fatal_error("The aix-small-local-[exec|dynamic]-tls attribute is "128                         "only supported on AIX in "129                         "64-bit mode.\n",130                         false);131    // The aix-small-local-[exec|dynamic]-tls attribute should only be used with132    // -data-sections, as having data sections turned off with this option133    // is not ideal for performance. Moreover, the134    // small-local-[exec|dynamic]-tls region is a limited resource, and should135    // not be used for variables that may be replaced.136    if (!TM.getDataSections())137      report_fatal_error("The aix-small-local-[exec|dynamic]-tls attribute can "138                         "only be specified with "139                         "-data-sections.\n",140                         false);141  }142 143  if (HasAIXShLibTLSModelOpt && (!getTargetTriple().isOSAIX() || !IsPPC64))144    report_fatal_error("The aix-shared-lib-tls-model-opt attribute "145                       "is only supported on AIX in 64-bit mode.\n",146                       false);147}148 149bool PPCSubtarget::enableMachineScheduler() const { return true; }150 151bool PPCSubtarget::enableMachinePipeliner() const {152  return getSchedModel().hasInstrSchedModel() && EnableMachinePipeliner;153}154 155bool PPCSubtarget::useDFAforSMS() const { return false; }156 157// This overrides the PostRAScheduler bit in the SchedModel for each CPU.158bool PPCSubtarget::enablePostRAScheduler() const { return true; }159 160PPCGenSubtargetInfo::AntiDepBreakMode PPCSubtarget::getAntiDepBreakMode() const {161  return TargetSubtargetInfo::ANTIDEP_ALL;162}163 164void PPCSubtarget::getCriticalPathRCs(RegClassVector &CriticalPathRCs) const {165  CriticalPathRCs.clear();166  CriticalPathRCs.push_back(isPPC64() ?167                            &PPC::G8RCRegClass : &PPC::GPRCRegClass);168}169 170void PPCSubtarget::overrideSchedPolicy(MachineSchedPolicy &Policy,171                                       const SchedRegion &Region) const {172  // The GenericScheduler that we use defaults to scheduling bottom up only.173  // We want to schedule from both the top and the bottom and so we set174  // OnlyBottomUp to false.175  // We want to do bi-directional scheduling since it provides a more balanced176  // schedule leading to better performance.177  Policy.OnlyBottomUp = false;178  // Spilling is generally expensive on all PPC cores, so always enable179  // register-pressure tracking.180  Policy.ShouldTrackPressure = true;181}182 183bool PPCSubtarget::useAA() const {184  return true;185}186 187bool PPCSubtarget::enableSubRegLiveness() const { return true; }188 189bool PPCSubtarget::isGVIndirectSymbol(const GlobalValue *GV) const {190  if (isAIXABI()) {191    if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV))192      // On AIX the only symbols that aren't indirect are toc-data.193      return !GVar->hasAttribute("toc-data");194 195    return true;196  }197 198  // Large code model always uses the TOC even for local symbols.199  if (TM.getCodeModel() == CodeModel::Large)200    return true;201 202  if (TM.shouldAssumeDSOLocal(GV))203    return false;204  return true;205}206 207CodeModel::Model PPCSubtarget::getCodeModel(const TargetMachine &TM,208                                            const GlobalValue *GV) const {209  // If there isn't an attribute to override the module code model210  // this will be the effective code model.211  CodeModel::Model ModuleModel = TM.getCodeModel();212 213  // Initially support per global code model for AIX only.214  if (!isAIXABI())215    return ModuleModel;216 217  // Only GlobalVariables carry an attribute which can override the module code218  // model.219  assert(GV && "Unexpected NULL GlobalValue");220  const GlobalVariable *GlobalVar =221      [](const GlobalValue *GV) -> const GlobalVariable * {222    const GlobalVariable *Var = dyn_cast<GlobalVariable>(GV);223    if (Var)224      return Var;225 226    const GlobalAlias *Alias = dyn_cast<GlobalAlias>(GV);227    if (Alias)228      return dyn_cast<GlobalVariable>(Alias->getAliaseeObject());229 230    return nullptr;231  }(GV);232 233  if (!GlobalVar)234    return ModuleModel;235 236  std::optional<CodeModel::Model> MaybeCodeModel = GlobalVar->getCodeModel();237  if (MaybeCodeModel) {238    CodeModel::Model CM = *MaybeCodeModel;239    assert((CM == CodeModel::Small || CM == CodeModel::Large) &&240           "invalid code model for AIX");241    return CM;242  }243 244  return ModuleModel;245}246 247bool PPCSubtarget::isELFv2ABI() const { return TM.isELFv2ABI(); }248 249bool PPCSubtarget::isUsingPCRelativeCalls() const {250  return isPPC64() && hasPCRelativeMemops() && isELFv2ABI() &&251         CodeModel::Medium == getTargetMachine().getCodeModel();252}253 254// GlobalISEL255const CallLowering *PPCSubtarget::getCallLowering() const {256  return CallLoweringInfo.get();257}258 259const RegisterBankInfo *PPCSubtarget::getRegBankInfo() const {260  return RegBankInfo.get();261}262 263const LegalizerInfo *PPCSubtarget::getLegalizerInfo() const {264  return Legalizer.get();265}266 267InstructionSelector *PPCSubtarget::getInstructionSelector() const {268  return InstSelector.get();269}270