void destroyConstantImpl();
public:
- /// Static constructor to get a '-1' constant. This supports integers and
- /// vectors.
- ///
- static Constant *getAllOnesValue(const Type *Ty);
-
/// isNullValue - Return true if this is the value that would be returned by
/// getNullValue.
virtual bool isNullValue() const = 0;
return Val.getLimitedValue(Limit);
}
- /// @returns the value for an integer constant of the given type that has all
- /// its bits set to true.
- /// @brief Get the all ones value
- static ConstantInt *getAllOnesValue(const Type *Ty);
-
/// @brief Methods to support type inquiry through isa, cast, and dyn_cast.
static inline bool classof(const ConstantInt *) { return true; }
static bool classof(const Value *V) {
inline const VectorType *getType() const {
return reinterpret_cast<const VectorType*>(Value::getType());
}
-
- /// @returns the value for a vector integer constant of the given type that
- /// has all its bits set to true.
- /// @brief Get the all ones value
- static ConstantVector *getAllOnesValue(const VectorType *Ty);
/// isNullValue - Return true if this is the value that would be returned by
/// getNullValue. This always returns false because zero vectors are always
/// ConstantExpr::get* - Return some common constants without having to
/// specify the full Instruction::OPCODE identifier.
///
- static Constant *getNot(Constant *C);
static Constant *getAdd(Constant *C1, Constant *C2);
static Constant *getFAdd(Constant *C1, Constant *C2);
static Constant *getSub(Constant *C1, Constant *C2);
static BinaryOperator *CreateFNeg(LLVMContext &Context,
Value *Op, const std::string &Name,
BasicBlock *InsertAtEnd);
- static BinaryOperator *CreateNot(Value *Op, const std::string &Name = "",
+ static BinaryOperator *CreateNot(LLVMContext &Context,
+ Value *Op, const std::string &Name = "",
Instruction *InsertBefore = 0);
- static BinaryOperator *CreateNot(Value *Op, const std::string &Name,
+ static BinaryOperator *CreateNot(LLVMContext &Context,
+ Value *Op, const std::string &Name,
BasicBlock *InsertAtEnd);
/// isNeg, isFNeg, isNot - Check if the given Value is a
// Constant accessors
Constant* getNullValue(const Type* Ty);
+
+ /// @returns the value for an integer constant of the given type that has all
+ /// its bits set to true.
+ /// @brief Get the all ones value
Constant* getAllOnesValue(const Type* Ty);
// UndefValue accessors
ConstantInt* getConstantIntSigned(const IntegerType* Ty, int64_t V);
ConstantInt* getConstantInt(const APInt& V);
Constant* getConstantInt(const Type* Ty, const APInt& V);
- ConstantInt* getConstantIntAllOnesValue(const Type* Ty);
// ConstantPointerNull accessors
ConstantPointerNull* getConstantPointerNull(const PointerType* T);
const std::vector<Constant*>& V);
Constant* getConstantVector(const std::vector<Constant*>& V);
Constant* getConstantVector(Constant* const* Vals, unsigned NumVals);
- ConstantVector* getConstantVectorAllOnesValue(const VectorType* Ty);
// MDNode accessors
MDNode* getMDNode(Value* const* Vals, unsigned NumVals);
Value *CreateNeg(Value *V, const char *Name = "") {
if (Constant *VC = dyn_cast<Constant>(V))
return Folder.CreateNeg(VC);
- return Insert(BinaryOperator::CreateNeg(getGlobalContext(), V), Name);
+ return Insert(BinaryOperator::CreateNeg(Context, V), Name);
}
Value *CreateFNeg(Value *V, const char *Name = "") {
if (Constant *VC = dyn_cast<Constant>(V))
return Folder.CreateFNeg(VC);
- return Insert(BinaryOperator::CreateFNeg(getGlobalContext(), V), Name);
+ return Insert(BinaryOperator::CreateFNeg(Context, V), Name);
}
Value *CreateNot(Value *V, const char *Name = "") {
if (Constant *VC = dyn_cast<Constant>(V))
return Folder.CreateNot(VC);
- return Insert(BinaryOperator::CreateNot(V), Name);
+ return Insert(BinaryOperator::CreateNot(Context, V), Name);
}
//===--------------------------------------------------------------------===//
const Type *Ty = V->getType();
Ty = getEffectiveSCEVType(Ty);
- return getMulExpr(V, getConstant(ConstantInt::getAllOnesValue(Ty)));
+ return getMulExpr(V,
+ getConstant(cast<ConstantInt>(Context->getAllOnesValue(Ty))));
}
/// getNotSCEV - Return a SCEV corresponding to ~V = -1-V
const SCEV *ScalarEvolution::getNotSCEV(const SCEV *V) {
if (const SCEVConstant *VC = dyn_cast<SCEVConstant>(V))
- return getConstant(cast<ConstantInt>(ConstantExpr::getNot(VC->getValue())));
+ return getConstant(
+ cast<ConstantInt>(Context->getConstantExprNot(VC->getValue())));
const Type *Ty = V->getType();
Ty = getEffectiveSCEVType(Ty);
- const SCEV *AllOnes = getConstant(ConstantInt::getAllOnesValue(Ty));
+ const SCEV *AllOnes =
+ getConstant(cast<ConstantInt>(Context->getAllOnesValue(Ty)));
return getMinusSCEV(AllOnes, V);
}
const VectorType *Ty = VectorType::get(Type::Int32Ty, 4);
Constant *C = LoadMI->getOpcode() == X86::V_SET0 ?
MF.getFunction()->getContext()->getNullValue(Ty) :
- ConstantVector::getAllOnesValue(Ty);
+ MF.getFunction()->getContext()->getAllOnesValue(Ty);
unsigned CPI = MCP.getConstantPoolIndex(C, 16);
// Create operands to load from the constant pool entry.
case ICmpInst::ICMP_ULE:
case ICmpInst::ICMP_SLE:
case ICmpInst::ICMP_EQ:
- LV = BinaryOperator::CreateNot(LV, "notinit", CI);
+ LV = BinaryOperator::CreateNot(*Context, LV, "notinit", CI);
break;
case ICmpInst::ICMP_NE:
case ICmpInst::ICMP_UGE:
ZI->getOperand(0)->getType() == Type::Int1Ty)
return SelectInst::Create(ZI->getOperand(0),
Context->getNullValue(I.getType()),
- Context->getConstantIntAllOnesValue(I.getType()));
+ Context->getAllOnesValue(I.getType()));
}
if (isa<PHINode>(LHS))
if (ConstantInt *C = dyn_cast<ConstantInt>(Op0)) {
// Replace (-1 - A) with (~A)...
if (C->isAllOnesValue())
- return BinaryOperator::CreateNot(Op1);
+ return BinaryOperator::CreateNot(*Context, Op1);
// C - ~X == X + (1+C)
Value *X = 0;
Value *OtherOp = Op1I->getOperand(Op1I->getOperand(0) == Op0);
Value *NewNot =
- InsertNewInstBefore(BinaryOperator::CreateNot(OtherOp, "B.not"), I);
+ InsertNewInstBefore(BinaryOperator::CreateNot(*Context,
+ OtherOp, "B.not"), I);
return BinaryOperator::CreateAnd(Op0, NewNot);
}
if (RHSI->getOpcode() == Instruction::Shl &&
isa<ConstantInt>(RHSI->getOperand(0))) {
if (cast<ConstantInt>(RHSI->getOperand(0))->getValue().isPowerOf2()) {
- Constant *N1 = Context->getConstantIntAllOnesValue(I.getType());
+ Constant *N1 = Context->getAllOnesValue(I.getType());
Value *Add = InsertNewInstBefore(BinaryOperator::CreateAdd(RHSI, N1,
"tmp"), I);
return BinaryOperator::CreateAnd(Op0, Add);
Instruction *Or = BinaryOperator::CreateOr(Op0NotVal, Op1NotVal,
I.getName()+".demorgan");
InsertNewInstBefore(Or, I);
- return BinaryOperator::CreateNot(Or);
+ return BinaryOperator::CreateNot(*Context, Or);
}
{
std::swap(A, B);
}
if (A == Op0) { // A&(A^B) -> A & ~B
- Instruction *NotB = BinaryOperator::CreateNot(B, "tmp");
+ Instruction *NotB = BinaryOperator::CreateNot(*Context, B, "tmp");
InsertNewInstBefore(NotB, I);
return BinaryOperator::CreateAnd(A, NotB);
}
if (A && isOnlyUse(Op0) && isOnlyUse(Op1)) {
Value *And = InsertNewInstBefore(BinaryOperator::CreateAnd(A, B,
I.getName()+".demorgan"), I);
- return BinaryOperator::CreateNot(And);
+ return BinaryOperator::CreateNot(*Context, And);
}
}
if (dyn_castNotVal(Op0I->getOperand(1), Context)) Op0I->swapOperands();
if (Value *Op0NotVal = dyn_castNotVal(Op0I->getOperand(0), Context)) {
Instruction *NotY =
- BinaryOperator::CreateNot(Op0I->getOperand(1),
+ BinaryOperator::CreateNot(*Context, Op0I->getOperand(1),
Op0I->getOperand(1)->getName()+".not");
InsertNewInstBefore(NotY, I);
if (Op0I->getOpcode() == Instruction::And)
std::swap(A, B);
if (B == Op1) { // (A|B)^B == A & ~B
Instruction *NotB =
- InsertNewInstBefore(BinaryOperator::CreateNot(Op1, "tmp"), I);
+ InsertNewInstBefore(BinaryOperator::CreateNot(*Context,
+ Op1, "tmp"), I);
return BinaryOperator::CreateAnd(A, NotB);
}
} else if (match(Op0I, m_Xor(m_Specific(Op1), m_Value(B)), *Context)) {
if (B == Op1 && // (B&A)^A == ~B & A
!isa<ConstantInt>(Op1)) { // Canonical form is (B&C)^C
Instruction *N =
- InsertNewInstBefore(BinaryOperator::CreateNot(A, "tmp"), I);
+ InsertNewInstBefore(BinaryOperator::CreateNot(*Context, A, "tmp"), I);
return BinaryOperator::CreateAnd(N, Op1);
}
}
case ICmpInst::ICMP_EQ: { // icmp eq i1 A, B -> ~(A^B)
Instruction *Xor = BinaryOperator::CreateXor(Op0, Op1, I.getName()+"tmp");
InsertNewInstBefore(Xor, I);
- return BinaryOperator::CreateNot(Xor);
+ return BinaryOperator::CreateNot(*Context, Xor);
}
case ICmpInst::ICMP_NE: // icmp eq i1 A, B -> A^B
return BinaryOperator::CreateXor(Op0, Op1);
std::swap(Op0, Op1); // Change icmp ugt -> icmp ult
// FALL THROUGH
case ICmpInst::ICMP_ULT:{ // icmp ult i1 A, B -> ~A & B
- Instruction *Not = BinaryOperator::CreateNot(Op0, I.getName()+"tmp");
+ Instruction *Not = BinaryOperator::CreateNot(*Context,
+ Op0, I.getName()+"tmp");
InsertNewInstBefore(Not, I);
return BinaryOperator::CreateAnd(Not, Op1);
}
std::swap(Op0, Op1); // Change icmp sgt -> icmp slt
// FALL THROUGH
case ICmpInst::ICMP_SLT: { // icmp slt i1 A, B -> A & ~B
- Instruction *Not = BinaryOperator::CreateNot(Op1, I.getName()+"tmp");
+ Instruction *Not = BinaryOperator::CreateNot(*Context,
+ Op1, I.getName()+"tmp");
InsertNewInstBefore(Not, I);
return BinaryOperator::CreateAnd(Not, Op0);
}
std::swap(Op0, Op1); // Change icmp uge -> icmp ule
// FALL THROUGH
case ICmpInst::ICMP_ULE: { // icmp ule i1 A, B -> ~A | B
- Instruction *Not = BinaryOperator::CreateNot(Op0, I.getName()+"tmp");
+ Instruction *Not = BinaryOperator::CreateNot(*Context,
+ Op0, I.getName()+"tmp");
InsertNewInstBefore(Not, I);
return BinaryOperator::CreateOr(Not, Op1);
}
std::swap(Op0, Op1); // Change icmp sge -> icmp sle
// FALL THROUGH
case ICmpInst::ICMP_SLE: { // icmp sle i1 A, B -> A | ~B
- Instruction *Not = BinaryOperator::CreateNot(Op1, I.getName()+"tmp");
+ Instruction *Not = BinaryOperator::CreateNot(*Context,
+ Op1, I.getName()+"tmp");
InsertNewInstBefore(Not, I);
return BinaryOperator::CreateOr(Not, Op0);
}
// (x <u 2147483648) -> (x >s -1) -> true if sign bit clear
if (CI->isMinValue(true))
return new ICmpInst(*Context, ICmpInst::ICMP_SGT, Op0,
- Context->getConstantIntAllOnesValue(Op0->getType()));
+ Context->getAllOnesValue(Op0->getType()));
}
break;
case ICmpInst::ICMP_UGT:
if (isSignedExt) {
// We're performing an unsigned comp with a sign extended value.
// This is true if the input is >= 0. [aka >s -1]
- Constant *NegOne = Context->getConstantIntAllOnesValue(SrcTy);
+ Constant *NegOne = Context->getAllOnesValue(SrcTy);
Result = InsertNewInstBefore(new ICmpInst(*Context, ICmpInst::ICMP_SGT,
LHSCIOp, NegOne, ICI.getName()), ICI);
} else {
"ICmp should be folded!");
if (Constant *CI = dyn_cast<Constant>(Result))
return ReplaceInstUsesWith(ICI, Context->getConstantExprNot(CI));
- return BinaryOperator::CreateNot(Result);
+ return BinaryOperator::CreateNot(*Context, Result);
}
Instruction *InstCombiner::visitShl(BinaryOperator &I) {
// Canonicalize sign-extend from i1 to a select.
if (Src->getType() == Type::Int1Ty)
return SelectInst::Create(Src,
- Context->getConstantIntAllOnesValue(CI.getType()),
+ Context->getAllOnesValue(CI.getType()),
Context->getNullValue(CI.getType()));
// See if the value being truncated is already sign extended. If so, just
true/*SExt*/, "tmp", ICI);
if (Pred == ICmpInst::ICMP_SGT)
- In = InsertNewInstBefore(BinaryOperator::CreateNot(In,
+ In = InsertNewInstBefore(BinaryOperator::CreateNot(*Context, In,
In->getName()+".not"), *ICI);
return ReplaceInstUsesWith(SI, In);
} else {
// Change: A = select B, false, C --> A = and !B, C
Value *NotCond =
- InsertNewInstBefore(BinaryOperator::CreateNot(CondVal,
+ InsertNewInstBefore(BinaryOperator::CreateNot(*Context, CondVal,
"not."+CondVal->getName()), SI);
return BinaryOperator::CreateAnd(NotCond, FalseVal);
}
} else {
// Change: A = select B, C, true --> A = or !B, C
Value *NotCond =
- InsertNewInstBefore(BinaryOperator::CreateNot(CondVal,
+ InsertNewInstBefore(BinaryOperator::CreateNot(*Context, CondVal,
"not."+CondVal->getName()), SI);
return BinaryOperator::CreateOr(NotCond, TrueVal);
}
} else if (TrueValC->isZero() && FalseValC->getValue() == 1) {
// select C, 0, 1 -> zext !C to int
Value *NotCond =
- InsertNewInstBefore(BinaryOperator::CreateNot(CondVal,
+ InsertNewInstBefore(BinaryOperator::CreateNot(*Context, CondVal,
"not."+CondVal->getName()), SI);
return CastInst::Create(Instruction::ZExt, NotCond, SI.getType());
}
switch (BO->getOpcode()) {
case Instruction::And: {
// "and i32 %a, %b" EQ -1 then %a EQ -1 and %b EQ -1
- ConstantInt *CI = ConstantInt::getAllOnesValue(Ty);
+ ConstantInt *CI = cast<ConstantInt>(Context->getAllOnesValue(Ty));
if (Canonical == CI) {
add(CI, Op0, ICmpInst::ICMP_EQ, NewContext);
add(CI, Op1, ICmpInst::ICMP_EQ, NewContext);
Constant *Zero = Context->getNullValue(Ty);
Constant *One = ConstantInt::get(Ty, 1);
- ConstantInt *AllOnes = ConstantInt::getAllOnesValue(Ty);
+ ConstantInt *AllOnes = cast<ConstantInt>(Context->getAllOnesValue(Ty));
switch (Opcode) {
default: break;
static Instruction *LowerNegateToMultiply(Instruction *Neg,
std::map<AssertingVH<>, unsigned> &ValueRankMap,
LLVMContext *Context) {
- Constant *Cst = Context->getConstantIntAllOnesValue(Neg->getType());
+ Constant *Cst = Context->getAllOnesValue(Neg->getType());
Instruction *Res = BinaryOperator::CreateMul(Neg->getOperand(1), Cst, "",Neg);
ValueRankMap.erase(Neg);
return Context->getNullValue(X->getType());
} else if (Opcode == Instruction::Or) { // ...|X|~X = -1
++NumAnnihil;
- return Context->getConstantIntAllOnesValue(X->getType());
+ return Context->getAllOnesValue(X->getType());
}
}
}
if (I.getOpcode() == Instruction::And)
markConstant(IV, &I, Context->getNullValue(I.getType()));
else if (const VectorType *PT = dyn_cast<VectorType>(I.getType()))
- markConstant(IV, &I, Context->getConstantVectorAllOnesValue(PT));
+ markConstant(IV, &I, Context->getAllOnesValue(PT));
else
markConstant(IV, &I,
- Context->getConstantIntAllOnesValue(I.getType()));
+ Context->getAllOnesValue(I.getType()));
return;
} else {
if (I.getOpcode() == Instruction::And) {
// undef | X -> -1. X could be -1.
if (const VectorType *PTy = dyn_cast<VectorType>(ITy))
markForcedConstant(LV, I,
- Context->getConstantVectorAllOnesValue(PTy));
+ Context->getAllOnesValue(PTy));
else
- markForcedConstant(LV, I, Context->getConstantIntAllOnesValue(ITy));
+ markForcedConstant(LV, I, Context->getAllOnesValue(ITy));
return true;
case Instruction::SDiv:
// abs(x) -> x >s -1 ? x : -x
Value *Op = CI->getOperand(1);
Value *Pos = B.CreateICmpSGT(Op,
- Context->getConstantIntAllOnesValue(Op->getType()),
+ Context->getAllOnesValue(Op->getType()),
"ispos");
Value *Neg = B.CreateNeg(Op, "neg");
return B.CreateSelect(Pos, Op, Neg);
// If we need to invert the condition in the pred block to match, do so now.
if (InvertPredCond) {
Value *NewCond =
- BinaryOperator::CreateNot(PBI->getCondition(),
+ BinaryOperator::CreateNot(*BI->getParent()->getContext(),
+ PBI->getCondition(),
PBI->getCondition()->getName()+".not", PBI);
PBI->setCondition(NewCond);
BasicBlock *OldTrue = PBI->getSuccessor(0);
// Make sure we get to CommonDest on True&True directions.
Value *PBICond = PBI->getCondition();
if (PBIOp)
- PBICond = BinaryOperator::CreateNot(PBICond,
+ PBICond = BinaryOperator::CreateNot(*Context, PBICond,
PBICond->getName()+".not",
PBI);
Value *BICond = BI->getCondition();
if (BIOp)
- BICond = BinaryOperator::CreateNot(BICond,
+ BICond = BinaryOperator::CreateNot(*Context, BICond,
BICond->getName()+".not",
PBI);
// Merge the conditions.
return false;
}
-Constant *Constant::getAllOnesValue(const Type *Ty) {
- if (const IntegerType* ITy = dyn_cast<IntegerType>(Ty))
- return ConstantInt::get(APInt::getAllOnesValue(ITy->getBitWidth()));
- return ConstantVector::getAllOnesValue(cast<VectorType>(Ty));
-}
-
-// Static constructor to create an integral constant with all bits set
-ConstantInt *ConstantInt::getAllOnesValue(const Type *Ty) {
- if (const IntegerType* ITy = dyn_cast<IntegerType>(Ty))
- return ConstantInt::get(APInt::getAllOnesValue(ITy->getBitWidth()));
- return 0;
-}
-
-/// @returns the value for a vector integer constant of the given type that
-/// has all its bits set to true.
-/// @brief Get the all ones value
-ConstantVector *ConstantVector::getAllOnesValue(const VectorType *Ty) {
- std::vector<Constant*> Elts;
- Elts.resize(Ty->getNumElements(),
- ConstantInt::getAllOnesValue(Ty->getElementType()));
- assert(Elts[0] && "Not a vector integer type!");
- return cast<ConstantVector>(ConstantVector::get(Elts));
-}
-
-
/// getVectorElements - This method, which is only valid on constant of vector
/// type, returns the elements of the vector in the specified smallvector.
/// This handles breaking down a vector undef into undef elements, etc. For
return cast<InsertValueConstantExpr>(this)->Indices;
}
-Constant *ConstantExpr::getNot(Constant *C) {
- assert(C->getType()->isIntOrIntVector() &&
- "Cannot NOT a nonintegral value!");
- return get(Instruction::Xor, C,
- Constant::getAllOnesValue(C->getType()));
-}
Constant *ConstantExpr::getAdd(Constant *C1, Constant *C2) {
return get(Instruction::Add, C1, C2);
}
Op->getType(), Name, InsertAtEnd);
}
-BinaryOperator *BinaryOperator::CreateNot(Value *Op, const std::string &Name,
+BinaryOperator *BinaryOperator::CreateNot(LLVMContext &Context,
+ Value *Op, const std::string &Name,
Instruction *InsertBefore) {
Constant *C;
if (const VectorType *PTy = dyn_cast<VectorType>(Op->getType())) {
- C = ConstantInt::getAllOnesValue(PTy->getElementType());
+ C = Context.getAllOnesValue(PTy->getElementType());
C = ConstantVector::get(std::vector<Constant*>(PTy->getNumElements(), C));
} else {
- C = ConstantInt::getAllOnesValue(Op->getType());
+ C = Context.getAllOnesValue(Op->getType());
}
return new BinaryOperator(Instruction::Xor, Op, C,
Op->getType(), Name, InsertBefore);
}
-BinaryOperator *BinaryOperator::CreateNot(Value *Op, const std::string &Name,
+BinaryOperator *BinaryOperator::CreateNot(LLVMContext &Context,
+ Value *Op, const std::string &Name,
BasicBlock *InsertAtEnd) {
Constant *AllOnes;
if (const VectorType *PTy = dyn_cast<VectorType>(Op->getType())) {
// Create a vector of all ones values.
- Constant *Elt = ConstantInt::getAllOnesValue(PTy->getElementType());
+ Constant *Elt = Context.getAllOnesValue(PTy->getElementType());
AllOnes =
ConstantVector::get(std::vector<Constant*>(PTy->getNumElements(), Elt));
} else {
- AllOnes = ConstantInt::getAllOnesValue(Op->getType());
+ AllOnes = Context.getAllOnesValue(Op->getType());
}
return new BinaryOperator(Instruction::Xor, Op, AllOnes,
}
Constant* LLVMContext::getAllOnesValue(const Type* Ty) {
- return Constant::getAllOnesValue(Ty);
+ if (const IntegerType* ITy = dyn_cast<IntegerType>(Ty))
+ return getConstantInt(APInt::getAllOnesValue(ITy->getBitWidth()));
+
+ std::vector<Constant*> Elts;
+ const VectorType* VTy = cast<VectorType>(Ty);
+ Elts.resize(VTy->getNumElements(), getAllOnesValue(VTy->getElementType()));
+ assert(Elts[0] && "Not a vector integer type!");
+ return cast<ConstantVector>(getConstantVector(Elts));
}
// UndefValue accessors.
return ConstantInt::get(Ty, V);
}
-ConstantInt* LLVMContext::getConstantIntAllOnesValue(const Type* Ty) {
- return ConstantInt::getAllOnesValue(Ty);
-}
-
-
// ConstantPointerNull accessors.
ConstantPointerNull* LLVMContext::getConstantPointerNull(const PointerType* T) {
return ConstantPointerNull::get(T);
}
Constant* LLVMContext::getConstantExprNot(Constant* C) {
- return ConstantExpr::getNot(C);
+ assert(C->getType()->isIntOrIntVector() &&
+ "Cannot NOT a nonintegral value!");
+ return getConstantExpr(Instruction::Xor, C, getAllOnesValue(C->getType()));
}
Constant* LLVMContext::getConstantExprAdd(Constant* C1, Constant* C2) {
return ConstantVector::get(Vals, NumVals);
}
-ConstantVector* LLVMContext::getConstantVectorAllOnesValue(
- const VectorType* Ty) {
- return ConstantVector::getAllOnesValue(Ty);
-}
-
// MDNode accessors
MDNode* LLVMContext::getMDNode(Value* const* Vals, unsigned NumVals) {
return MDNode::get(Vals, NumVals);