static inline bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::Add ||
I->getOpcode() == Instruction::Sub ||
- I->getOpcode() == Instruction::Mul;
+ I->getOpcode() == Instruction::Mul ||
+ I->getOpcode() == Instruction::Shl;
}
static inline bool classof(const ConstantExpr *CE) {
return CE->getOpcode() == Instruction::Add ||
CE->getOpcode() == Instruction::Sub ||
- CE->getOpcode() == Instruction::Mul;
- }
- static inline bool classof(const Value *V) {
- return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
- (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)));
- }
-};
-
-/// AddOperator - Utility class for integer addition operators.
-///
-class AddOperator : public OverflowingBinaryOperator {
- ~AddOperator(); // do not implement
-public:
- static inline bool classof(const AddOperator *) { return true; }
- static inline bool classof(const Instruction *I) {
- return I->getOpcode() == Instruction::Add;
- }
- static inline bool classof(const ConstantExpr *CE) {
- return CE->getOpcode() == Instruction::Add;
- }
- static inline bool classof(const Value *V) {
- return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
- (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)));
- }
-};
-
-/// SubOperator - Utility class for integer subtraction operators.
-///
-class SubOperator : public OverflowingBinaryOperator {
- ~SubOperator(); // do not implement
-public:
- static inline bool classof(const SubOperator *) { return true; }
- static inline bool classof(const Instruction *I) {
- return I->getOpcode() == Instruction::Sub;
- }
- static inline bool classof(const ConstantExpr *CE) {
- return CE->getOpcode() == Instruction::Sub;
- }
- static inline bool classof(const Value *V) {
- return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
- (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)));
- }
-};
-
-/// MulOperator - Utility class for integer multiplication operators.
-///
-class MulOperator : public OverflowingBinaryOperator {
- ~MulOperator(); // do not implement
-public:
- static inline bool classof(const MulOperator *) { return true; }
- static inline bool classof(const Instruction *I) {
- return I->getOpcode() == Instruction::Mul;
- }
- static inline bool classof(const ConstantExpr *CE) {
- return CE->getOpcode() == Instruction::Mul;
+ CE->getOpcode() == Instruction::Mul ||
+ CE->getOpcode() == Instruction::Shl;
}
static inline bool classof(const Value *V) {
return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
return SubclassOptionalData & IsExact;
}
- static inline bool classof(const ConstantExpr *CE) {
- return CE->getOpcode() == Instruction::SDiv ||
- CE->getOpcode() == Instruction::UDiv;
+ static bool isPossiblyExactOpcode(unsigned OpC) {
+ return OpC == Instruction::SDiv ||
+ OpC == Instruction::UDiv ||
+ OpC == Instruction::AShr ||
+ OpC == Instruction::LShr;
}
- static inline bool classof(const Instruction *I) {
- return I->getOpcode() == Instruction::SDiv ||
- I->getOpcode() == Instruction::UDiv;
- }
- static inline bool classof(const Value *V) {
- return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
- (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)));
- }
-};
-
-/// SDivOperator - An Operator with opcode Instruction::SDiv.
-///
-class SDivOperator : public PossiblyExactOperator {
-public:
- // Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const SDivOperator *) { return true; }
static inline bool classof(const ConstantExpr *CE) {
- return CE->getOpcode() == Instruction::SDiv;
+ return isPossiblyExactOpcode(CE->getOpcode());
}
static inline bool classof(const Instruction *I) {
- return I->getOpcode() == Instruction::SDiv;
+ return isPossiblyExactOpcode(I->getOpcode());
}
static inline bool classof(const Value *V) {
return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
(isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)));
}
};
+
-/// UDivOperator - An Operator with opcode Instruction::UDiv.
-///
-class UDivOperator : public PossiblyExactOperator {
+
+/// ConcreteOperator - A helper template for defining operators for individual
+/// opcodes.
+template<typename SuperClass, unsigned Opc>
+class ConcreteOperator : public SuperClass {
+ ~ConcreteOperator(); // DO NOT IMPLEMENT
public:
- // Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const UDivOperator *) { return true; }
- static inline bool classof(const ConstantExpr *CE) {
- return CE->getOpcode() == Instruction::UDiv;
+ static inline bool classof(const ConcreteOperator<SuperClass, Opc> *) {
+ return true;
}
static inline bool classof(const Instruction *I) {
- return I->getOpcode() == Instruction::UDiv;
+ return I->getOpcode() == Opc;
+ }
+ static inline bool classof(const ConstantExpr *CE) {
+ return CE->getOpcode() == Opc;
}
static inline bool classof(const Value *V) {
return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
- (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)));
+ (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)));
}
};
+
+class AddOperator
+ : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Add> {};
+class SubOperator
+ : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Sub> {};
+class MulOperator
+ : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Mul> {};
+class ShlOperator
+ : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Shl> {};
+
+
+class SDivOperator
+ : public ConcreteOperator<PossiblyExactOperator, Instruction::SDiv> {};
+class UDivOperator
+ : public ConcreteOperator<PossiblyExactOperator, Instruction::UDiv> {};
+class AShrOperator
+ : public ConcreteOperator<PossiblyExactOperator, Instruction::AShr> {};
+class LShrOperator
+ : public ConcreteOperator<PossiblyExactOperator, Instruction::LShr> {};
+
-class GEPOperator : public Operator {
+
+class GEPOperator
+ : public ConcreteOperator<Operator, Instruction::GetElementPtr> {
enum {
IsInBounds = (1 << 0)
};
- ~GEPOperator(); // do not implement
-
friend class GetElementPtrInst;
friend class ConstantExpr;
void setIsInBounds(bool B) {
/// value, just potentially different types.
bool hasAllZeroIndices() const {
for (const_op_iterator I = idx_begin(), E = idx_end(); I != E; ++I) {
- if (Constant *C = dyn_cast<Constant>(I))
- if (C->isNullValue())
+ if (ConstantInt *C = dyn_cast<ConstantInt>(I))
+ if (C->isZero())
continue;
return false;
}
}
return true;
}
-
-
- // Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const GEPOperator *) { return true; }
- static inline bool classof(const GetElementPtrInst *) { return true; }
- static inline bool classof(const ConstantExpr *CE) {
- return CE->getOpcode() == Instruction::GetElementPtr;
- }
- static inline bool classof(const Instruction *I) {
- return I->getOpcode() == Instruction::GetElementPtr;
- }
- static inline bool classof(const Value *V) {
- return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
- (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)));
- }
};
} // End llvm namespace
//
//===----------------------------------------------------------------------===//
//
-// This file implements the Constant* classes.
+// This file implements the Constant *classes.
//
//===----------------------------------------------------------------------===//
}
}
-Constant* Constant::getIntegerValue(const Type *Ty, const APInt &V) {
+Constant *Constant::getIntegerValue(const Type *Ty, const APInt &V) {
const Type *ScalarTy = Ty->getScalarType();
// Create the base integer constant.
return C;
}
-Constant* Constant::getAllOnesValue(const Type *Ty) {
+Constant *Constant::getAllOnesValue(const Type *Ty) {
if (const IntegerType *ITy = dyn_cast<IntegerType>(Ty))
return ConstantInt::get(Ty->getContext(),
APInt::getAllOnesValue(ITy->getBitWidth()));
return Slot;
}
-Constant* ConstantInt::get(const Type* Ty, uint64_t V, bool isSigned) {
+Constant *ConstantInt::get(const Type* Ty, uint64_t V, bool isSigned) {
Constant *C = get(cast<IntegerType>(Ty->getScalarType()),
V, isSigned);
return get(Ty, V, true);
}
-Constant* ConstantInt::get(const Type* Ty, const APInt& V) {
+Constant *ConstantInt::get(const Type* Ty, const APInt& V) {
ConstantInt *C = get(Ty->getContext(), V);
assert(C->getType() == Ty->getScalarType() &&
"ConstantInt type doesn't match the type implied by its value!");
/// get() - This returns a constant fp for the specified value in the
/// specified type. This should only be used for simple constant values like
/// 2.0/1.0 etc, that are known-valid both as double and as the target format.
-Constant* ConstantFP::get(const Type* Ty, double V) {
+Constant *ConstantFP::get(const Type* Ty, double V) {
LLVMContext &Context = Ty->getContext();
APFloat FV(V);
}
-Constant* ConstantFP::get(const Type* Ty, StringRef Str) {
+Constant *ConstantFP::get(const Type* Ty, StringRef Str) {
LLVMContext &Context = Ty->getContext();
APFloat FV(*TypeToFloatSemantics(Ty->getScalarType()), Str);
}
-Constant* ConstantFP::getZeroValueForNegation(const Type* Ty) {
+Constant *ConstantFP::getZeroValueForNegation(const Type* Ty) {
if (const VectorType *PTy = dyn_cast<VectorType>(Ty))
if (PTy->getElementType()->isFloatingPointTy()) {
std::vector<Constant*> zeros(PTy->getNumElements(),
}
-Constant* ConstantArray::get(const ArrayType* T, Constant* const* Vals,
+Constant *ConstantArray::get(const ArrayType* T, Constant *const* Vals,
unsigned NumVals) {
// FIXME: make this the primary ctor method.
return get(T, std::vector<Constant*>(Vals, Vals+NumVals));
/// Otherwise, the length parameter specifies how much of the string to use
/// and it won't be null terminated.
///
-Constant* ConstantArray::get(LLVMContext &Context, StringRef Str,
+Constant *ConstantArray::get(LLVMContext &Context, StringRef Str,
bool AddNull) {
std::vector<Constant*> ElementVals;
ElementVals.reserve(Str.size() + size_t(AddNull));
}
// ConstantStruct accessors.
-Constant* ConstantStruct::get(const StructType* T,
+Constant *ConstantStruct::get(const StructType* T,
const std::vector<Constant*>& V) {
LLVMContextImpl* pImpl = T->getContext().pImpl;
return ConstantAggregateZero::get(T);
}
-Constant* ConstantStruct::get(LLVMContext &Context,
+Constant *ConstantStruct::get(LLVMContext &Context,
const std::vector<Constant*>& V, bool packed) {
std::vector<const Type*> StructEls;
StructEls.reserve(V.size());
return get(StructType::get(Context, StructEls, packed), V);
}
-Constant* ConstantStruct::get(LLVMContext &Context,
- Constant* const *Vals, unsigned NumVals,
+Constant *ConstantStruct::get(LLVMContext &Context,
+ Constant *const *Vals, unsigned NumVals,
bool Packed) {
// FIXME: make this the primary ctor method.
return get(Context, std::vector<Constant*>(Vals, Vals+NumVals), Packed);
}
// ConstantVector accessors.
-Constant* ConstantVector::get(const VectorType* T,
+Constant *ConstantVector::get(const VectorType* T,
const std::vector<Constant*>& V) {
assert(!V.empty() && "Vectors can't be empty");
LLVMContext &Context = T->getContext();
return pImpl->VectorConstants.getOrCreate(T, V);
}
-Constant* ConstantVector::get(const std::vector<Constant*>& V) {
+Constant *ConstantVector::get(const std::vector<Constant*>& V) {
assert(!V.empty() && "Cannot infer type if V is empty");
return get(VectorType::get(V.front()->getType(),V.size()), V);
}
-Constant* ConstantVector::get(Constant* const* Vals, unsigned NumVals) {
+Constant *ConstantVector::get(Constant *const* Vals, unsigned NumVals) {
// FIXME: make this the primary ctor method.
return get(std::vector<Constant*>(Vals, Vals+NumVals));
}
-Constant* ConstantExpr::getNSWNeg(Constant* C) {
+Constant *ConstantExpr::getNSWNeg(Constant *C) {
assert(C->getType()->isIntOrIntVectorTy() &&
"Cannot NEG a nonintegral value!");
return getNSWSub(ConstantFP::getZeroValueForNegation(C->getType()), C);
}
-Constant* ConstantExpr::getNUWNeg(Constant* C) {
+Constant *ConstantExpr::getNUWNeg(Constant *C) {
assert(C->getType()->isIntOrIntVectorTy() &&
"Cannot NEG a nonintegral value!");
return getNUWSub(ConstantFP::getZeroValueForNegation(C->getType()), C);
}
-Constant* ConstantExpr::getNSWAdd(Constant* C1, Constant* C2) {
+Constant *ConstantExpr::getNSWAdd(Constant *C1, Constant *C2) {
return getTy(C1->getType(), Instruction::Add, C1, C2,
OverflowingBinaryOperator::NoSignedWrap);
}
-Constant* ConstantExpr::getNUWAdd(Constant* C1, Constant* C2) {
+Constant *ConstantExpr::getNUWAdd(Constant *C1, Constant *C2) {
return getTy(C1->getType(), Instruction::Add, C1, C2,
OverflowingBinaryOperator::NoUnsignedWrap);
}
-Constant* ConstantExpr::getNSWSub(Constant* C1, Constant* C2) {
+Constant *ConstantExpr::getNSWSub(Constant *C1, Constant *C2) {
return getTy(C1->getType(), Instruction::Sub, C1, C2,
OverflowingBinaryOperator::NoSignedWrap);
}
-Constant* ConstantExpr::getNUWSub(Constant* C1, Constant* C2) {
+Constant *ConstantExpr::getNUWSub(Constant *C1, Constant *C2) {
return getTy(C1->getType(), Instruction::Sub, C1, C2,
OverflowingBinaryOperator::NoUnsignedWrap);
}
-Constant* ConstantExpr::getNSWMul(Constant* C1, Constant* C2) {
+Constant *ConstantExpr::getNSWMul(Constant *C1, Constant *C2) {
return getTy(C1->getType(), Instruction::Mul, C1, C2,
OverflowingBinaryOperator::NoSignedWrap);
}
-Constant* ConstantExpr::getNUWMul(Constant* C1, Constant* C2) {
+Constant *ConstantExpr::getNUWMul(Constant *C1, Constant *C2) {
return getTy(C1->getType(), Instruction::Mul, C1, C2,
OverflowingBinaryOperator::NoUnsignedWrap);
}
-Constant* ConstantExpr::getExactSDiv(Constant* C1, Constant* C2) {
+Constant *ConstantExpr::getNSWShl(Constant *C1, Constant *C2) {
+ return getTy(C1->getType(), Instruction::Shl, C1, C2,
+ OverflowingBinaryOperator::NoSignedWrap);
+}
+
+Constant *ConstantExpr::getNUWShl(Constant *C1, Constant *C2) {
+ return getTy(C1->getType(), Instruction::Shl, C1, C2,
+ OverflowingBinaryOperator::NoUnsignedWrap);
+}
+
+Constant *ConstantExpr::getExactSDiv(Constant *C1, Constant *C2) {
return getTy(C1->getType(), Instruction::SDiv, C1, C2,
PossiblyExactOperator::IsExact);
}
-Constant* ConstantExpr::getExactUDiv(Constant* C1, Constant* C2) {
+Constant *ConstantExpr::getExactUDiv(Constant *C1, Constant *C2) {
return getTy(C1->getType(), Instruction::UDiv, C1, C2,
PossiblyExactOperator::IsExact);
}
+Constant *ConstantExpr::getExactAShr(Constant *C1, Constant *C2) {
+ return getTy(C1->getType(), Instruction::AShr, C1, C2,
+ PossiblyExactOperator::IsExact);
+}
+
+Constant *ConstantExpr::getExactLShr(Constant *C1, Constant *C2) {
+ return getTy(C1->getType(), Instruction::LShr, C1, C2,
+ PossiblyExactOperator::IsExact);
+}
+
+
// Utility function for determining if a ConstantExpr is a CastOp or not. This
// can't be inline because we don't want to #include Instruction.h into
// Constant.h
/// operands replaced with the specified values. The specified operands must
/// match count and type with the existing ones.
Constant *ConstantExpr::
-getWithOperands(Constant* const *Ops, unsigned NumOps) const {
+getWithOperands(Constant *const *Ops, unsigned NumOps) const {
assert(NumOps == getNumOperands() && "Operand count mismatch!");
bool AnyChange = false;
for (unsigned i = 0; i != NumOps; ++i) {
return getTy(C1->getType(), Opcode, C1, C2, Flags);
}
-Constant* ConstantExpr::getSizeOf(const Type* Ty) {
+Constant *ConstantExpr::getSizeOf(const Type* Ty) {
// sizeof is implemented as: (i64) gep (Ty*)null, 1
// Note that a non-inbounds gep is used, as null isn't within any object.
Constant *GEPIdx = ConstantInt::get(Type::getInt32Ty(Ty->getContext()), 1);
Type::getInt64Ty(Ty->getContext()));
}
-Constant* ConstantExpr::getAlignOf(const Type* Ty) {
+Constant *ConstantExpr::getAlignOf(const Type* Ty) {
// alignof is implemented as: (i64) gep ({i1,Ty}*)null, 0, 1
// Note that a non-inbounds gep is used, as null isn't within any object.
const Type *AligningTy = StructType::get(Ty->getContext(),
Type::getInt64Ty(Ty->getContext()));
}
-Constant* ConstantExpr::getOffsetOf(const StructType* STy, unsigned FieldNo) {
+Constant *ConstantExpr::getOffsetOf(const StructType* STy, unsigned FieldNo) {
return getOffsetOf(STy, ConstantInt::get(Type::getInt32Ty(STy->getContext()),
FieldNo));
}
-Constant* ConstantExpr::getOffsetOf(const Type* Ty, Constant *FieldNo) {
+Constant *ConstantExpr::getOffsetOf(const Type* Ty, Constant *FieldNo) {
// offsetof is implemented as: (i64) gep (Ty*)null, 0, FieldNo
// Note that a non-inbounds gep is used, as null isn't within any object.
Constant *GEPIdx[] = {
return getExtractValueTy(ReqTy, Agg, IdxList, NumIdx);
}
-Constant* ConstantExpr::getNeg(Constant* C) {
+Constant *ConstantExpr::getNeg(Constant *C) {
assert(C->getType()->isIntOrIntVectorTy() &&
"Cannot NEG a nonintegral value!");
return get(Instruction::Sub,
C);
}
-Constant* ConstantExpr::getFNeg(Constant* C) {
+Constant *ConstantExpr::getFNeg(Constant *C) {
assert(C->getType()->isFPOrFPVectorTy() &&
"Cannot FNEG a non-floating-point value!");
return get(Instruction::FSub,
C);
}
-Constant* ConstantExpr::getNot(Constant* C) {
+Constant *ConstantExpr::getNot(Constant *C) {
assert(C->getType()->isIntOrIntVectorTy() &&
"Cannot NOT a nonintegral value!");
return get(Instruction::Xor, C, Constant::getAllOnesValue(C->getType()));
}
-Constant* ConstantExpr::getAdd(Constant* C1, Constant* C2) {
+Constant *ConstantExpr::getAdd(Constant *C1, Constant *C2) {
return get(Instruction::Add, C1, C2);
}
-Constant* ConstantExpr::getFAdd(Constant* C1, Constant* C2) {
+Constant *ConstantExpr::getFAdd(Constant *C1, Constant *C2) {
return get(Instruction::FAdd, C1, C2);
}
-Constant* ConstantExpr::getSub(Constant* C1, Constant* C2) {
+Constant *ConstantExpr::getSub(Constant *C1, Constant *C2) {
return get(Instruction::Sub, C1, C2);
}
-Constant* ConstantExpr::getFSub(Constant* C1, Constant* C2) {
+Constant *ConstantExpr::getFSub(Constant *C1, Constant *C2) {
return get(Instruction::FSub, C1, C2);
}
-Constant* ConstantExpr::getMul(Constant* C1, Constant* C2) {
+Constant *ConstantExpr::getMul(Constant *C1, Constant *C2) {
return get(Instruction::Mul, C1, C2);
}
-Constant* ConstantExpr::getFMul(Constant* C1, Constant* C2) {
+Constant *ConstantExpr::getFMul(Constant *C1, Constant *C2) {
return get(Instruction::FMul, C1, C2);
}
-Constant* ConstantExpr::getUDiv(Constant* C1, Constant* C2) {
+Constant *ConstantExpr::getUDiv(Constant *C1, Constant *C2) {
return get(Instruction::UDiv, C1, C2);
}
-Constant* ConstantExpr::getSDiv(Constant* C1, Constant* C2) {
+Constant *ConstantExpr::getSDiv(Constant *C1, Constant *C2) {
return get(Instruction::SDiv, C1, C2);
}
-Constant* ConstantExpr::getFDiv(Constant* C1, Constant* C2) {
+Constant *ConstantExpr::getFDiv(Constant *C1, Constant *C2) {
return get(Instruction::FDiv, C1, C2);
}
-Constant* ConstantExpr::getURem(Constant* C1, Constant* C2) {
+Constant *ConstantExpr::getURem(Constant *C1, Constant *C2) {
return get(Instruction::URem, C1, C2);
}
-Constant* ConstantExpr::getSRem(Constant* C1, Constant* C2) {
+Constant *ConstantExpr::getSRem(Constant *C1, Constant *C2) {
return get(Instruction::SRem, C1, C2);
}
-Constant* ConstantExpr::getFRem(Constant* C1, Constant* C2) {
+Constant *ConstantExpr::getFRem(Constant *C1, Constant *C2) {
return get(Instruction::FRem, C1, C2);
}
-Constant* ConstantExpr::getAnd(Constant* C1, Constant* C2) {
+Constant *ConstantExpr::getAnd(Constant *C1, Constant *C2) {
return get(Instruction::And, C1, C2);
}
-Constant* ConstantExpr::getOr(Constant* C1, Constant* C2) {
+Constant *ConstantExpr::getOr(Constant *C1, Constant *C2) {
return get(Instruction::Or, C1, C2);
}
-Constant* ConstantExpr::getXor(Constant* C1, Constant* C2) {
+Constant *ConstantExpr::getXor(Constant *C1, Constant *C2) {
return get(Instruction::Xor, C1, C2);
}
-Constant* ConstantExpr::getShl(Constant* C1, Constant* C2) {
+Constant *ConstantExpr::getShl(Constant *C1, Constant *C2) {
return get(Instruction::Shl, C1, C2);
}
-Constant* ConstantExpr::getLShr(Constant* C1, Constant* C2) {
+Constant *ConstantExpr::getLShr(Constant *C1, Constant *C2) {
return get(Instruction::LShr, C1, C2);
}
-Constant* ConstantExpr::getAShr(Constant* C1, Constant* C2) {
+Constant *ConstantExpr::getAShr(Constant *C1, Constant *C2) {
return get(Instruction::AShr, C1, C2);
}