llvm-project/llvm/lib/Target/SystemZ/SystemZSubtarget.cpp
Eli Friedman 9f82ac5738
Remove GlobalObject::getAlign/setAlignment (#143188)
Currently, GlobalObject has an "alignment" property... but it's
basically nonsense: alignment doesn't mean the same thing for variables
and functions, and it's completely meaningless for ifuncs.

This "removes" (actually marking protected) the methods from
GlobalObject, adds the relevant methods to Function and GlobalVariable,
and adjusts the code appropriately.

This should make future alignment-related cleanups easier.
2025-06-09 13:51:03 -07:00

133 lines
4.4 KiB
C++

//===-- SystemZSubtarget.cpp - SystemZ subtarget information --------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "SystemZSubtarget.h"
#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/Target/TargetMachine.h"
using namespace llvm;
#define DEBUG_TYPE "systemz-subtarget"
#define GET_SUBTARGETINFO_TARGET_DESC
#define GET_SUBTARGETINFO_CTOR
#include "SystemZGenSubtargetInfo.inc"
static cl::opt<bool> UseSubRegLiveness(
"systemz-subreg-liveness",
cl::desc("Enable subregister liveness tracking for SystemZ (experimental)"),
cl::Hidden);
// Pin the vtable to this file.
void SystemZSubtarget::anchor() {}
SystemZSubtarget &SystemZSubtarget::initializeSubtargetDependencies(
StringRef CPU, StringRef TuneCPU, StringRef FS) {
if (CPU.empty())
CPU = "generic";
if (TuneCPU.empty())
TuneCPU = CPU;
// Parse features string.
ParseSubtargetFeatures(CPU, TuneCPU, FS);
// -msoft-float implies -mno-vx.
if (HasSoftFloat)
HasVector = false;
// -mno-vx implicitly disables all vector-related features.
if (!HasVector) {
HasVectorEnhancements1 = false;
HasVectorEnhancements2 = false;
HasVectorEnhancements3 = false;
HasVectorPackedDecimal = false;
HasVectorPackedDecimalEnhancement = false;
HasVectorPackedDecimalEnhancement2 = false;
HasVectorPackedDecimalEnhancement3 = false;
}
return *this;
}
SystemZCallingConventionRegisters *
SystemZSubtarget::initializeSpecialRegisters() {
if (isTargetXPLINK64())
return new SystemZXPLINK64Registers;
else if (isTargetELF())
return new SystemZELFRegisters;
llvm_unreachable("Invalid Calling Convention. Cannot initialize Special "
"Call Registers!");
}
SystemZSubtarget::SystemZSubtarget(const Triple &TT, const std::string &CPU,
const std::string &TuneCPU,
const std::string &FS,
const TargetMachine &TM)
: SystemZGenSubtargetInfo(TT, CPU, TuneCPU, FS), TargetTriple(TT),
SpecialRegisters(initializeSpecialRegisters()),
InstrInfo(initializeSubtargetDependencies(CPU, TuneCPU, FS)),
TLInfo(TM, *this), FrameLowering(SystemZFrameLowering::create(*this)) {}
bool SystemZSubtarget::enableSubRegLiveness() const {
return UseSubRegLiveness;
}
bool SystemZSubtarget::isAddressedViaADA(const GlobalValue *GV) const {
if (const auto *GO = dyn_cast<GlobalObject>(GV)) {
// A R/O variable is placed in code section. If the R/O variable has as
// least two byte alignment, then generated code can use relative
// instructions to address the variable. Otherwise, use the ADA to address
// the variable.
if (auto *GV = dyn_cast<GlobalVariable>(GO))
if (GV->getAlign() && (*GV->getAlign()).value() & 0x1)
return true;
// getKindForGlobal only works with definitions
if (GO->isDeclaration()) {
return true;
}
// check AvailableExternallyLinkage here as getKindForGlobal() asserts
if (GO->hasAvailableExternallyLinkage()) {
return true;
}
SectionKind GOKind = TargetLoweringObjectFile::getKindForGlobal(
GO, TLInfo.getTargetMachine());
if (!GOKind.isReadOnly()) {
return true;
}
return false; // R/O variable with multiple of 2 byte alignment
}
return true;
}
bool SystemZSubtarget::isPC32DBLSymbol(const GlobalValue *GV,
CodeModel::Model CM) const {
if (isTargetzOS())
return !isAddressedViaADA(GV);
// PC32DBL accesses require the low bit to be clear.
//
// FIXME: Explicitly check for functions: the datalayout is currently
// missing information about function pointers.
const DataLayout &DL = GV->getDataLayout();
if (GV->getPointerAlignment(DL) == 1 && !GV->getValueType()->isFunctionTy())
return false;
// For the small model, all locally-binding symbols are in range.
if (CM == CodeModel::Small)
return TLInfo.getTargetMachine().shouldAssumeDSOLocal(GV);
// For Medium and above, assume that the symbol is not within the 4GB range.
// Taking the address of locally-defined text would be OK, but that
// case isn't easy to detect.
return false;
}