summaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/GlobalISel/Utils.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2023-02-11 12:38:04 +0000
committerDimitry Andric <dim@FreeBSD.org>2023-02-11 12:38:11 +0000
commite3b557809604d036af6e00c60f012c2025b59a5e (patch)
tree8a11ba2269a3b669601e2fd41145b174008f4da8 /llvm/lib/CodeGen/GlobalISel/Utils.cpp
parent08e8dd7b9db7bb4a9de26d44c1cbfd24e869c014 (diff)
Diffstat (limited to 'llvm/lib/CodeGen/GlobalISel/Utils.cpp')
-rw-r--r--llvm/lib/CodeGen/GlobalISel/Utils.cpp263
1 files changed, 155 insertions, 108 deletions
diff --git a/llvm/lib/CodeGen/GlobalISel/Utils.cpp b/llvm/lib/CodeGen/GlobalISel/Utils.cpp
index 013c8700e8ae..07448548c295 100644
--- a/llvm/lib/CodeGen/GlobalISel/Utils.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/Utils.cpp
@@ -12,7 +12,7 @@
#include "llvm/CodeGen/GlobalISel/Utils.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/APInt.h"
-#include "llvm/ADT/Optional.h"
+#include "llvm/CodeGen/CodeGenCommonISel.h"
#include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h"
#include "llvm/CodeGen/GlobalISel/GISelKnownBits.h"
#include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h"
@@ -32,6 +32,8 @@
#include "llvm/IR/Constants.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/Utils/SizeOpts.h"
+#include <numeric>
+#include <optional>
#define DEBUG_TYPE "globalisel-utils"
@@ -55,7 +57,7 @@ Register llvm::constrainOperandRegClass(
const TargetRegisterClass &RegClass, MachineOperand &RegMO) {
Register Reg = RegMO.getReg();
// Assume physical registers are properly constrained.
- assert(Register::isVirtualRegister(Reg) && "PhysReg not implemented");
+ assert(Reg.isVirtual() && "PhysReg not implemented");
// Save the old register class to check whether
// the change notifications will be required.
@@ -107,7 +109,7 @@ Register llvm::constrainOperandRegClass(
MachineOperand &RegMO, unsigned OpIdx) {
Register Reg = RegMO.getReg();
// Assume physical registers are properly constrained.
- assert(Register::isVirtualRegister(Reg) && "PhysReg not implemented");
+ assert(Reg.isVirtual() && "PhysReg not implemented");
const TargetRegisterClass *OpRC = TII.getRegClass(II, OpIdx, &TRI, MF);
// Some of the target independent instructions, like COPY, may not impose any
@@ -169,7 +171,7 @@ bool llvm::constrainSelectedInstRegOperands(MachineInstr &I,
Register Reg = MO.getReg();
// Physical registers don't need to be constrained.
- if (Register::isPhysicalRegister(Reg))
+ if (Reg.isPhysical())
continue;
// Register operands with a value of 0 (e.g. predicate operands) don't need
@@ -233,7 +235,7 @@ bool llvm::isTriviallyDead(const MachineInstr &MI,
continue;
Register Reg = MO.getReg();
- if (Register::isPhysicalRegister(Reg) || !MRI.use_nodbg_empty(Reg))
+ if (Reg.isPhysical() || !MRI.use_nodbg_empty(Reg))
return false;
}
return true;
@@ -283,31 +285,31 @@ void llvm::reportGISelFailure(MachineFunction &MF, const TargetPassConfig &TPC,
reportGISelFailure(MF, TPC, MORE, R);
}
-Optional<APInt> llvm::getIConstantVRegVal(Register VReg,
- const MachineRegisterInfo &MRI) {
- Optional<ValueAndVReg> ValAndVReg = getIConstantVRegValWithLookThrough(
+std::optional<APInt> llvm::getIConstantVRegVal(Register VReg,
+ const MachineRegisterInfo &MRI) {
+ std::optional<ValueAndVReg> ValAndVReg = getIConstantVRegValWithLookThrough(
VReg, MRI, /*LookThroughInstrs*/ false);
assert((!ValAndVReg || ValAndVReg->VReg == VReg) &&
"Value found while looking through instrs");
if (!ValAndVReg)
- return None;
+ return std::nullopt;
return ValAndVReg->Value;
}
-Optional<int64_t>
+std::optional<int64_t>
llvm::getIConstantVRegSExtVal(Register VReg, const MachineRegisterInfo &MRI) {
- Optional<APInt> Val = getIConstantVRegVal(VReg, MRI);
+ std::optional<APInt> Val = getIConstantVRegVal(VReg, MRI);
if (Val && Val->getBitWidth() <= 64)
return Val->getSExtValue();
- return None;
+ return std::nullopt;
}
namespace {
typedef std::function<bool(const MachineInstr *)> IsOpcodeFn;
-typedef std::function<Optional<APInt>(const MachineInstr *MI)> GetAPCstFn;
+typedef std::function<std::optional<APInt>(const MachineInstr *MI)> GetAPCstFn;
-Optional<ValueAndVReg> getConstantVRegValWithLookThrough(
+std::optional<ValueAndVReg> getConstantVRegValWithLookThrough(
Register VReg, const MachineRegisterInfo &MRI, IsOpcodeFn IsConstantOpcode,
GetAPCstFn getAPCstValue, bool LookThroughInstrs = true,
bool LookThroughAnyExt = false) {
@@ -319,8 +321,8 @@ Optional<ValueAndVReg> getConstantVRegValWithLookThrough(
switch (MI->getOpcode()) {
case TargetOpcode::G_ANYEXT:
if (!LookThroughAnyExt)
- return None;
- LLVM_FALLTHROUGH;
+ return std::nullopt;
+ [[fallthrough]];
case TargetOpcode::G_TRUNC:
case TargetOpcode::G_SEXT:
case TargetOpcode::G_ZEXT:
@@ -331,22 +333,22 @@ Optional<ValueAndVReg> getConstantVRegValWithLookThrough(
break;
case TargetOpcode::COPY:
VReg = MI->getOperand(1).getReg();
- if (Register::isPhysicalRegister(VReg))
- return None;
+ if (VReg.isPhysical())
+ return std::nullopt;
break;
case TargetOpcode::G_INTTOPTR:
VReg = MI->getOperand(1).getReg();
break;
default:
- return None;
+ return std::nullopt;
}
}
if (!MI || !IsConstantOpcode(MI))
- return None;
+ return std::nullopt;
- Optional<APInt> MaybeVal = getAPCstValue(MI);
+ std::optional<APInt> MaybeVal = getAPCstValue(MI);
if (!MaybeVal)
- return None;
+ return std::nullopt;
APInt &Val = *MaybeVal;
while (!SeenOpcodes.empty()) {
std::pair<unsigned, unsigned> OpcodeAndSize = SeenOpcodes.pop_back_val();
@@ -386,31 +388,31 @@ bool isAnyConstant(const MachineInstr *MI) {
return Opc == TargetOpcode::G_CONSTANT || Opc == TargetOpcode::G_FCONSTANT;
}
-Optional<APInt> getCImmAsAPInt(const MachineInstr *MI) {
+std::optional<APInt> getCImmAsAPInt(const MachineInstr *MI) {
const MachineOperand &CstVal = MI->getOperand(1);
if (CstVal.isCImm())
return CstVal.getCImm()->getValue();
- return None;
+ return std::nullopt;
}
-Optional<APInt> getCImmOrFPImmAsAPInt(const MachineInstr *MI) {
+std::optional<APInt> getCImmOrFPImmAsAPInt(const MachineInstr *MI) {
const MachineOperand &CstVal = MI->getOperand(1);
if (CstVal.isCImm())
return CstVal.getCImm()->getValue();
if (CstVal.isFPImm())
return CstVal.getFPImm()->getValueAPF().bitcastToAPInt();
- return None;
+ return std::nullopt;
}
} // end anonymous namespace
-Optional<ValueAndVReg> llvm::getIConstantVRegValWithLookThrough(
+std::optional<ValueAndVReg> llvm::getIConstantVRegValWithLookThrough(
Register VReg, const MachineRegisterInfo &MRI, bool LookThroughInstrs) {
return getConstantVRegValWithLookThrough(VReg, MRI, isIConstant,
getCImmAsAPInt, LookThroughInstrs);
}
-Optional<ValueAndVReg> llvm::getAnyConstantVRegValWithLookThrough(
+std::optional<ValueAndVReg> llvm::getAnyConstantVRegValWithLookThrough(
Register VReg, const MachineRegisterInfo &MRI, bool LookThroughInstrs,
bool LookThroughAnyExt) {
return getConstantVRegValWithLookThrough(
@@ -418,12 +420,12 @@ Optional<ValueAndVReg> llvm::getAnyConstantVRegValWithLookThrough(
LookThroughAnyExt);
}
-Optional<FPValueAndVReg> llvm::getFConstantVRegValWithLookThrough(
+std::optional<FPValueAndVReg> llvm::getFConstantVRegValWithLookThrough(
Register VReg, const MachineRegisterInfo &MRI, bool LookThroughInstrs) {
auto Reg = getConstantVRegValWithLookThrough(
VReg, MRI, isFConstant, getCImmOrFPImmAsAPInt, LookThroughInstrs);
if (!Reg)
- return None;
+ return std::nullopt;
return FPValueAndVReg{getConstantFPVRegVal(Reg->VReg, MRI)->getValueAPF(),
Reg->VReg};
}
@@ -436,13 +438,13 @@ llvm::getConstantFPVRegVal(Register VReg, const MachineRegisterInfo &MRI) {
return MI->getOperand(1).getFPImm();
}
-Optional<DefinitionAndSourceRegister>
+std::optional<DefinitionAndSourceRegister>
llvm::getDefSrcRegIgnoringCopies(Register Reg, const MachineRegisterInfo &MRI) {
Register DefSrcReg = Reg;
auto *DefMI = MRI.getVRegDef(Reg);
auto DstTy = MRI.getType(DefMI->getOperand(0).getReg());
if (!DstTy.isValid())
- return None;
+ return std::nullopt;
unsigned Opc = DefMI->getOpcode();
while (Opc == TargetOpcode::COPY || isPreISelGenericOptimizationHint(Opc)) {
Register SrcReg = DefMI->getOperand(1).getReg();
@@ -458,14 +460,14 @@ llvm::getDefSrcRegIgnoringCopies(Register Reg, const MachineRegisterInfo &MRI) {
MachineInstr *llvm::getDefIgnoringCopies(Register Reg,
const MachineRegisterInfo &MRI) {
- Optional<DefinitionAndSourceRegister> DefSrcReg =
+ std::optional<DefinitionAndSourceRegister> DefSrcReg =
getDefSrcRegIgnoringCopies(Reg, MRI);
return DefSrcReg ? DefSrcReg->MI : nullptr;
}
Register llvm::getSrcRegIgnoringCopies(Register Reg,
const MachineRegisterInfo &MRI) {
- Optional<DefinitionAndSourceRegister> DefSrcReg =
+ std::optional<DefinitionAndSourceRegister> DefSrcReg =
getDefSrcRegIgnoringCopies(Reg, MRI);
return DefSrcReg ? DefSrcReg->Reg : Register();
}
@@ -489,16 +491,17 @@ APFloat llvm::getAPFloatFromSize(double Val, unsigned Size) {
return APF;
}
-Optional<APInt> llvm::ConstantFoldBinOp(unsigned Opcode, const Register Op1,
- const Register Op2,
- const MachineRegisterInfo &MRI) {
+std::optional<APInt> llvm::ConstantFoldBinOp(unsigned Opcode,
+ const Register Op1,
+ const Register Op2,
+ const MachineRegisterInfo &MRI) {
auto MaybeOp2Cst = getAnyConstantVRegValWithLookThrough(Op2, MRI, false);
if (!MaybeOp2Cst)
- return None;
+ return std::nullopt;
auto MaybeOp1Cst = getAnyConstantVRegValWithLookThrough(Op1, MRI, false);
if (!MaybeOp1Cst)
- return None;
+ return std::nullopt;
const APInt &C1 = MaybeOp1Cst->Value;
const APInt &C2 = MaybeOp2Cst->Value;
@@ -550,19 +553,19 @@ Optional<APInt> llvm::ConstantFoldBinOp(unsigned Opcode, const Register Op1,
return APIntOps::umax(C1, C2);
}
- return None;
+ return std::nullopt;
}
-Optional<APFloat> llvm::ConstantFoldFPBinOp(unsigned Opcode, const Register Op1,
- const Register Op2,
- const MachineRegisterInfo &MRI) {
+std::optional<APFloat>
+llvm::ConstantFoldFPBinOp(unsigned Opcode, const Register Op1,
+ const Register Op2, const MachineRegisterInfo &MRI) {
const ConstantFP *Op2Cst = getConstantFPVRegVal(Op2, MRI);
if (!Op2Cst)
- return None;
+ return std::nullopt;
const ConstantFP *Op1Cst = getConstantFPVRegVal(Op1, MRI);
if (!Op1Cst)
- return None;
+ return std::nullopt;
APFloat C1 = Op1Cst->getValueAPF();
const APFloat &C2 = Op2Cst->getValueAPF();
@@ -604,7 +607,7 @@ Optional<APFloat> llvm::ConstantFoldFPBinOp(unsigned Opcode, const Register Op1,
break;
}
- return None;
+ return std::nullopt;
}
SmallVector<APInt>
@@ -656,6 +659,20 @@ bool llvm::isKnownNeverNaN(Register Val, const MachineRegisterInfo &MRI,
switch (DefMI->getOpcode()) {
default:
break;
+ case TargetOpcode::G_FADD:
+ case TargetOpcode::G_FSUB:
+ case TargetOpcode::G_FMUL:
+ case TargetOpcode::G_FDIV:
+ case TargetOpcode::G_FREM:
+ case TargetOpcode::G_FSIN:
+ case TargetOpcode::G_FCOS:
+ case TargetOpcode::G_FMA:
+ case TargetOpcode::G_FMAD:
+ if (SNaN)
+ return true;
+
+ // TODO: Need isKnownNeverInfinity
+ return false;
case TargetOpcode::G_FMINNUM_IEEE:
case TargetOpcode::G_FMAXNUM_IEEE: {
if (SNaN)
@@ -742,9 +759,9 @@ Register llvm::getFunctionLiveInPhysReg(MachineFunction &MF,
return LiveIn;
}
-Optional<APInt> llvm::ConstantFoldExtOp(unsigned Opcode, const Register Op1,
- uint64_t Imm,
- const MachineRegisterInfo &MRI) {
+std::optional<APInt> llvm::ConstantFoldExtOp(unsigned Opcode,
+ const Register Op1, uint64_t Imm,
+ const MachineRegisterInfo &MRI) {
auto MaybeOp1Cst = getIConstantVRegVal(Op1, MRI);
if (MaybeOp1Cst) {
switch (Opcode) {
@@ -756,12 +773,12 @@ Optional<APInt> llvm::ConstantFoldExtOp(unsigned Opcode, const Register Op1,
}
}
}
- return None;
+ return std::nullopt;
}
-Optional<APFloat> llvm::ConstantFoldIntToFloat(unsigned Opcode, LLT DstTy,
- Register Src,
- const MachineRegisterInfo &MRI) {
+std::optional<APFloat>
+llvm::ConstantFoldIntToFloat(unsigned Opcode, LLT DstTy, Register Src,
+ const MachineRegisterInfo &MRI) {
assert(Opcode == TargetOpcode::G_SITOFP || Opcode == TargetOpcode::G_UITOFP);
if (auto MaybeSrcVal = getIConstantVRegVal(Src, MRI)) {
APFloat DstVal(getFltSemanticForLLT(DstTy));
@@ -769,30 +786,30 @@ Optional<APFloat> llvm::ConstantFoldIntToFloat(unsigned Opcode, LLT DstTy,
APFloat::rmNearestTiesToEven);
return DstVal;
}
- return None;
+ return std::nullopt;
}
-Optional<SmallVector<unsigned>>
+std::optional<SmallVector<unsigned>>
llvm::ConstantFoldCTLZ(Register Src, const MachineRegisterInfo &MRI) {
LLT Ty = MRI.getType(Src);
SmallVector<unsigned> FoldedCTLZs;
- auto tryFoldScalar = [&](Register R) -> Optional<unsigned> {
+ auto tryFoldScalar = [&](Register R) -> std::optional<unsigned> {
auto MaybeCst = getIConstantVRegVal(R, MRI);
if (!MaybeCst)
- return None;
+ return std::nullopt;
return MaybeCst->countLeadingZeros();
};
if (Ty.isVector()) {
// Try to constant fold each element.
auto *BV = getOpcodeDef<GBuildVector>(Src, MRI);
if (!BV)
- return None;
+ return std::nullopt;
for (unsigned SrcIdx = 0; SrcIdx < BV->getNumSources(); ++SrcIdx) {
if (auto MaybeFold = tryFoldScalar(BV->getSourceReg(SrcIdx))) {
FoldedCTLZs.emplace_back(*MaybeFold);
continue;
}
- return None;
+ return std::nullopt;
}
return FoldedCTLZs;
}
@@ -800,12 +817,12 @@ llvm::ConstantFoldCTLZ(Register Src, const MachineRegisterInfo &MRI) {
FoldedCTLZs.emplace_back(*MaybeCst);
return FoldedCTLZs;
}
- return None;
+ return std::nullopt;
}
bool llvm::isKnownToBeAPowerOfTwo(Register Reg, const MachineRegisterInfo &MRI,
GISelKnownBits *KB) {
- Optional<DefinitionAndSourceRegister> DefSrcReg =
+ std::optional<DefinitionAndSourceRegister> DefSrcReg =
getDefSrcRegIgnoringCopies(Reg, MRI);
if (!DefSrcReg)
return false;
@@ -879,12 +896,6 @@ void llvm::getSelectionDAGFallbackAnalysisUsage(AnalysisUsage &AU) {
AU.addPreserved<StackProtector>();
}
-static unsigned getLCMSize(unsigned OrigSize, unsigned TargetSize) {
- unsigned Mul = OrigSize * TargetSize;
- unsigned GCDSize = greatestCommonDivisor(OrigSize, TargetSize);
- return Mul / GCDSize;
-}
-
LLT llvm::getLCMType(LLT OrigTy, LLT TargetTy) {
const unsigned OrigSize = OrigTy.getSizeInBits();
const unsigned TargetSize = TargetTy.getSizeInBits();
@@ -899,8 +910,8 @@ LLT llvm::getLCMType(LLT OrigTy, LLT TargetTy) {
const LLT TargetElt = TargetTy.getElementType();
if (OrigElt.getSizeInBits() == TargetElt.getSizeInBits()) {
- int GCDElts = greatestCommonDivisor(OrigTy.getNumElements(),
- TargetTy.getNumElements());
+ int GCDElts =
+ std::gcd(OrigTy.getNumElements(), TargetTy.getNumElements());
// Prefer the original element type.
ElementCount Mul = OrigTy.getElementCount() * TargetTy.getNumElements();
return LLT::vector(Mul.divideCoefficientBy(GCDElts),
@@ -911,16 +922,16 @@ LLT llvm::getLCMType(LLT OrigTy, LLT TargetTy) {
return OrigTy;
}
- unsigned LCMSize = getLCMSize(OrigSize, TargetSize);
+ unsigned LCMSize = std::lcm(OrigSize, TargetSize);
return LLT::fixed_vector(LCMSize / OrigElt.getSizeInBits(), OrigElt);
}
if (TargetTy.isVector()) {
- unsigned LCMSize = getLCMSize(OrigSize, TargetSize);
+ unsigned LCMSize = std::lcm(OrigSize, TargetSize);
return LLT::fixed_vector(LCMSize / OrigSize, OrigTy);
}
- unsigned LCMSize = getLCMSize(OrigSize, TargetSize);
+ unsigned LCMSize = std::lcm(OrigSize, TargetSize);
// Preserve pointer types.
if (LCMSize == OrigSize)
@@ -958,8 +969,7 @@ LLT llvm::getGCDType(LLT OrigTy, LLT TargetTy) {
if (TargetTy.isVector()) {
LLT TargetElt = TargetTy.getElementType();
if (OrigElt.getSizeInBits() == TargetElt.getSizeInBits()) {
- int GCD = greatestCommonDivisor(OrigTy.getNumElements(),
- TargetTy.getNumElements());
+ int GCD = std::gcd(OrigTy.getNumElements(), TargetTy.getNumElements());
return LLT::scalarOrVector(ElementCount::getFixed(GCD), OrigElt);
}
} else {
@@ -968,7 +978,7 @@ LLT llvm::getGCDType(LLT OrigTy, LLT TargetTy) {
return OrigElt;
}
- unsigned GCD = greatestCommonDivisor(OrigSize, TargetSize);
+ unsigned GCD = std::gcd(OrigSize, TargetSize);
if (GCD == OrigElt.getSizeInBits())
return OrigElt;
@@ -986,11 +996,11 @@ LLT llvm::getGCDType(LLT OrigTy, LLT TargetTy) {
return OrigTy;
}
- unsigned GCD = greatestCommonDivisor(OrigSize, TargetSize);
+ unsigned GCD = std::gcd(OrigSize, TargetSize);
return LLT::scalar(GCD);
}
-Optional<int> llvm::getSplatIndex(MachineInstr &MI) {
+std::optional<int> llvm::getSplatIndex(MachineInstr &MI) {
assert(MI.getOpcode() == TargetOpcode::G_SHUFFLE_VECTOR &&
"Only G_SHUFFLE_VECTOR can have a splat index!");
ArrayRef<int> Mask = MI.getOperand(3).getShuffleMask();
@@ -1006,7 +1016,7 @@ Optional<int> llvm::getSplatIndex(MachineInstr &MI) {
int SplatValue = *FirstDefinedIdx;
if (any_of(make_range(std::next(FirstDefinedIdx), Mask.end()),
[&SplatValue](int Elt) { return Elt >= 0 && Elt != SplatValue; }))
- return None;
+ return std::nullopt;
return SplatValue;
}
@@ -1018,36 +1028,41 @@ static bool isBuildVectorOp(unsigned Opcode) {
namespace {
-Optional<ValueAndVReg> getAnyConstantSplat(Register VReg,
- const MachineRegisterInfo &MRI,
- bool AllowUndef) {
+std::optional<ValueAndVReg> getAnyConstantSplat(Register VReg,
+ const MachineRegisterInfo &MRI,
+ bool AllowUndef) {
MachineInstr *MI = getDefIgnoringCopies(VReg, MRI);
if (!MI)
- return None;
+ return std::nullopt;
- if (!isBuildVectorOp(MI->getOpcode()))
- return None;
+ bool isConcatVectorsOp = MI->getOpcode() == TargetOpcode::G_CONCAT_VECTORS;
+ if (!isBuildVectorOp(MI->getOpcode()) && !isConcatVectorsOp)
+ return std::nullopt;
- Optional<ValueAndVReg> SplatValAndReg = None;
+ std::optional<ValueAndVReg> SplatValAndReg;
for (MachineOperand &Op : MI->uses()) {
Register Element = Op.getReg();
+ // If we have a G_CONCAT_VECTOR, we recursively look into the
+ // vectors that we're concatenating to see if they're splats.
auto ElementValAndReg =
- getAnyConstantVRegValWithLookThrough(Element, MRI, true, true);
+ isConcatVectorsOp
+ ? getAnyConstantSplat(Element, MRI, AllowUndef)
+ : getAnyConstantVRegValWithLookThrough(Element, MRI, true, true);
// If AllowUndef, treat undef as value that will result in a constant splat.
if (!ElementValAndReg) {
if (AllowUndef && isa<GImplicitDef>(MRI.getVRegDef(Element)))
continue;
- return None;
+ return std::nullopt;
}
// Record splat value
if (!SplatValAndReg)
SplatValAndReg = ElementValAndReg;
- // Different constant then the one already recorded, not a constant splat.
+ // Different constant than the one already recorded, not a constant splat.
if (SplatValAndReg->Value != ElementValAndReg->Value)
- return None;
+ return std::nullopt;
}
return SplatValAndReg;
@@ -1070,44 +1085,45 @@ bool llvm::isBuildVectorConstantSplat(const MachineInstr &MI,
AllowUndef);
}
-Optional<APInt> llvm::getIConstantSplatVal(const Register Reg,
- const MachineRegisterInfo &MRI) {
+std::optional<APInt>
+llvm::getIConstantSplatVal(const Register Reg, const MachineRegisterInfo &MRI) {
if (auto SplatValAndReg =
getAnyConstantSplat(Reg, MRI, /* AllowUndef */ false)) {
- Optional<ValueAndVReg> ValAndVReg =
+ std::optional<ValueAndVReg> ValAndVReg =
getIConstantVRegValWithLookThrough(SplatValAndReg->VReg, MRI);
return ValAndVReg->Value;
}
- return None;
+ return std::nullopt;
}
-Optional<APInt> getIConstantSplatVal(const MachineInstr &MI,
- const MachineRegisterInfo &MRI) {
+std::optional<APInt>
+llvm::getIConstantSplatVal(const MachineInstr &MI,
+ const MachineRegisterInfo &MRI) {
return getIConstantSplatVal(MI.getOperand(0).getReg(), MRI);
}
-Optional<int64_t>
+std::optional<int64_t>
llvm::getIConstantSplatSExtVal(const Register Reg,
const MachineRegisterInfo &MRI) {
if (auto SplatValAndReg =
getAnyConstantSplat(Reg, MRI, /* AllowUndef */ false))
return getIConstantVRegSExtVal(SplatValAndReg->VReg, MRI);
- return None;
+ return std::nullopt;
}
-Optional<int64_t>
+std::optional<int64_t>
llvm::getIConstantSplatSExtVal(const MachineInstr &MI,
const MachineRegisterInfo &MRI) {
return getIConstantSplatSExtVal(MI.getOperand(0).getReg(), MRI);
}
-Optional<FPValueAndVReg> llvm::getFConstantSplat(Register VReg,
- const MachineRegisterInfo &MRI,
- bool AllowUndef) {
+std::optional<FPValueAndVReg>
+llvm::getFConstantSplat(Register VReg, const MachineRegisterInfo &MRI,
+ bool AllowUndef) {
if (auto SplatValAndReg = getAnyConstantSplat(VReg, MRI, AllowUndef))
return getFConstantVRegValWithLookThrough(SplatValAndReg->VReg, MRI);
- return None;
+ return std::nullopt;
}
bool llvm::isBuildVectorAllZeros(const MachineInstr &MI,
@@ -1122,17 +1138,17 @@ bool llvm::isBuildVectorAllOnes(const MachineInstr &MI,
return isBuildVectorConstantSplat(MI, MRI, -1, AllowUndef);
}
-Optional<RegOrConstant> llvm::getVectorSplat(const MachineInstr &MI,
- const MachineRegisterInfo &MRI) {
+std::optional<RegOrConstant>
+llvm::getVectorSplat(const MachineInstr &MI, const MachineRegisterInfo &MRI) {
unsigned Opc = MI.getOpcode();
if (!isBuildVectorOp(Opc))
- return None;
+ return std::nullopt;
if (auto Splat = getIConstantSplatSExtVal(MI, MRI))
return RegOrConstant(*Splat);
auto Reg = MI.getOperand(1).getReg();
if (any_of(make_range(MI.operands_begin() + 2, MI.operands_end()),
[&Reg](const MachineOperand &Op) { return Op.getReg() != Reg; }))
- return None;
+ return std::nullopt;
return RegOrConstant(Reg);
}
@@ -1192,7 +1208,7 @@ bool llvm::isConstantOrConstantVector(const MachineInstr &MI,
return true;
}
-Optional<APInt>
+std::optional<APInt>
llvm::isConstantOrConstantSplatVector(MachineInstr &MI,
const MachineRegisterInfo &MRI) {
Register Def = MI.getOperand(0).getReg();
@@ -1200,7 +1216,7 @@ llvm::isConstantOrConstantSplatVector(MachineInstr &MI,
return C->Value;
auto MaybeCst = getIConstantSplatSExtVal(MI, MRI);
if (!MaybeCst)
- return None;
+ return std::nullopt;
const unsigned ScalarSize = MRI.getType(Def).getScalarSizeInBits();
return APInt(ScalarSize, *MaybeCst, true);
}
@@ -1283,6 +1299,18 @@ bool llvm::isConstTrueVal(const TargetLowering &TLI, int64_t Val, bool IsVector,
llvm_unreachable("Invalid boolean contents");
}
+bool llvm::isConstFalseVal(const TargetLowering &TLI, int64_t Val,
+ bool IsVector, bool IsFP) {
+ switch (TLI.getBooleanContents(IsVector, IsFP)) {
+ case TargetLowering::UndefinedBooleanContent:
+ return ~Val & 0x1;
+ case TargetLowering::ZeroOrOneBooleanContent:
+ case TargetLowering::ZeroOrNegativeOneBooleanContent:
+ return Val == 0;
+ }
+ llvm_unreachable("Invalid boolean contents");
+}
+
int64_t llvm::getICmpTrueVal(const TargetLowering &TLI, bool IsVector,
bool IsFP) {
switch (TLI.getBooleanContents(IsVector, IsFP)) {
@@ -1335,3 +1363,22 @@ void llvm::eraseInstr(MachineInstr &MI, MachineRegisterInfo &MRI,
LostDebugLocObserver *LocObserver) {
return eraseInstrs({&MI}, MRI, LocObserver);
}
+
+void llvm::salvageDebugInfo(const MachineRegisterInfo &MRI, MachineInstr &MI) {
+ for (auto &Def : MI.defs()) {
+ assert(Def.isReg() && "Must be a reg");
+
+ SmallVector<MachineOperand *, 16> DbgUsers;
+ for (auto &MOUse : MRI.use_operands(Def.getReg())) {
+ MachineInstr *DbgValue = MOUse.getParent();
+ // Ignore partially formed DBG_VALUEs.
+ if (DbgValue->isNonListDebugValue() && DbgValue->getNumOperands() == 4) {
+ DbgUsers.push_back(&MOUse);
+ }
+ }
+
+ if (!DbgUsers.empty()) {
+ salvageDebugInfoForDbgValue(MRI, MI, DbgUsers);
+ }
+ }
+}