}
#include "llvm/Instruction.def"
-
- /// CreateNSWAdd - Create an Add operator with the NSW flag set.
- ///
- static BinaryOperator *CreateNSWAdd(Value *V1, Value *V2,
- const Twine &Name = "") {
- BinaryOperator *BO = CreateAdd(V1, V2, Name);
- BO->setHasNoSignedWrap(true);
- return BO;
- }
- static BinaryOperator *CreateNSWAdd(Value *V1, Value *V2,
- const Twine &Name, BasicBlock *BB) {
- BinaryOperator *BO = CreateAdd(V1, V2, Name, BB);
- BO->setHasNoSignedWrap(true);
- return BO;
- }
- static BinaryOperator *CreateNSWAdd(Value *V1, Value *V2,
- const Twine &Name, Instruction *I) {
- BinaryOperator *BO = CreateAdd(V1, V2, Name, I);
- BO->setHasNoSignedWrap(true);
- return BO;
- }
-
- /// CreateNUWAdd - Create an Add operator with the NUW flag set.
- ///
- static BinaryOperator *CreateNUWAdd(Value *V1, Value *V2,
- const Twine &Name = "") {
- BinaryOperator *BO = CreateAdd(V1, V2, Name);
- BO->setHasNoUnsignedWrap(true);
- return BO;
- }
- static BinaryOperator *CreateNUWAdd(Value *V1, Value *V2,
- const Twine &Name, BasicBlock *BB) {
- BinaryOperator *BO = CreateAdd(V1, V2, Name, BB);
- BO->setHasNoUnsignedWrap(true);
- return BO;
- }
- static BinaryOperator *CreateNUWAdd(Value *V1, Value *V2,
- const Twine &Name, Instruction *I) {
- BinaryOperator *BO = CreateAdd(V1, V2, Name, I);
- BO->setHasNoUnsignedWrap(true);
- return BO;
- }
-
- /// CreateNSWSub - Create an Sub operator with the NSW flag set.
- ///
- static BinaryOperator *CreateNSWSub(Value *V1, Value *V2,
- const Twine &Name = "") {
- BinaryOperator *BO = CreateSub(V1, V2, Name);
- BO->setHasNoSignedWrap(true);
- return BO;
- }
- static BinaryOperator *CreateNSWSub(Value *V1, Value *V2,
- const Twine &Name, BasicBlock *BB) {
- BinaryOperator *BO = CreateSub(V1, V2, Name, BB);
- BO->setHasNoSignedWrap(true);
- return BO;
- }
- static BinaryOperator *CreateNSWSub(Value *V1, Value *V2,
- const Twine &Name, Instruction *I) {
- BinaryOperator *BO = CreateSub(V1, V2, Name, I);
- BO->setHasNoSignedWrap(true);
- return BO;
- }
-
- /// CreateNUWSub - Create an Sub operator with the NUW flag set.
- ///
- static BinaryOperator *CreateNUWSub(Value *V1, Value *V2,
- const Twine &Name = "") {
- BinaryOperator *BO = CreateSub(V1, V2, Name);
- BO->setHasNoUnsignedWrap(true);
- return BO;
- }
- static BinaryOperator *CreateNUWSub(Value *V1, Value *V2,
- const Twine &Name, BasicBlock *BB) {
- BinaryOperator *BO = CreateSub(V1, V2, Name, BB);
- BO->setHasNoUnsignedWrap(true);
- return BO;
- }
- static BinaryOperator *CreateNUWSub(Value *V1, Value *V2,
- const Twine &Name, Instruction *I) {
- BinaryOperator *BO = CreateSub(V1, V2, Name, I);
- BO->setHasNoUnsignedWrap(true);
- return BO;
- }
-
- /// CreateNSWMul - Create a Mul operator with the NSW flag set.
- ///
- static BinaryOperator *CreateNSWMul(Value *V1, Value *V2,
- const Twine &Name = "") {
- BinaryOperator *BO = CreateMul(V1, V2, Name);
+ static BinaryOperator *CreateNSW(BinaryOps Opc, Value *V1, Value *V2,
+ const Twine &Name = "") {
+ BinaryOperator *BO = Create(Opc, V1, V2, Name);
BO->setHasNoSignedWrap(true);
return BO;
}
- static BinaryOperator *CreateNSWMul(Value *V1, Value *V2,
- const Twine &Name, BasicBlock *BB) {
- BinaryOperator *BO = CreateMul(V1, V2, Name, BB);
+ static BinaryOperator *CreateNSW(BinaryOps Opc, Value *V1, Value *V2,
+ const Twine &Name, BasicBlock *BB) {
+ BinaryOperator *BO = Create(Opc, V1, V2, Name, BB);
BO->setHasNoSignedWrap(true);
return BO;
}
- static BinaryOperator *CreateNSWMul(Value *V1, Value *V2,
- const Twine &Name, Instruction *I) {
- BinaryOperator *BO = CreateMul(V1, V2, Name, I);
+ static BinaryOperator *CreateNSW(BinaryOps Opc, Value *V1, Value *V2,
+ const Twine &Name, Instruction *I) {
+ BinaryOperator *BO = Create(Opc, V1, V2, Name, I);
BO->setHasNoSignedWrap(true);
return BO;
}
-
- /// CreateNUWMul - Create a Mul operator with the NUW flag set.
- ///
- static BinaryOperator *CreateNUWMul(Value *V1, Value *V2,
- const Twine &Name = "") {
- BinaryOperator *BO = CreateMul(V1, V2, Name);
+
+ static BinaryOperator *CreateNUW(BinaryOps Opc, Value *V1, Value *V2,
+ const Twine &Name = "") {
+ BinaryOperator *BO = Create(Opc, V1, V2, Name);
BO->setHasNoUnsignedWrap(true);
return BO;
}
- static BinaryOperator *CreateNUWMul(Value *V1, Value *V2,
- const Twine &Name, BasicBlock *BB) {
- BinaryOperator *BO = CreateMul(V1, V2, Name, BB);
+ static BinaryOperator *CreateNUW(BinaryOps Opc, Value *V1, Value *V2,
+ const Twine &Name, BasicBlock *BB) {
+ BinaryOperator *BO = Create(Opc, V1, V2, Name, BB);
BO->setHasNoUnsignedWrap(true);
return BO;
}
- static BinaryOperator *CreateNUWMul(Value *V1, Value *V2,
- const Twine &Name, Instruction *I) {
- BinaryOperator *BO = CreateMul(V1, V2, Name, I);
+ static BinaryOperator *CreateNUW(BinaryOps Opc, Value *V1, Value *V2,
+ const Twine &Name, Instruction *I) {
+ BinaryOperator *BO = Create(Opc, V1, V2, Name, I);
BO->setHasNoUnsignedWrap(true);
return BO;
}
-
- /// CreateExactUDiv - Create a UDiv operator with the exact flag set.
- ///
- static BinaryOperator *CreateExactUDiv(Value *V1, Value *V2,
- const Twine &Name = "") {
- BinaryOperator *BO = CreateUDiv(V1, V2, Name);
- BO->setIsExact(true);
- return BO;
- }
- static BinaryOperator *CreateExactUDiv(Value *V1, Value *V2,
- const Twine &Name, BasicBlock *BB) {
- BinaryOperator *BO = CreateUDiv(V1, V2, Name, BB);
- BO->setIsExact(true);
- return BO;
- }
- static BinaryOperator *CreateExactUDiv(Value *V1, Value *V2,
- const Twine &Name, Instruction *I) {
- BinaryOperator *BO = CreateUDiv(V1, V2, Name, I);
+
+ static BinaryOperator *CreateExact(BinaryOps Opc, Value *V1, Value *V2,
+ const Twine &Name = "") {
+ BinaryOperator *BO = Create(Opc, V1, V2, Name);
BO->setIsExact(true);
return BO;
}
-
- /// CreateExactSDiv - Create an SDiv operator with the exact flag set.
- ///
- static BinaryOperator *CreateExactSDiv(Value *V1, Value *V2,
- const Twine &Name = "") {
- BinaryOperator *BO = CreateSDiv(V1, V2, Name);
+ static BinaryOperator *CreateExact(BinaryOps Opc, Value *V1, Value *V2,
+ const Twine &Name, BasicBlock *BB) {
+ BinaryOperator *BO = Create(Opc, V1, V2, Name, BB);
BO->setIsExact(true);
return BO;
}
- static BinaryOperator *CreateExactSDiv(Value *V1, Value *V2,
- const Twine &Name, BasicBlock *BB) {
- BinaryOperator *BO = CreateSDiv(V1, V2, Name, BB);
+ static BinaryOperator *CreateExact(BinaryOps Opc, Value *V1, Value *V2,
+ const Twine &Name, Instruction *I) {
+ BinaryOperator *BO = Create(Opc, V1, V2, Name, I);
BO->setIsExact(true);
return BO;
}
- static BinaryOperator *CreateExactSDiv(Value *V1, Value *V2,
- const Twine &Name, Instruction *I) {
- BinaryOperator *BO = CreateSDiv(V1, V2, Name, I);
- BO->setIsExact(true);
- return BO;
+
+#define DEFINE_HELPERS(OPC, NUWNSWEXACT) \
+ static BinaryOperator *Create ## NUWNSWEXACT ## OPC \
+ (Value *V1, Value *V2, const Twine &Name = "") { \
+ return Create ## NUWNSWEXACT(Instruction::OPC, V1, V2, Name); \
+ } \
+ static BinaryOperator *Create ## NUWNSWEXACT ## OPC \
+ (Value *V1, Value *V2, const Twine &Name, BasicBlock *BB) { \
+ return Create ## NUWNSWEXACT(Instruction::OPC, V1, V2, Name, BB); \
+ } \
+ static BinaryOperator *Create ## NUWNSWEXACT ## OPC \
+ (Value *V1, Value *V2, const Twine &Name, Instruction *I) { \
+ return Create ## NUWNSWEXACT(Instruction::OPC, V1, V2, Name, I); \
}
+ DEFINE_HELPERS(Add, NSW) // CreateNSWAdd
+ DEFINE_HELPERS(Add, NUW) // CreateNUWAdd
+ DEFINE_HELPERS(Sub, NSW) // CreateNSWSub
+ DEFINE_HELPERS(Sub, NUW) // CreateNUWSub
+ DEFINE_HELPERS(Mul, NSW) // CreateNSWMul
+ DEFINE_HELPERS(Mul, NUW) // CreateNUWMul
+ DEFINE_HELPERS(Shl, NSW) // CreateNSWShl
+ DEFINE_HELPERS(Shl, NUW) // CreateNUWShl
+
+ DEFINE_HELPERS(SDiv, Exact) // CreateExactSDiv
+ DEFINE_HELPERS(UDiv, Exact) // CreateExactUDiv
+ DEFINE_HELPERS(AShr, Exact) // CreateExactAShr
+ DEFINE_HELPERS(LShr, Exact) // CreateExactLShr
+
+#undef DEFINE_HELPERS
+
/// Helper functions to construct and inspect unary operations (NEG and NOT)
/// via binary operators SUB and XOR:
///
return Insert(Folder.CreateFMul(LC, RC), Name);
return Insert(BinaryOperator::CreateFMul(LHS, RHS), Name);
}
- Value *CreateUDiv(Value *LHS, Value *RHS, const Twine &Name = "") {
+ Value *CreateUDiv(Value *LHS, Value *RHS, const Twine &Name = "",
+ bool isExact = false) {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
- return Insert(Folder.CreateUDiv(LC, RC), Name);
- return Insert(BinaryOperator::CreateUDiv(LHS, RHS), Name);
+ return Insert(Folder.CreateUDiv(LC, RC, isExact), Name);
+ if (!isExact)
+ return Insert(BinaryOperator::CreateUDiv(LHS, RHS), Name);
+ return Insert(BinaryOperator::CreateExactUDiv(LHS, RHS), Name);
}
Value *CreateExactUDiv(Value *LHS, Value *RHS, const Twine &Name = "") {
- if (Constant *LC = dyn_cast<Constant>(LHS))
- if (Constant *RC = dyn_cast<Constant>(RHS))
- return Insert(Folder.CreateExactUDiv(LC, RC), Name);
- return Insert(BinaryOperator::CreateExactUDiv(LHS, RHS), Name);
+ return CreateUDiv(LHS, RHS, Name, true);
}
- Value *CreateSDiv(Value *LHS, Value *RHS, const Twine &Name = "") {
+ Value *CreateSDiv(Value *LHS, Value *RHS, const Twine &Name = "",
+ bool isExact = false) {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
- return Insert(Folder.CreateSDiv(LC, RC), Name);
- return Insert(BinaryOperator::CreateSDiv(LHS, RHS), Name);
+ return Insert(Folder.CreateSDiv(LC, RC, isExact), Name);
+ if (!isExact)
+ return Insert(BinaryOperator::CreateSDiv(LHS, RHS), Name);
+ return Insert(BinaryOperator::CreateExactSDiv(LHS, RHS), Name);
}
Value *CreateExactSDiv(Value *LHS, Value *RHS, const Twine &Name = "") {
- if (Constant *LC = dyn_cast<Constant>(LHS))
- if (Constant *RC = dyn_cast<Constant>(RHS))
- return Insert(Folder.CreateExactSDiv(LC, RC), Name);
- return Insert(BinaryOperator::CreateExactSDiv(LHS, RHS), Name);
+ return CreateSDiv(LHS, RHS, Name, true);
}
Value *CreateFDiv(Value *LHS, Value *RHS, const Twine &Name = "") {
if (Constant *LC = dyn_cast<Constant>(LHS))
return Insert(BinaryOperator::CreateShl(LHS, RHS), Name);
}
Value *CreateShl(Value *LHS, const APInt &RHS, const Twine &Name = "") {
- Constant *RHSC = ConstantInt::get(LHS->getType(), RHS);
- if (Constant *LC = dyn_cast<Constant>(LHS))
- return Insert(Folder.CreateShl(LC, RHSC), Name);
- return Insert(BinaryOperator::CreateShl(LHS, RHSC), Name);
+ return CreateShl(LHS, ConstantInt::get(LHS->getType(), RHS), Name);
}
Value *CreateShl(Value *LHS, uint64_t RHS, const Twine &Name = "") {
- Constant *RHSC = ConstantInt::get(LHS->getType(), RHS);
- if (Constant *LC = dyn_cast<Constant>(LHS))
- return Insert(Folder.CreateShl(LC, RHSC), Name);
- return Insert(BinaryOperator::CreateShl(LHS, RHSC), Name);
+ return CreateShl(LHS, ConstantInt::get(LHS->getType(), RHS), Name);
}
- Value *CreateLShr(Value *LHS, Value *RHS, const Twine &Name = "") {
+ Value *CreateLShr(Value *LHS, Value *RHS, const Twine &Name = "",
+ bool isExact = false) {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
- return Insert(Folder.CreateLShr(LC, RC), Name);
- return Insert(BinaryOperator::CreateLShr(LHS, RHS), Name);
+ return Insert(Folder.CreateLShr(LC, RC, isExact), Name);
+ if (!isExact)
+ return Insert(BinaryOperator::CreateLShr(LHS, RHS), Name);
+ return Insert(BinaryOperator::CreateExactLShr(LHS, RHS), Name);
}
- Value *CreateLShr(Value *LHS, const APInt &RHS, const Twine &Name = "") {
- Constant *RHSC = ConstantInt::get(LHS->getType(), RHS);
- if (Constant *LC = dyn_cast<Constant>(LHS))
- return Insert(Folder.CreateLShr(LC, RHSC), Name);
- return Insert(BinaryOperator::CreateLShr(LHS, RHSC), Name);
+ Value *CreateLShr(Value *LHS, const APInt &RHS, const Twine &Name = "",
+ bool isExact = false) {
+ return CreateLShr(LHS, ConstantInt::get(LHS->getType(), RHS), Name,isExact);
}
- Value *CreateLShr(Value *LHS, uint64_t RHS, const Twine &Name = "") {
- Constant *RHSC = ConstantInt::get(LHS->getType(), RHS);
- if (Constant *LC = dyn_cast<Constant>(LHS))
- return Insert(Folder.CreateLShr(LC, RHSC), Name);
- return Insert(BinaryOperator::CreateLShr(LHS, RHSC), Name);
+ Value *CreateLShr(Value *LHS, uint64_t RHS, const Twine &Name = "",
+ bool isExact = false) {
+ return CreateLShr(LHS, ConstantInt::get(LHS->getType(), RHS), Name,isExact);
}
- Value *CreateAShr(Value *LHS, Value *RHS, const Twine &Name = "") {
+ Value *CreateAShr(Value *LHS, Value *RHS, const Twine &Name = "",
+ bool isExact = false) {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
- return Insert(Folder.CreateAShr(LC, RC), Name);
- return Insert(BinaryOperator::CreateAShr(LHS, RHS), Name);
+ return Insert(Folder.CreateAShr(LC, RC, isExact), Name);
+ if (!isExact)
+ return Insert(BinaryOperator::CreateAShr(LHS, RHS), Name);
+ return Insert(BinaryOperator::CreateExactAShr(LHS, RHS), Name);
}
- Value *CreateAShr(Value *LHS, const APInt &RHS, const Twine &Name = "") {
- Constant *RHSC = ConstantInt::get(LHS->getType(), RHS);
- if (Constant *LC = dyn_cast<Constant>(LHS))
- return Insert(Folder.CreateAShr(LC, RHSC), Name);
- return Insert(BinaryOperator::CreateAShr(LHS, RHSC), Name);
+ Value *CreateAShr(Value *LHS, const APInt &RHS, const Twine &Name = "",
+ bool isExact = false) {
+ return CreateAShr(LHS, ConstantInt::get(LHS->getType(), RHS), Name,isExact);
}
- Value *CreateAShr(Value *LHS, uint64_t RHS, const Twine &Name = "") {
- Constant *RHSC = ConstantInt::get(LHS->getType(), RHS);
- if (Constant *LC = dyn_cast<Constant>(LHS))
- return Insert(Folder.CreateAShr(LC, RHSC), Name);
- return Insert(BinaryOperator::CreateAShr(LHS, RHSC), Name);
+ Value *CreateAShr(Value *LHS, uint64_t RHS, const Twine &Name = "",
+ bool isExact = false) {
+ return CreateAShr(LHS, ConstantInt::get(LHS->getType(), RHS), Name,isExact);
}
Value *CreateAnd(Value *LHS, Value *RHS, const Twine &Name = "") {
return Insert(BinaryOperator::CreateAnd(LHS, RHS), Name);
}
Value *CreateAnd(Value *LHS, const APInt &RHS, const Twine &Name = "") {
- Constant *RHSC = ConstantInt::get(LHS->getType(), RHS);
- if (Constant *LC = dyn_cast<Constant>(LHS))
- return Insert(Folder.CreateAnd(LC, RHSC), Name);
- return Insert(BinaryOperator::CreateAnd(LHS, RHSC), Name);
+ return CreateAnd(LHS, ConstantInt::get(LHS->getType(), RHS), Name);
}
Value *CreateAnd(Value *LHS, uint64_t RHS, const Twine &Name = "") {
- Constant *RHSC = ConstantInt::get(LHS->getType(), RHS);
- if (Constant *LC = dyn_cast<Constant>(LHS))
- return Insert(Folder.CreateAnd(LC, RHSC), Name);
- return Insert(BinaryOperator::CreateAnd(LHS, RHSC), Name);
+ return CreateAnd(LHS, ConstantInt::get(LHS->getType(), RHS), Name);
}
Value *CreateOr(Value *LHS, Value *RHS, const Twine &Name = "") {
return Insert(BinaryOperator::CreateOr(LHS, RHS), Name);
}
Value *CreateOr(Value *LHS, const APInt &RHS, const Twine &Name = "") {
- Constant *RHSC = ConstantInt::get(LHS->getType(), RHS);
- if (Constant *LC = dyn_cast<Constant>(LHS))
- return Insert(Folder.CreateOr(LC, RHSC), Name);
- return Insert(BinaryOperator::CreateOr(LHS, RHSC), Name);
+ return CreateOr(LHS, ConstantInt::get(LHS->getType(), RHS), Name);
}
Value *CreateOr(Value *LHS, uint64_t RHS, const Twine &Name = "") {
- Constant *RHSC = ConstantInt::get(LHS->getType(), RHS);
- if (Constant *LC = dyn_cast<Constant>(LHS))
- return Insert(Folder.CreateOr(LC, RHSC), Name);
- return Insert(BinaryOperator::CreateOr(LHS, RHSC), Name);
+ return CreateOr(LHS, ConstantInt::get(LHS->getType(), RHS), Name);
}
Value *CreateXor(Value *LHS, Value *RHS, const Twine &Name = "") {
return Insert(BinaryOperator::CreateXor(LHS, RHS), Name);
}
Value *CreateXor(Value *LHS, const APInt &RHS, const Twine &Name = "") {
- Constant *RHSC = ConstantInt::get(LHS->getType(), RHS);
- if (Constant *LC = dyn_cast<Constant>(LHS))
- return Insert(Folder.CreateXor(LC, RHSC), Name);
- return Insert(BinaryOperator::CreateXor(LHS, RHSC), Name);
+ return CreateXor(LHS, ConstantInt::get(LHS->getType(), RHS), Name);
}
Value *CreateXor(Value *LHS, uint64_t RHS, const Twine &Name = "") {
- Constant *RHSC = ConstantInt::get(LHS->getType(), RHS);
- if (Constant *LC = dyn_cast<Constant>(LHS))
- return Insert(Folder.CreateXor(LC, RHSC), Name);
- return Insert(BinaryOperator::CreateXor(LHS, RHSC), Name);
+ return CreateXor(LHS, ConstantInt::get(LHS->getType(), RHS), Name);
}
Value *CreateBinOp(Instruction::BinaryOps Opc,
}
template<typename Class>
-struct leaf_ty {
+struct class_match {
template<typename ITy>
bool match(ITy *V) { return isa<Class>(V); }
};
/// m_Value() - Match an arbitrary value and ignore it.
-inline leaf_ty<Value> m_Value() { return leaf_ty<Value>(); }
+inline class_match<Value> m_Value() { return class_match<Value>(); }
/// m_ConstantInt() - Match an arbitrary ConstantInt and ignore it.
-inline leaf_ty<ConstantInt> m_ConstantInt() { return leaf_ty<ConstantInt>(); }
+inline class_match<ConstantInt> m_ConstantInt() {
+ return class_match<ConstantInt>();
+}
+/// m_Undef() - Match an arbitrary undef constant.
+inline class_match<UndefValue> m_Undef() { return class_match<UndefValue>(); }
+inline class_match<Constant> m_Constant() { return class_match<Constant>(); }
+
+struct match_zero {
+ template<typename ITy>
+ bool match(ITy *V) {
+ if (const Constant *C = dyn_cast<Constant>(V))
+ return C->isNullValue();
+ return false;
+ }
+};
+
+/// m_Zero() - Match an arbitrary zero/null constant. This includes
+/// zero_initializer for vectors and ConstantPointerNull for pointers.
+inline match_zero m_Zero() { return match_zero(); }
+
+
+struct apint_match {
+ const APInt *&Res;
+ apint_match(const APInt *&R) : Res(R) {}
+ template<typename ITy>
+ bool match(ITy *V) {
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
+ Res = &CI->getValue();
+ return true;
+ }
+ if (ConstantVector *CV = dyn_cast<ConstantVector>(V))
+ if (ConstantInt *CI = cast_or_null<ConstantInt>(CV->getSplatValue())) {
+ Res = &CI->getValue();
+ return true;
+ }
+ return false;
+ }
+};
+
+/// m_APInt - Match a ConstantInt or splatted ConstantVector, binding the
+/// specified pointer to the contained APInt.
+inline apint_match m_APInt(const APInt *&Res) { return Res; }
+
+
template<int64_t Val>
-struct constantint_ty {
+struct constantint_match {
template<typename ITy>
bool match(ITy *V) {
if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
}
};
-/// m_ConstantInt(int64_t) - Match a ConstantInt with a specific value
-/// and ignore it.
+/// m_ConstantInt<int64_t> - Match a ConstantInt with a specific value.
template<int64_t Val>
-inline constantint_ty<Val> m_ConstantInt() {
- return constantint_ty<Val>();
+inline constantint_match<Val> m_ConstantInt() {
+ return constantint_match<Val>();
}
-struct undef_ty {
- template<typename ITy>
- bool match(ITy *V) {
- return isa<UndefValue>(V);
- }
-};
-
-/// m_Undef() - Match an arbitrary undef constant.
-inline undef_ty m_Undef() { return undef_ty(); }
-
-struct zero_ty {
+/// cst_pred_ty - This helper class is used to match scalar and vector constants
+/// that satisfy a specified predicate.
+template<typename Predicate>
+struct cst_pred_ty : public Predicate {
template<typename ITy>
bool match(ITy *V) {
- if (const Constant *C = dyn_cast<Constant>(V))
- return C->isNullValue();
+ if (const ConstantInt *CI = dyn_cast<ConstantInt>(V))
+ return this->isValue(CI->getValue());
+ if (const ConstantVector *CV = dyn_cast<ConstantVector>(V))
+ if (ConstantInt *CI = cast_or_null<ConstantInt>(CV->getSplatValue()))
+ return this->isValue(CI->getValue());
return false;
}
};
-
-/// m_Zero() - Match an arbitrary zero/null constant.
-inline zero_ty m_Zero() { return zero_ty(); }
-
-struct one_ty {
+
+/// api_pred_ty - This helper class is used to match scalar and vector constants
+/// that satisfy a specified predicate, and bind them to an APInt.
+template<typename Predicate>
+struct api_pred_ty : public Predicate {
+ const APInt *&Res;
+ api_pred_ty(const APInt *&R) : Res(R) {}
template<typename ITy>
bool match(ITy *V) {
if (const ConstantInt *CI = dyn_cast<ConstantInt>(V))
- return CI->isOne();
+ if (this->isValue(CI->getValue())) {
+ Res = &CI->getValue();
+ return true;
+ }
if (const ConstantVector *CV = dyn_cast<ConstantVector>(V))
if (ConstantInt *CI = cast_or_null<ConstantInt>(CV->getSplatValue()))
- return CI->isOne();
+ if (this->isValue(CI->getValue())) {
+ Res = &CI->getValue();
+ return true;
+ }
return false;
}
};
-
-/// m_One() - Match an integer 1 or a vector with all elements equal to 1.
-inline one_ty m_One() { return one_ty(); }
-struct all_ones_ty {
- template<typename ITy>
- bool match(ITy *V) {
- if (const ConstantInt *C = dyn_cast<ConstantInt>(V))
- return C->isAllOnesValue();
- if (const ConstantVector *C = dyn_cast<ConstantVector>(V))
- return C->isAllOnesValue();
- return false;
- }
+
+struct is_one {
+ bool isValue(const APInt &C) { return C == 1; }
};
+/// m_One() - Match an integer 1 or a vector with all elements equal to 1.
+inline cst_pred_ty<is_one> m_One() { return cst_pred_ty<is_one>(); }
+inline api_pred_ty<is_one> m_One(const APInt *&V) { return V; }
+
+struct is_all_ones {
+ bool isValue(const APInt &C) { return C.isAllOnesValue(); }
+};
+
/// m_AllOnes() - Match an integer or vector with all bits set to true.
-inline all_ones_ty m_AllOnes() { return all_ones_ty(); }
+inline cst_pred_ty<is_all_ones> m_AllOnes() {return cst_pred_ty<is_all_ones>();}
+inline api_pred_ty<is_all_ones> m_AllOnes(const APInt *&V) { return V; }
-struct signbit_ty {
- template<typename ITy>
- bool match(ITy *V) {
- if (const ConstantInt *CI = dyn_cast<ConstantInt>(V))
- return CI->getValue().isSignBit();
- if (const ConstantVector *CV = dyn_cast<ConstantVector>(V))
- if (ConstantInt *CI = cast_or_null<ConstantInt>(CV->getSplatValue()))
- return CI->getValue().isSignBit();
- return false;
- }
+struct is_sign_bit {
+ bool isValue(const APInt &C) { return C.isSignBit(); }
};
/// m_SignBit() - Match an integer or vector with only the sign bit(s) set.
-inline signbit_ty m_SignBit() { return signbit_ty(); }
+inline cst_pred_ty<is_sign_bit> m_SignBit() {return cst_pred_ty<is_sign_bit>();}
+inline api_pred_ty<is_sign_bit> m_SignBit(const APInt *&V) { return V; }
+struct is_power2 {
+ bool isValue(const APInt &C) { return C.isPowerOf2(); }
+};
+
+/// m_Power2() - Match an integer or vector power of 2.
+inline cst_pred_ty<is_power2> m_Power2() { return cst_pred_ty<is_power2>(); }
+inline api_pred_ty<is_power2> m_Power2(const APInt *&V) { return V; }
template<typename Class>
struct bind_ty {
/// m_ConstantInt - Match a ConstantInt, capturing the value if we match.
inline bind_ty<ConstantInt> m_ConstantInt(ConstantInt *&CI) { return CI; }
+/// m_Constant - Match a Constant, capturing the value if we match.
+inline bind_ty<Constant> m_Constant(Constant *&C) { return C; }
+
/// specificval_ty - Match a specified Value*.
struct specificval_ty {
const Value *Val;
// Matchers for specific binary operators.
//
-template<typename LHS_t, typename RHS_t,
- unsigned Opcode, typename ConcreteTy = BinaryOperator>
+template<typename LHS_t, typename RHS_t, unsigned Opcode>
struct BinaryOp_match {
LHS_t L;
RHS_t R;
template<typename OpTy>
bool match(OpTy *V) {
if (V->getValueID() == Value::InstructionVal + Opcode) {
- ConcreteTy *I = cast<ConcreteTy>(V);
- return I->getOpcode() == Opcode && L.match(I->getOperand(0)) &&
- R.match(I->getOperand(1));
+ BinaryOperator *I = cast<BinaryOperator>(V);
+ return L.match(I->getOperand(0)) && R.match(I->getOperand(1));
}
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
return CE->getOpcode() == Opcode && L.match(CE->getOperand(0)) &&
};
template<typename LHS, typename RHS>
-inline BinaryOp_match<LHS, RHS, Instruction::Add> m_Add(const LHS &L,
- const RHS &R) {
+inline BinaryOp_match<LHS, RHS, Instruction::Add>
+m_Add(const LHS &L, const RHS &R) {
return BinaryOp_match<LHS, RHS, Instruction::Add>(L, R);
}
template<typename LHS, typename RHS>
-inline BinaryOp_match<LHS, RHS, Instruction::FAdd> m_FAdd(const LHS &L,
- const RHS &R) {
+inline BinaryOp_match<LHS, RHS, Instruction::FAdd>
+m_FAdd(const LHS &L, const RHS &R) {
return BinaryOp_match<LHS, RHS, Instruction::FAdd>(L, R);
}
template<typename LHS, typename RHS>
-inline BinaryOp_match<LHS, RHS, Instruction::Sub> m_Sub(const LHS &L,
- const RHS &R) {
+inline BinaryOp_match<LHS, RHS, Instruction::Sub>
+m_Sub(const LHS &L, const RHS &R) {
return BinaryOp_match<LHS, RHS, Instruction::Sub>(L, R);
}
template<typename LHS, typename RHS>
-inline BinaryOp_match<LHS, RHS, Instruction::FSub> m_FSub(const LHS &L,
- const RHS &R) {
+inline BinaryOp_match<LHS, RHS, Instruction::FSub>
+m_FSub(const LHS &L, const RHS &R) {
return BinaryOp_match<LHS, RHS, Instruction::FSub>(L, R);
}
template<typename LHS, typename RHS>
-inline BinaryOp_match<LHS, RHS, Instruction::Mul> m_Mul(const LHS &L,
- const RHS &R) {
+inline BinaryOp_match<LHS, RHS, Instruction::Mul>
+m_Mul(const LHS &L, const RHS &R) {
return BinaryOp_match<LHS, RHS, Instruction::Mul>(L, R);
}
template<typename LHS, typename RHS>
-inline BinaryOp_match<LHS, RHS, Instruction::FMul> m_FMul(const LHS &L,
- const RHS &R) {
+inline BinaryOp_match<LHS, RHS, Instruction::FMul>
+m_FMul(const LHS &L, const RHS &R) {
return BinaryOp_match<LHS, RHS, Instruction::FMul>(L, R);
}
template<typename LHS, typename RHS>
-inline BinaryOp_match<LHS, RHS, Instruction::UDiv> m_UDiv(const LHS &L,
- const RHS &R) {
+inline BinaryOp_match<LHS, RHS, Instruction::UDiv>
+m_UDiv(const LHS &L, const RHS &R) {
return BinaryOp_match<LHS, RHS, Instruction::UDiv>(L, R);
}
template<typename LHS, typename RHS>
-inline BinaryOp_match<LHS, RHS, Instruction::SDiv> m_SDiv(const LHS &L,
- const RHS &R) {
+inline BinaryOp_match<LHS, RHS, Instruction::SDiv>
+m_SDiv(const LHS &L, const RHS &R) {
return BinaryOp_match<LHS, RHS, Instruction::SDiv>(L, R);
}
template<typename LHS, typename RHS>
-inline BinaryOp_match<LHS, RHS, Instruction::FDiv> m_FDiv(const LHS &L,
- const RHS &R) {
+inline BinaryOp_match<LHS, RHS, Instruction::FDiv>
+m_FDiv(const LHS &L, const RHS &R) {
return BinaryOp_match<LHS, RHS, Instruction::FDiv>(L, R);
}
template<typename LHS, typename RHS>
-inline BinaryOp_match<LHS, RHS, Instruction::URem> m_URem(const LHS &L,
- const RHS &R) {
+inline BinaryOp_match<LHS, RHS, Instruction::URem>
+m_URem(const LHS &L, const RHS &R) {
return BinaryOp_match<LHS, RHS, Instruction::URem>(L, R);
}
template<typename LHS, typename RHS>
-inline BinaryOp_match<LHS, RHS, Instruction::SRem> m_SRem(const LHS &L,
- const RHS &R) {
+inline BinaryOp_match<LHS, RHS, Instruction::SRem>
+m_SRem(const LHS &L, const RHS &R) {
return BinaryOp_match<LHS, RHS, Instruction::SRem>(L, R);
}
template<typename LHS, typename RHS>
-inline BinaryOp_match<LHS, RHS, Instruction::FRem> m_FRem(const LHS &L,
- const RHS &R) {
+inline BinaryOp_match<LHS, RHS, Instruction::FRem>
+m_FRem(const LHS &L, const RHS &R) {
return BinaryOp_match<LHS, RHS, Instruction::FRem>(L, R);
}
template<typename LHS, typename RHS>
-inline BinaryOp_match<LHS, RHS, Instruction::And> m_And(const LHS &L,
- const RHS &R) {
+inline BinaryOp_match<LHS, RHS, Instruction::And>
+m_And(const LHS &L, const RHS &R) {
return BinaryOp_match<LHS, RHS, Instruction::And>(L, R);
}
template<typename LHS, typename RHS>
-inline BinaryOp_match<LHS, RHS, Instruction::Or> m_Or(const LHS &L,
- const RHS &R) {
+inline BinaryOp_match<LHS, RHS, Instruction::Or>
+m_Or(const LHS &L, const RHS &R) {
return BinaryOp_match<LHS, RHS, Instruction::Or>(L, R);
}
template<typename LHS, typename RHS>
-inline BinaryOp_match<LHS, RHS, Instruction::Xor> m_Xor(const LHS &L,
- const RHS &R) {
+inline BinaryOp_match<LHS, RHS, Instruction::Xor>
+m_Xor(const LHS &L, const RHS &R) {
return BinaryOp_match<LHS, RHS, Instruction::Xor>(L, R);
}
template<typename LHS, typename RHS>
-inline BinaryOp_match<LHS, RHS, Instruction::Shl> m_Shl(const LHS &L,
- const RHS &R) {
+inline BinaryOp_match<LHS, RHS, Instruction::Shl>
+m_Shl(const LHS &L, const RHS &R) {
return BinaryOp_match<LHS, RHS, Instruction::Shl>(L, R);
}
template<typename LHS, typename RHS>
-inline BinaryOp_match<LHS, RHS, Instruction::LShr> m_LShr(const LHS &L,
- const RHS &R) {
+inline BinaryOp_match<LHS, RHS, Instruction::LShr>
+m_LShr(const LHS &L, const RHS &R) {
return BinaryOp_match<LHS, RHS, Instruction::LShr>(L, R);
}
template<typename LHS, typename RHS>
-inline BinaryOp_match<LHS, RHS, Instruction::AShr> m_AShr(const LHS &L,
- const RHS &R) {
+inline BinaryOp_match<LHS, RHS, Instruction::AShr>
+m_AShr(const LHS &L, const RHS &R) {
return BinaryOp_match<LHS, RHS, Instruction::AShr>(L, R);
}
//===----------------------------------------------------------------------===//
-// Matchers for either AShr or LShr .. for convenience
-//
-template<typename LHS_t, typename RHS_t, typename ConcreteTy = BinaryOperator>
-struct Shr_match {
- LHS_t L;
- RHS_t R;
-
- Shr_match(const LHS_t &LHS, const RHS_t &RHS) : L(LHS), R(RHS) {}
-
- template<typename OpTy>
- bool match(OpTy *V) {
- if (V->getValueID() == Value::InstructionVal + Instruction::LShr ||
- V->getValueID() == Value::InstructionVal + Instruction::AShr) {
- ConcreteTy *I = cast<ConcreteTy>(V);
- return (I->getOpcode() == Instruction::AShr ||
- I->getOpcode() == Instruction::LShr) &&
- L.match(I->getOperand(0)) &&
- R.match(I->getOperand(1));
- }
- if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
- return (CE->getOpcode() == Instruction::LShr ||
- CE->getOpcode() == Instruction::AShr) &&
- L.match(CE->getOperand(0)) &&
- R.match(CE->getOperand(1));
- return false;
- }
-};
-
-template<typename LHS, typename RHS>
-inline Shr_match<LHS, RHS> m_Shr(const LHS &L, const RHS &R) {
- return Shr_match<LHS, RHS>(L, R);
-}
-
-//===----------------------------------------------------------------------===//
-// Matchers for either SDiv or UDiv .. for convenience
+// Class that matches two different binary ops.
//
-template<typename LHS_t, typename RHS_t, typename ConcreteTy = BinaryOperator>
-struct Div_match {
+template<typename LHS_t, typename RHS_t, unsigned Opc1, unsigned Opc2>
+struct BinOp2_match {
LHS_t L;
RHS_t R;
- Div_match(const LHS_t &LHS, const RHS_t &RHS) : L(LHS), R(RHS) {}
+ BinOp2_match(const LHS_t &LHS, const RHS_t &RHS) : L(LHS), R(RHS) {}
template<typename OpTy>
bool match(OpTy *V) {
- if (V->getValueID() == Value::InstructionVal + Instruction::SDiv ||
- V->getValueID() == Value::InstructionVal + Instruction::UDiv) {
- ConcreteTy *I = cast<ConcreteTy>(V);
- return (I->getOpcode() == Instruction::UDiv ||
- I->getOpcode() == Instruction::SDiv) &&
- L.match(I->getOperand(0)) &&
- R.match(I->getOperand(1));
+ if (V->getValueID() == Value::InstructionVal + Opc1 ||
+ V->getValueID() == Value::InstructionVal + Opc2) {
+ BinaryOperator *I = cast<BinaryOperator>(V);
+ return L.match(I->getOperand(0)) && R.match(I->getOperand(1));
}
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
- return (CE->getOpcode() == Instruction::SDiv ||
- CE->getOpcode() == Instruction::UDiv) &&
- L.match(CE->getOperand(0)) &&
- R.match(CE->getOperand(1));
+ return (CE->getOpcode() == Opc1 || CE->getOpcode() == Opc2) &&
+ L.match(CE->getOperand(0)) && R.match(CE->getOperand(1));
return false;
}
};
+/// m_Shr - Matches LShr or AShr.
template<typename LHS, typename RHS>
-inline Div_match<LHS, RHS> m_Div(const LHS &L, const RHS &R) {
- return Div_match<LHS, RHS>(L, R);
+inline BinOp2_match<LHS, RHS, Instruction::LShr, Instruction::AShr>
+m_Shr(const LHS &L, const RHS &R) {
+ return BinOp2_match<LHS, RHS, Instruction::LShr, Instruction::AShr>(L, R);
}
-//===----------------------------------------------------------------------===//
-// Matchers for binary classes
-//
-
-template<typename LHS_t, typename RHS_t, typename Class, typename OpcType>
-struct BinaryOpClass_match {
- OpcType *Opcode;
- LHS_t L;
- RHS_t R;
-
- BinaryOpClass_match(OpcType &Op, const LHS_t &LHS,
- const RHS_t &RHS)
- : Opcode(&Op), L(LHS), R(RHS) {}
- BinaryOpClass_match(const LHS_t &LHS, const RHS_t &RHS)
- : Opcode(0), L(LHS), R(RHS) {}
-
- template<typename OpTy>
- bool match(OpTy *V) {
- if (Class *I = dyn_cast<Class>(V))
- if (L.match(I->getOperand(0)) &&
- R.match(I->getOperand(1))) {
- if (Opcode)
- *Opcode = I->getOpcode();
- return true;
- }
-#if 0 // Doesn't handle constantexprs yet!
- if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
- return CE->getOpcode() == Opcode && L.match(CE->getOperand(0)) &&
- R.match(CE->getOperand(1));
-#endif
- return false;
- }
-};
-
+/// m_LogicalShift - Matches LShr or Shl.
template<typename LHS, typename RHS>
-inline BinaryOpClass_match<LHS, RHS, BinaryOperator, Instruction::BinaryOps>
-m_Shift(Instruction::BinaryOps &Op, const LHS &L, const RHS &R) {
- return BinaryOpClass_match<LHS, RHS,
- BinaryOperator, Instruction::BinaryOps>(Op, L, R);
+inline BinOp2_match<LHS, RHS, Instruction::LShr, Instruction::Shl>
+m_LogicalShift(const LHS &L, const RHS &R) {
+ return BinOp2_match<LHS, RHS, Instruction::LShr, Instruction::Shl>(L, R);
}
+/// m_IDiv - Matches UDiv and SDiv.
template<typename LHS, typename RHS>
-inline BinaryOpClass_match<LHS, RHS, BinaryOperator, Instruction::BinaryOps>
-m_Shift(const LHS &L, const RHS &R) {
- return BinaryOpClass_match<LHS, RHS,
- BinaryOperator, Instruction::BinaryOps>(L, R);
+inline BinOp2_match<LHS, RHS, Instruction::SDiv, Instruction::UDiv>
+m_IDiv(const LHS &L, const RHS &R) {
+ return BinOp2_match<LHS, RHS, Instruction::SDiv, Instruction::UDiv>(L, R);
}
//===----------------------------------------------------------------------===//
LHS_t L;
RHS_t R;
- CmpClass_match(PredicateTy &Pred, const LHS_t &LHS,
- const RHS_t &RHS)
+ CmpClass_match(PredicateTy &Pred, const LHS_t &LHS, const RHS_t &RHS)
: Predicate(Pred), L(LHS), R(RHS) {}
template<typename OpTy>
bool match(OpTy *V) {
if (Class *I = dyn_cast<Class>(V))
- if (L.match(I->getOperand(0)) &&
- R.match(I->getOperand(1))) {
+ if (L.match(I->getOperand(0)) && R.match(I->getOperand(1))) {
Predicate = I->getPredicate();
return true;
}
/// m_SelectCst - This matches a select of two constants, e.g.:
/// m_SelectCst<-1, 0>(m_Value(V))
template<int64_t L, int64_t R, typename Cond>
-inline SelectClass_match<Cond, constantint_ty<L>, constantint_ty<R> >
+inline SelectClass_match<Cond, constantint_match<L>, constantint_match<R> >
m_SelectCst(const Cond &C) {
- return SelectClass_match<Cond, constantint_ty<L>,
- constantint_ty<R> >(C, m_ConstantInt<L>(),
- m_ConstantInt<R>());
+ return m_Select(C, m_ConstantInt<L>(), m_ConstantInt<R>());
}
bool matchIfNot(Value *LHS, Value *RHS) {
if (ConstantInt *CI = dyn_cast<ConstantInt>(RHS))
return CI->isAllOnesValue() && L.match(LHS);
- if (ConstantInt *CI = dyn_cast<ConstantInt>(LHS))
- return CI->isAllOnesValue() && L.match(RHS);
if (ConstantVector *CV = dyn_cast<ConstantVector>(RHS))
return CV->isAllOnesValue() && L.match(LHS);
- if (ConstantVector *CV = dyn_cast<ConstantVector>(LHS))
- return CV->isAllOnesValue() && L.match(RHS);
return false;
}
};
}
private:
bool matchIfNeg(Value *LHS, Value *RHS) {
- return LHS == ConstantFP::getZeroValueForNegation(LHS->getType()) &&
- L.match(RHS);
+ if (ConstantInt *C = dyn_cast<ConstantInt>(LHS))
+ return C->isZero() && L.match(RHS);
+ return false;
}
};
+/// m_Neg - Match an integer negate.
template<typename LHS>
inline neg_match<LHS> m_Neg(const LHS &L) { return L; }
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
if (CE->getOpcode() == Instruction::FSub)
return matchIfFNeg(CE->getOperand(0), CE->getOperand(1));
- if (ConstantFP *CF = dyn_cast<ConstantFP>(V))
- return L.match(ConstantExpr::getFNeg(CF));
return false;
}
private:
bool matchIfFNeg(Value *LHS, Value *RHS) {
- return LHS == ConstantFP::getZeroValueForNegation(LHS->getType()) &&
- L.match(RHS);
+ if (ConstantFP *C = dyn_cast<ConstantFP>(LHS))
+ return C->isNegativeZeroValue() && L.match(RHS);
+ return false;
}
};
+/// m_FNeg - Match a floating point negate.
template<typename LHS>
inline fneg_match<LHS> m_FNeg(const LHS &L) { return L; }
//===----------------------------------------------------------------------===//
-// Matchers for control flow
+// Matchers for control flow.
//
template<typename Cond_t>
template<typename OpTy>
bool match(OpTy *V) {
if (BranchInst *BI = dyn_cast<BranchInst>(V))
- if (BI->isConditional()) {
- if (Cond.match(BI->getCondition())) {
- T = BI->getSuccessor(0);
- F = BI->getSuccessor(1);
- return true;
- }
+ if (BI->isConditional() && Cond.match(BI->getCondition())) {
+ T = BI->getSuccessor(0);
+ F = BI->getSuccessor(1);
+ return true;
}
return false;
}
// (X / Y) * Y -> X if the division is exact.
Value *X = 0, *Y = 0;
- if ((match(Op0, m_Div(m_Value(X), m_Value(Y))) && Y == Op1) || // (X / Y) * Y
- (match(Op1, m_Div(m_Value(X), m_Value(Y))) && Y == Op0)) { // Y * (X / Y)
+ if ((match(Op0, m_IDiv(m_Value(X), m_Value(Y))) && Y == Op1) || // (X / Y) * Y
+ (match(Op1, m_IDiv(m_Value(X), m_Value(Y))) && Y == Op0)) { // Y * (X / Y)
BinaryOperator *Div = cast<BinaryOperator>(Y == Op1 ? Op0 : Op1);
if (Div->isExact())
return X;
// (A >> B) | (C << D) and (A << B) | (B >> C) -> bswap if possible.
if (match(Op0, m_Or(m_Value(), m_Value())) ||
match(Op1, m_Or(m_Value(), m_Value())) ||
- (match(Op0, m_Shift(m_Value(), m_Value())) &&
- match(Op1, m_Shift(m_Value(), m_Value())))) {
+ (match(Op0, m_LogicalShift(m_Value(), m_Value())) &&
+ match(Op1, m_LogicalShift(m_Value(), m_Value())))) {
if (Instruction *BSwap = MatchBSwap(I))
return BSwap;
}