Subzero: Avoid explicit references to RegNumT sentinel value.
There are many occurrences of if (RegNum == RegNumT::NoRegister).
This patch eliminates NoRegister and provides a simpler mechanism for declaring and testing RegNumT values to see if they are undefined.
BUG= none
R=stichnot@chromium.org
Review URL: https://codereview.chromium.org/1691193002 .
Patch from Reed Kotler <rkotlerimgtec@gmail.com>.
diff --git a/src/IceInstARM32.h b/src/IceInstARM32.h
index 5d53afd..c939246 100644
--- a/src/IceInstARM32.h
+++ b/src/IceInstARM32.h
@@ -361,7 +361,7 @@
private:
StackVariable(Type Ty, SizeT Index)
: Variable(StackVariableKind, Ty, Index) {}
- RegNumT BaseRegNum = RegNumT::NoRegister;
+ RegNumT BaseRegNum;
};
/// Base class for ARM instructions. While most ARM instructions can be
diff --git a/src/IceInstX86BaseImpl.h b/src/IceInstX86BaseImpl.h
index 6a087e8..b80a169 100644
--- a/src/IceInstX86BaseImpl.h
+++ b/src/IceInstX86BaseImpl.h
@@ -1987,8 +1987,7 @@
Type Ty = Src0Var->getType();
// lea on x86-32 doesn't accept mem128 operands, so cast VSrc0 to an
// acceptable type.
- Src0Var->asType(isVectorType(Ty) ? IceType_i32 : Ty, RegNumT::NoRegister)
- ->emit(Func);
+ Src0Var->asType(isVectorType(Ty) ? IceType_i32 : Ty, RegNumT())->emit(Func);
} else {
Src0->emit(Func);
}
@@ -2025,7 +2024,7 @@
InstX86Base::getTarget(Func)->typeWidthInBytesOnStack(SrcTy));
const Operand *NewSrc = Src;
if (auto *SrcVar = llvm::dyn_cast<Variable>(Src)) {
- auto NewRegNum = RegNumT::NoRegister;
+ RegNumT NewRegNum;
if (SrcVar->hasReg())
NewRegNum = Traits::getGprForType(DestTy, SrcVar->getRegNum());
if (SrcTy != DestTy)
diff --git a/src/IceOperand.cpp b/src/IceOperand.cpp
index ada1606..73b0958 100644
--- a/src/IceOperand.cpp
+++ b/src/IceOperand.cpp
@@ -86,7 +86,6 @@
return true;
}
-const RegNumT RegNumT::NoRegister(RegNumT::NoRegisterValue);
RegNumT::BaseType RegNumT::Limit = 0;
bool operator<(const RegWeight &A, const RegWeight &B) {
@@ -201,7 +200,7 @@
Variable *V = new (getCurrentCfgAllocator()->Allocate<Variable>())
Variable(kVariable, Ty, Number);
V->NameIndex = NameIndex;
- V->RegNum = NewRegNum == RegNumT::NoRegister ? RegNum : NewRegNum;
+ V->RegNum = NewRegNum.hasValue() ? NewRegNum : RegNum;
V->StackOffset = StackOffset;
return V;
}
diff --git a/src/IceOperand.h b/src/IceOperand.h
index a203086..9b46e35 100644
--- a/src/IceOperand.h
+++ b/src/IceOperand.h
@@ -403,11 +403,11 @@
};
/// RegNumT is for holding target-specific register numbers, plus the sentinel
-/// value NoRegister. Its public ctor allows direct use of enum values, such as
-/// RegNumT(Reg_eax), but not things like RegNumT(Reg_eax+1). This is to try to
-/// prevent inappropriate assumptions about enum ordering. If needed, the
-/// fromInt() method can be used, such as when a RegNumT is based on a bitvector
-/// index.
+/// value if no register is assigned. Its public ctor allows direct use of enum
+/// values, such as RegNumT(Reg_eax), but not things like RegNumT(Reg_eax+1).
+/// This is to try to prevent inappropriate assumptions about enum ordering. If
+/// needed, the fromInt() method can be used, such as when a RegNumT is based
+/// on a bitvector index.
class RegNumT {
public:
using BaseType = uint32_t;
@@ -441,7 +441,9 @@
// Define NoRegisterValue as an enum value so that it can be used as an
// argument for the public ctor if desired.
enum { NoRegisterValue = std::numeric_limits<BaseType>::max() };
- const static RegNumT NoRegister /* = NoRegisterValue */;
+
+ bool hasValue() const { return Value != NoRegisterValue; }
+ bool hasNoValue() const { return !hasValue(); }
private:
BaseType Value = NoRegisterValue;
@@ -646,14 +648,14 @@
return "lv$" + getName(Func);
}
- bool hasReg() const { return getRegNum() != RegNumT::NoRegister; }
+ bool hasReg() const { return getRegNum().hasValue(); }
RegNumT getRegNum() const { return RegNum; }
void setRegNum(RegNumT NewRegNum) {
// Regnum shouldn't be set more than once.
assert(!hasReg() || RegNum == NewRegNum);
RegNum = NewRegNum;
}
- bool hasRegTmp() const { return getRegNumTmp() != RegNumT::NoRegister; }
+ bool hasRegTmp() const { return getRegNumTmp().hasValue(); }
RegNumT getRegNumTmp() const { return RegNumTmp; }
void setRegNumTmp(RegNumT NewRegNum) { RegNumTmp = NewRegNum; }
@@ -702,7 +704,7 @@
/// primarily for syntactic correctness of textual assembly emission. Note
/// that only basic information is copied, in particular not IsArgument,
/// IsImplicitArgument, IgnoreLiveness, RegNumTmp, Live, LoVar, HiVar,
- /// VarsReal. If NewRegNum!=NoRegister, then that register assignment is made
+ /// VarsReal. If NewRegNum.hasValue(), then that register assignment is made
/// instead of copying the existing assignment.
const Variable *asType(Type Ty, RegNumT NewRegNum) const;
@@ -711,7 +713,7 @@
void dump(const Cfg *Func, Ostream &Str) const override;
/// Return reg num of base register, if different from stack/frame register.
- virtual RegNumT getBaseRegNum() const { return RegNumT::NoRegister; }
+ virtual RegNumT getBaseRegNum() const { return RegNumT(); }
static bool classof(const Operand *Operand) {
OperandKind Kind = Operand->getKind();
@@ -741,13 +743,12 @@
bool IsRematerializable = false;
RegRequirement RegRequirement = RR_MayHaveRegister;
RegClass RegisterClass;
- /// RegNum is the allocated register, or NoRegister if it isn't
- /// register-allocated.
- RegNumT RegNum = RegNumT::NoRegister;
+ /// RegNum is the allocated register, (as long as RegNum.hasValue() is true).
+ RegNumT RegNum;
/// RegNumTmp is the tentative assignment during register allocation.
- RegNumT RegNumTmp = RegNumT::NoRegister;
+ RegNumT RegNumTmp;
/// StackOffset is the canonical location on stack (only if
- /// RegNum==NoRegister || IsArgument).
+ /// RegNum.hasNoValue() || IsArgument).
int32_t StackOffset = 0;
LiveRange Live;
/// VarsReal (and Operand::Vars) are set up such that Vars[0] == this.
diff --git a/src/IceRegAlloc.cpp b/src/IceRegAlloc.cpp
index f59cb3c..993dc44 100644
--- a/src/IceRegAlloc.cpp
+++ b/src/IceRegAlloc.cpp
@@ -502,7 +502,7 @@
// not appear within the current Variable's live range.
void LinearScan::findRegisterPreference(IterationState &Iter) {
Iter.Prefer = nullptr;
- Iter.PreferReg = RegNumT::NoRegister;
+ Iter.PreferReg = RegNumT();
Iter.AllowOverlap = false;
if (!FindPreference)
@@ -738,7 +738,7 @@
--RegUses[RegAlias];
assert(RegUses[RegAlias] >= 0);
}
- Item->setRegNumTmp(RegNumT::NoRegister);
+ Item->setRegNumTmp(RegNumT());
moveItem(Active, Index, Handled);
Evicted.push_back(Item);
}
@@ -756,7 +756,7 @@
// instructions.
if (Aliases[Item->getRegNumTmp()] && Item->rangeOverlaps(Iter.Cur)) {
dumpLiveRangeTrace("Evicting I ", Item);
- Item->setRegNumTmp(RegNumT::NoRegister);
+ Item->setRegNumTmp(RegNumT());
moveItem(Inactive, Index, Handled);
Evicted.push_back(Item);
}
diff --git a/src/IceRegAlloc.h b/src/IceRegAlloc.h
index 299d709..67f4137 100644
--- a/src/IceRegAlloc.h
+++ b/src/IceRegAlloc.h
@@ -58,7 +58,7 @@
IterationState() = default;
Variable *Cur = nullptr;
Variable *Prefer = nullptr;
- RegNumT PreferReg = RegNumT::NoRegister;
+ RegNumT PreferReg;
bool AllowOverlap = false;
llvm::SmallBitVector RegMask;
llvm::SmallBitVector RegMaskUnfiltered;
diff --git a/src/IceRegistersARM32.h b/src/IceRegistersARM32.h
index 6e3c562..8941a9e 100644
--- a/src/IceRegistersARM32.h
+++ b/src/IceRegistersARM32.h
@@ -104,7 +104,7 @@
static inline void assertValidRegNum(RegNumT RegNum) {
(void)RegNum;
- assert(RegNum != RegNumT::NoRegister);
+ assert(RegNum.hasValue());
}
static inline bool isGPRegister(RegNumT RegNum) {
diff --git a/src/IceTargetLoweringARM32.cpp b/src/IceTargetLoweringARM32.cpp
index 0b12bc6..85e0a65 100644
--- a/src/IceTargetLoweringARM32.cpp
+++ b/src/IceTargetLoweringARM32.cpp
@@ -1183,7 +1183,7 @@
assert(!Var->isRematerializable());
int32_t Offset = Var->getStackOffset();
auto BaseRegNum = Var->getBaseRegNum();
- if (BaseRegNum == RegNumT::NoRegister) {
+ if (BaseRegNum.hasNoValue()) {
BaseRegNum = getFrameOrStackReg();
}
const Type VarTy = Var->getType();
@@ -5816,7 +5816,7 @@
assert(Allowed & Legal_Reg);
// Copied ipsis literis from TargetX86Base<Machine>.
- if (RegNum == RegNumT::NoRegister) {
+ if (RegNum.hasNoValue()) {
if (Variable *Subst = getContext().availabilityGet(From)) {
// At this point we know there is a potential substitution available.
if (!Subst->isRematerializable() && Subst->mustHaveReg() &&
@@ -6018,7 +6018,7 @@
// register, or
// RegNum is required and Var->getRegNum() doesn't match.
if ((!(Allowed & Legal_Mem) && !MustHaveRegister) ||
- (RegNum != RegNumT::NoRegister && RegNum != Var->getRegNum())) {
+ (RegNum.hasValue() && (RegNum != Var->getRegNum()))) {
From = copyToReg(From, RegNum);
}
return From;
@@ -6085,12 +6085,12 @@
Variable *TargetARM32::makeReg(Type Type, RegNumT RegNum) {
// There aren't any 64-bit integer registers for ARM32.
assert(Type != IceType_i64);
- assert(AllowTemporaryWithNoReg || RegNum != RegNumT::NoRegister);
+ assert(AllowTemporaryWithNoReg || RegNum.hasValue());
Variable *Reg = Func->makeVariable(Type);
- if (RegNum == RegNumT::NoRegister)
- Reg->setMustHaveReg();
- else
+ if (RegNum.hasValue())
Reg->setRegNum(RegNum);
+ else
+ Reg->setMustHaveReg();
return Reg;
}
diff --git a/src/IceTargetLoweringARM32.h b/src/IceTargetLoweringARM32.h
index 267c766..e457127 100644
--- a/src/IceTargetLoweringARM32.h
+++ b/src/IceTargetLoweringARM32.h
@@ -174,10 +174,10 @@
};
using LegalMask = uint32_t;
- Operand *legalizeUndef(Operand *From, RegNumT RegNum = RegNumT::NoRegister);
+ Operand *legalizeUndef(Operand *From, RegNumT RegNum = RegNumT());
Operand *legalize(Operand *From, LegalMask Allowed = Legal_Default,
- RegNumT RegNum = RegNumT::NoRegister);
- Variable *legalizeToReg(Operand *From, RegNumT RegNum = RegNumT::NoRegister);
+ RegNumT RegNum = RegNumT());
+ Variable *legalizeToReg(Operand *From, RegNumT RegNum = RegNumT());
OperandARM32ShAmtImm *shAmtImm(uint32_t ShAmtImm) const {
assert(ShAmtImm < 32);
@@ -270,14 +270,14 @@
OperandARM32Mem *formMemoryOperand(Operand *Ptr, Type Ty);
Variable64On32 *makeI64RegPair();
- Variable *makeReg(Type Ty, RegNumT RegNum = RegNumT::NoRegister);
+ Variable *makeReg(Type Ty, RegNumT RegNum = RegNumT());
static Type stackSlotType();
- Variable *copyToReg(Operand *Src, RegNumT RegNum = RegNumT::NoRegister);
+ Variable *copyToReg(Operand *Src, RegNumT RegNum = RegNumT());
void alignRegisterPow2(Variable *Reg, uint32_t Align,
- RegNumT TmpRegNum = RegNumT::NoRegister);
+ RegNumT TmpRegNum = RegNumT());
/// Returns a vector in a register with the given constant entries.
- Variable *makeVectorOfZeros(Type Ty, RegNumT RegNum = RegNumT::NoRegister);
+ Variable *makeVectorOfZeros(Type Ty, RegNumT RegNum = RegNumT());
void
makeRandomRegisterPermutation(llvm::SmallVectorImpl<RegNumT> &Permutation,
diff --git a/src/IceTargetLoweringMIPS32.cpp b/src/IceTargetLoweringMIPS32.cpp
index e34dd5d..075e62c 100644
--- a/src/IceTargetLoweringMIPS32.cpp
+++ b/src/IceTargetLoweringMIPS32.cpp
@@ -360,10 +360,10 @@
// There aren't any 64-bit integer registers for Mips32.
assert(Type != IceType_i64);
Variable *Reg = Func->makeVariable(Type);
- if (RegNum == RegNumT::NoRegister)
- Reg->setMustHaveReg();
- else
+ if (RegNum.hasValue())
Reg->setRegNum(RegNum);
+ else
+ Reg->setMustHaveReg();
return Reg;
}
@@ -1253,10 +1253,10 @@
// Also try the inverse and use MVN if possible.
// Do a movw/movt to a register.
Variable *Reg;
- if (RegNum == RegNumT::NoRegister)
- Reg = makeReg(Ty, RegNum);
- else
+ if (RegNum.hasValue())
Reg = getPhysicalRegister(RegNum);
+ else
+ Reg = makeReg(Ty, RegNum);
if (isInt<16>(int32_t(Value))) {
Variable *Zero = getPhysicalRegister(RegMIPS32::Reg_ZERO, Ty);
Context.insert<InstFakeDef>(Zero);
@@ -1281,7 +1281,7 @@
// register, or
// RegNum is required and Var->getRegNum() doesn't match.
if ((!(Allowed & Legal_Mem) && !MustHaveRegister) ||
- (RegNum != RegNumT::NoRegister && RegNum != Var->getRegNum())) {
+ (RegNum.hasValue() && RegNum != Var->getRegNum())) {
From = copyToReg(From, RegNum);
}
return From;
diff --git a/src/IceTargetLoweringMIPS32.h b/src/IceTargetLoweringMIPS32.h
index 7608de1..08897e8 100644
--- a/src/IceTargetLoweringMIPS32.h
+++ b/src/IceTargetLoweringMIPS32.h
@@ -220,15 +220,15 @@
};
typedef uint32_t LegalMask;
Operand *legalize(Operand *From, LegalMask Allowed = Legal_Default,
- RegNumT RegNum = RegNumT::NoRegister);
+ RegNumT RegNum = RegNumT());
- Variable *legalizeToVar(Operand *From, RegNumT RegNum = RegNumT::NoRegister);
+ Variable *legalizeToVar(Operand *From, RegNumT RegNum = RegNumT());
- Variable *legalizeToReg(Operand *From, RegNumT RegNum = RegNumT::NoRegister);
+ Variable *legalizeToReg(Operand *From, RegNumT RegNum = RegNumT());
- Variable *makeReg(Type Ty, RegNumT RegNum = RegNumT::NoRegister);
+ Variable *makeReg(Type Ty, RegNumT RegNum = RegNumT());
static Type stackSlotType();
- Variable *copyToReg(Operand *Src, RegNumT RegNum = RegNumT::NoRegister);
+ Variable *copyToReg(Operand *Src, RegNumT RegNum = RegNumT());
void addProlog(CfgNode *Node) override;
void addEpilog(CfgNode *Node) override;
@@ -240,7 +240,7 @@
Operand *loOperand(Operand *Operand);
Operand *hiOperand(Operand *Operand);
- Operand *legalizeUndef(Operand *From, RegNumT RegNum = RegNumT::NoRegister);
+ Operand *legalizeUndef(Operand *From, RegNumT RegNum = RegNumT());
protected:
explicit TargetMIPS32(Cfg *Func);
diff --git a/src/IceTargetLoweringX8632Traits.h b/src/IceTargetLoweringX8632Traits.h
index 8b5412d..2ff3d7a 100644
--- a/src/IceTargetLoweringX8632Traits.h
+++ b/src/IceTargetLoweringX8632Traits.h
@@ -375,7 +375,7 @@
public:
// Return a register in RegNum's alias set that is suitable for Ty.
static RegNumT getGprForType(Type Ty, RegNumT RegNum) {
- assert(RegNum != RegNumT::NoRegister);
+ assert(RegNum.hasValue());
if (!isScalarIntegerType(Ty)) {
return RegNum;
@@ -686,7 +686,7 @@
static_assert(RegisterSet::Reg_xmm0 + 1 == RegisterSet::Reg_xmm1,
"Inconsistency between XMM register numbers and ordinals");
if (ArgNum >= X86_MAX_XMM_ARGS) {
- return RegNumT::NoRegister;
+ return RegNumT();
}
return RegNumT::fixme(RegisterSet::Reg_xmm0 + ArgNum);
}
@@ -695,7 +695,7 @@
assert(Ty == IceType_i64 || Ty == IceType_i32);
(void)Ty;
(void)ArgNum;
- return RegNumT::NoRegister;
+ return RegNumT();
}
/// The number of bits in a byte
diff --git a/src/IceTargetLoweringX8664.cpp b/src/IceTargetLoweringX8664.cpp
index ecf86b0..86956cd 100644
--- a/src/IceTargetLoweringX8664.cpp
+++ b/src/IceTargetLoweringX8664.cpp
@@ -419,8 +419,7 @@
}
}
- auto RegNum = RegNumT::NoRegister;
- auto RegNum32 = RegNumT::NoRegister;
+ RegNumT RegNum, RegNum32;
if (T != nullptr) {
if (T->hasReg()) {
RegNum = Traits::getGprForType(IceType_i64, T->getRegNum());
diff --git a/src/IceTargetLoweringX8664Traits.h b/src/IceTargetLoweringX8664Traits.h
index 18e054a..0ee1a69 100644
--- a/src/IceTargetLoweringX8664Traits.h
+++ b/src/IceTargetLoweringX8664Traits.h
@@ -401,7 +401,7 @@
public:
static RegNumT getGprForType(Type Ty, RegNumT RegNum) {
- assert(RegNum != RegNumT::NoRegister);
+ assert(RegNum.hasValue());
if (!isScalarIntegerType(Ty)) {
return RegNum;
@@ -730,14 +730,14 @@
static_assert(RegisterSet::Reg_xmm0 + 1 == RegisterSet::Reg_xmm1,
"Inconsistency between XMM register numbers and ordinals");
if (ArgNum >= X86_MAX_XMM_ARGS) {
- return RegNumT::NoRegister;
+ return RegNumT();
}
return RegNumT::fixme(RegisterSet::Reg_xmm0 + ArgNum);
}
/// Get the register for a given argument slot in the GPRs.
static RegNumT getRegisterForGprArgNum(Type Ty, uint32_t ArgNum) {
if (ArgNum >= X86_MAX_GPR_ARGS) {
- return RegNumT::NoRegister;
+ return RegNumT();
}
static const RegisterSet::AllRegisters GprForArgNum[] = {
RegisterSet::Reg_rdi, RegisterSet::Reg_rsi, RegisterSet::Reg_rdx,
diff --git a/src/IceTargetLoweringX86Base.h b/src/IceTargetLoweringX86Base.h
index c0bafd3..fd8f818 100644
--- a/src/IceTargetLoweringX86Base.h
+++ b/src/IceTargetLoweringX86Base.h
@@ -220,7 +220,7 @@
X86Address stackVarToAsmOperand(const Variable *Var) const;
InstructionSetEnum getInstructionSet() const { return InstructionSet; }
- Operand *legalizeUndef(Operand *From, RegNumT RegNum = RegNumT::NoRegister);
+ Operand *legalizeUndef(Operand *From, RegNumT RegNum = RegNumT());
protected:
const bool NeedSandboxing;
@@ -389,8 +389,8 @@
};
using LegalMask = uint32_t;
Operand *legalize(Operand *From, LegalMask Allowed = Legal_Default,
- RegNumT RegNum = RegNumT::NoRegister);
- Variable *legalizeToReg(Operand *From, RegNumT RegNum = RegNumT::NoRegister);
+ RegNumT RegNum = RegNumT());
+ Variable *legalizeToReg(Operand *From, RegNumT RegNum = RegNumT());
/// Legalize the first source operand for use in the cmp instruction.
Operand *legalizeSrc0ForCmp(Operand *Src0, Operand *Src1);
/// Turn a pointer operand into a memory operand that can be used by a real
@@ -399,7 +399,7 @@
X86OperandMem *formMemoryOperand(Operand *Ptr, Type Ty,
bool DoLegalize = true);
- Variable *makeReg(Type Ty, RegNumT RegNum = RegNumT::NoRegister);
+ Variable *makeReg(Type Ty, RegNumT RegNum = RegNumT());
static Type stackSlotType();
static constexpr uint32_t NoSizeLimit = 0;
@@ -415,22 +415,20 @@
static Type firstTypeThatFitsSize(uint32_t Size,
uint32_t MaxSize = NoSizeLimit);
- Variable *copyToReg8(Operand *Src, RegNumT RegNum = RegNumT::NoRegister);
- Variable *copyToReg(Operand *Src, RegNumT RegNum = RegNumT::NoRegister);
+ Variable *copyToReg8(Operand *Src, RegNumT RegNum = RegNumT());
+ Variable *copyToReg(Operand *Src, RegNumT RegNum = RegNumT());
/// Returns a register containing all zeros, without affecting the FLAGS
/// register, using the best instruction for the type.
- Variable *makeZeroedRegister(Type Ty, RegNumT RegNum = RegNumT::NoRegister);
+ Variable *makeZeroedRegister(Type Ty, RegNumT RegNum = RegNumT());
/// \name Returns a vector in a register with the given constant entries.
/// @{
- Variable *makeVectorOfZeros(Type Ty, RegNumT RegNum = RegNumT::NoRegister);
- Variable *makeVectorOfOnes(Type Ty, RegNumT RegNum = RegNumT::NoRegister);
- Variable *makeVectorOfMinusOnes(Type Ty,
- RegNumT RegNum = RegNumT::NoRegister);
- Variable *makeVectorOfHighOrderBits(Type Ty,
- RegNumT RegNum = RegNumT::NoRegister);
- Variable *makeVectorOfFabsMask(Type Ty, RegNumT RegNum = RegNumT::NoRegister);
+ Variable *makeVectorOfZeros(Type Ty, RegNumT RegNum = RegNumT());
+ Variable *makeVectorOfOnes(Type Ty, RegNumT RegNum = RegNumT());
+ Variable *makeVectorOfMinusOnes(Type Ty, RegNumT RegNum = RegNumT());
+ Variable *makeVectorOfHighOrderBits(Type Ty, RegNumT RegNum = RegNumT());
+ Variable *makeVectorOfFabsMask(Type Ty, RegNumT RegNum = RegNumT());
/// @}
/// Return a memory operand corresponding to a stack allocated Variable.
@@ -676,7 +674,7 @@
/// infinite register allocation weight, and returned through the in/out Dest
/// argument.
typename Traits::Insts::Mov *_mov(Variable *&Dest, Operand *Src0,
- RegNumT RegNum = RegNumT::NoRegister) {
+ RegNumT RegNum = RegNumT()) {
if (Dest == nullptr)
Dest = makeReg(Src0->getType(), RegNum);
AutoMemorySandboxer<> _(this, &Dest, &Src0);
@@ -1000,9 +998,9 @@
/// Randomize a given immediate operand
Operand *randomizeOrPoolImmediate(Constant *Immediate,
- RegNumT RegNum = RegNumT::NoRegister);
+ RegNumT RegNum = RegNumT());
X86OperandMem *randomizeOrPoolImmediate(X86OperandMem *MemOperand,
- RegNumT RegNum = RegNumT::NoRegister);
+ RegNumT RegNum = RegNumT());
bool RandomizationPoolingPaused = false;
private:
diff --git a/src/IceTargetLoweringX86BaseImpl.h b/src/IceTargetLoweringX86BaseImpl.h
index 7f2b349..cdece9c 100644
--- a/src/IceTargetLoweringX86BaseImpl.h
+++ b/src/IceTargetLoweringX86BaseImpl.h
@@ -891,7 +891,7 @@
}
const int32_t Offset = Var->getStackOffset();
auto BaseRegNum = Var->getBaseRegNum();
- if (BaseRegNum == RegNumT::NoRegister)
+ if (BaseRegNum.hasNoValue())
BaseRegNum = getFrameOrStackReg();
// Print in the form "Offset(%reg)", taking care that:
// - Offset is never printed when it is 0
@@ -921,7 +921,7 @@
}
int32_t Offset = Var->getStackOffset();
auto BaseRegNum = Var->getBaseRegNum();
- if (Var->getBaseRegNum() == RegNumT::NoRegister)
+ if (Var->getBaseRegNum().hasNoValue())
BaseRegNum = getFrameOrStackReg();
return X86Address(Traits::getEncodedGPR(BaseRegNum), Offset,
AssemblerFixup::NoFixup);
@@ -1123,20 +1123,20 @@
for (Variable *Arg : Args) {
// Skip arguments passed in registers.
if (isVectorType(Arg->getType())) {
- if (Traits::getRegisterForXmmArgNum(NumXmmArgs) != RegNumT::NoRegister) {
+ if (Traits::getRegisterForXmmArgNum(NumXmmArgs).hasValue()) {
++NumXmmArgs;
continue;
}
} else if (isScalarFloatingType(Arg->getType())) {
if (Traits::X86_PASS_SCALAR_FP_IN_XMM &&
- Traits::getRegisterForXmmArgNum(NumXmmArgs) != RegNumT::NoRegister) {
+ Traits::getRegisterForXmmArgNum(NumXmmArgs).hasValue()) {
++NumXmmArgs;
continue;
}
} else {
assert(isScalarIntegerType(Arg->getType()));
- if (Traits::getRegisterForGprArgNum(Traits::WordType, NumGPRArgs) !=
- RegNumT::NoRegister) {
+ if (Traits::getRegisterForGprArgNum(Traits::WordType, NumGPRArgs)
+ .hasValue()) {
++NumGPRArgs;
continue;
}
@@ -1476,10 +1476,10 @@
Variable *Arg = Args[i];
Type Ty = Arg->getType();
Variable *RegisterArg = nullptr;
- auto RegNum = RegNumT::NoRegister;
+ RegNumT RegNum;
if (isVectorType(Ty)) {
RegNum = Traits::getRegisterForXmmArgNum(NumXmmArgs);
- if (RegNum == RegNumT::NoRegister) {
+ if (RegNum.hasNoValue()) {
XmmSlotsRemain = false;
continue;
}
@@ -1490,7 +1490,7 @@
continue;
}
RegNum = Traits::getRegisterForXmmArgNum(NumXmmArgs);
- if (RegNum == RegNumT::NoRegister) {
+ if (RegNum.hasNoValue()) {
XmmSlotsRemain = false;
continue;
}
@@ -1498,14 +1498,14 @@
RegisterArg = Func->makeVariable(Ty);
} else if (isScalarIntegerType(Ty)) {
RegNum = Traits::getRegisterForGprArgNum(Ty, NumGprArgs);
- if (RegNum == RegNumT::NoRegister) {
+ if (RegNum.hasNoValue()) {
GprSlotsRemain = false;
continue;
}
++NumGprArgs;
RegisterArg = Func->makeVariable(Ty);
}
- assert(RegNum != RegNumT::NoRegister);
+ assert(RegNum.hasValue());
assert(RegisterArg != nullptr);
// Replace Arg in the argument list with the home register. Then generate
// an instruction in the prolog to copy the home register to the assigned
@@ -2490,16 +2490,14 @@
const Type Ty = Arg->getType();
// The PNaCl ABI requires the width of arguments to be at least 32 bits.
assert(typeWidthInBytes(Ty) >= 4);
- if (isVectorType(Ty) && (Traits::getRegisterForXmmArgNum(XmmArgs.size()) !=
- RegNumT::NoRegister)) {
+ if (isVectorType(Ty) &&
+ Traits::getRegisterForXmmArgNum(XmmArgs.size()).hasValue()) {
XmmArgs.push_back(Arg);
} else if (isScalarFloatingType(Ty) && Traits::X86_PASS_SCALAR_FP_IN_XMM &&
- (Traits::getRegisterForXmmArgNum(XmmArgs.size()) !=
- RegNumT::NoRegister)) {
+ Traits::getRegisterForXmmArgNum(XmmArgs.size()).hasValue()) {
XmmArgs.push_back(Arg);
} else if (isScalarIntegerType(Ty) &&
- (Traits::getRegisterForGprArgNum(Ty, GprArgs.size()) !=
- RegNumT::NoRegister)) {
+ Traits::getRegisterForGprArgNum(Ty, GprArgs.size()).hasValue()) {
GprArgs.emplace_back(Ty, Arg);
} else {
// Place on stack.
@@ -6613,7 +6611,7 @@
uint32_t Offset) {
// Ensure that Loc is a stack slot.
assert(Slot->mustNotHaveReg());
- assert(Slot->getRegNum() == RegNumT::NoRegister);
+ assert(Slot->getRegNum().hasNoValue());
// Compute the location of Loc in memory.
// TODO(wala,stichnot): lea should not
// be required. The address of the stack slot is known at compile time
@@ -6642,7 +6640,7 @@
///
/// Note #1. On a 64-bit target, the "movb 4(%ebp), %ah" is likely not
/// encodable, so RegNum=Reg_ah should NOT be given as an argument. Instead,
-/// use RegNum=NoRegister and then let the caller do a separate copy into
+/// use RegNum=RegNumT() and then let the caller do a separate copy into
/// Reg_ah.
///
/// Note #2. ConstantRelocatable operands are also put through this process
@@ -6713,14 +6711,14 @@
// If we're asking for a specific physical register, make sure we're not
// allowing any other operand kinds. (This could be future work, e.g. allow
// the shl shift amount to be either an immediate or in ecx.)
- assert(RegNum == RegNumT::NoRegister || Allowed == Legal_Reg);
+ assert(RegNum.hasNoValue() || Allowed == Legal_Reg);
// Substitute with an available infinite-weight variable if possible. Only do
// this when we are not asking for a specific register, and when the
// substitution is not locked to a specific register, and when the types
// match, in order to capture the vast majority of opportunities and avoid
// corner cases in the lowering.
- if (RegNum == RegNumT::NoRegister) {
+ if (RegNum.hasNoValue()) {
if (Variable *Subst = getContext().availabilityGet(From)) {
// At this point we know there is a potential substitution available.
if (Subst->mustHaveReg() && !Subst->hasReg()) {
@@ -6781,7 +6779,7 @@
// register in x86-64.
if (Traits::Is64Bit) {
if (llvm::isa<ConstantInteger64>(Const)) {
- if (RegNum != RegNumT::NoRegister) {
+ if (RegNum.hasValue()) {
assert(Traits::getGprForType(IceType_i64, RegNum) == RegNum);
}
return copyToReg(Const, RegNum);
@@ -6864,7 +6862,7 @@
_lea(NewVar, Mem);
From = NewVar;
} else if ((!(Allowed & Legal_Mem) && !MustHaveRegister) ||
- (RegNum != RegNumT::NoRegister && RegNum != Var->getRegNum())) {
+ (RegNum.hasValue() && RegNum != Var->getRegNum())) {
From = copyToReg(From, RegNum);
}
return From;
@@ -6967,10 +6965,10 @@
// There aren't any 64-bit integer registers for x86-32.
assert(Traits::Is64Bit || Type != IceType_i64);
Variable *Reg = Func->makeVariable(Type);
- if (RegNum == RegNumT::NoRegister)
- Reg->setMustHaveReg();
- else
+ if (RegNum.hasValue())
Reg->setRegNum(RegNum);
+ else
+ Reg->setMustHaveReg();
return Reg;
}
@@ -7241,7 +7239,7 @@
// phi lowering, we should not ask for new physical registers in
// general. However, if we do meet Memory Operand during phi lowering,
// we should not blind or pool the immediates for now.
- if (RegNum != RegNumT::NoRegister)
+ if (RegNum.hasValue())
return MemOperand;
Variable *RegTemp = makeReg(IceType_i32);
IceString Label;