diff options
Diffstat (limited to 'lib/VMCore')
-rw-r--r-- | lib/VMCore/AsmWriter.cpp | 7 | ||||
-rw-r--r-- | lib/VMCore/Constants.cpp | 94 | ||||
-rw-r--r-- | lib/VMCore/Instruction.cpp | 2 | ||||
-rw-r--r-- | lib/VMCore/Instructions.cpp | 100 |
4 files changed, 131 insertions, 72 deletions
diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp index 28e38cc..06bfc50 100644 --- a/lib/VMCore/AsmWriter.cpp +++ b/lib/VMCore/AsmWriter.cpp @@ -1251,11 +1251,8 @@ void AssemblyWriter::printInstruction(const Instruction &I) { Out << I.getOpcodeName(); // Print out the compare instruction predicates - if (const FCmpInst *FCI = dyn_cast<FCmpInst>(&I)) { - Out << " " << getPredicateText(FCI->getPredicate()); - } else if (const ICmpInst *ICI = dyn_cast<ICmpInst>(&I)) { - Out << " " << getPredicateText(ICI->getPredicate()); - } + if (const CmpInst *CI = dyn_cast<CmpInst>(&I)) + Out << " " << getPredicateText(CI->getPredicate()); // Print out the type of the operands... const Value *Operand = I.getNumOperands() ? I.getOperand(0) : 0; diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp index d0c8373..f9b8bd7 100644 --- a/lib/VMCore/Constants.cpp +++ b/lib/VMCore/Constants.cpp @@ -557,9 +557,9 @@ struct VISIBILITY_HIDDEN CompareConstantExpr : public ConstantExpr { return User::operator new(s, 2); } unsigned short predicate; - CompareConstantExpr(Instruction::OtherOps opc, unsigned short pred, - Constant* LHS, Constant* RHS) - : ConstantExpr(Type::Int1Ty, opc, &Op<0>(), 2), predicate(pred) { + CompareConstantExpr(const Type *ty, Instruction::OtherOps opc, + unsigned short pred, Constant* LHS, Constant* RHS) + : ConstantExpr(ty, opc, &Op<0>(), 2), predicate(pred) { Op<0>().init(LHS, this); Op<1>().init(RHS, this); } @@ -690,7 +690,10 @@ Constant *ConstantExpr::getXor(Constant *C1, Constant *C2) { return get(Instruction::Xor, C1, C2); } unsigned ConstantExpr::getPredicate() const { - assert(getOpcode() == Instruction::FCmp || getOpcode() == Instruction::ICmp); + assert(getOpcode() == Instruction::FCmp || + getOpcode() == Instruction::ICmp || + getOpcode() == Instruction::VFCmp || + getOpcode() == Instruction::VICmp); return ((const CompareConstantExpr*)this)->predicate; } Constant *ConstantExpr::getShl(Constant *C1, Constant *C2) { @@ -1564,10 +1567,16 @@ namespace llvm { // value and it is combined with the instruction opcode by multiplying // the opcode by one hundred. We must decode this to get the predicate. if (V.opcode == Instruction::ICmp) - return new CompareConstantExpr(Instruction::ICmp, V.predicate, + return new CompareConstantExpr(Ty, Instruction::ICmp, V.predicate, V.operands[0], V.operands[1]); if (V.opcode == Instruction::FCmp) - return new CompareConstantExpr(Instruction::FCmp, V.predicate, + return new CompareConstantExpr(Ty, Instruction::FCmp, V.predicate, + V.operands[0], V.operands[1]); + if (V.opcode == Instruction::VICmp) + return new CompareConstantExpr(Ty, Instruction::VICmp, V.predicate, + V.operands[0], V.operands[1]); + if (V.opcode == Instruction::VFCmp) + return new CompareConstantExpr(Ty, Instruction::VFCmp, V.predicate, V.operands[0], V.operands[1]); assert(0 && "Invalid ConstantExpr!"); return 0; @@ -2029,6 +2038,79 @@ ConstantExpr::getFCmp(unsigned short pred, Constant* LHS, Constant* RHS) { return ExprConstants->getOrCreate(Type::Int1Ty, Key); } +Constant * +ConstantExpr::getVICmp(unsigned short pred, Constant* LHS, Constant* RHS) { + assert(isa<VectorType>(LHS->getType()) && + "Tried to create vicmp operation on non-vector type!"); + assert(LHS->getType() == RHS->getType()); + assert(pred >= ICmpInst::FIRST_ICMP_PREDICATE && + pred <= ICmpInst::LAST_ICMP_PREDICATE && "Invalid VICmp Predicate"); + + const Type *VTy = cast<VectorType>(LHS->getType()); + const Type *EltTy = VTy->getElementType(); + unsigned NumElts = VTy->getNumElements(); + + SmallVector<Constant *, 8> Elts; + for (unsigned i = 0; i != NumElts; ++i) { + Constant *FC = ConstantFoldCompareInstruction(pred, LHS->getOperand(i), + RHS->getOperand(i)); + if (FC) { + uint64_t Val = cast<ConstantInt>(FC)->getZExtValue(); + if (Val != 0ULL) + Elts.push_back(ConstantInt::getAllOnesValue(EltTy)); + else + Elts.push_back(ConstantInt::get(EltTy, 0ULL)); + } + } + if (Elts.size() == NumElts) + return ConstantVector::get(&Elts[0], Elts.size()); + + // Look up the constant in the table first to ensure uniqueness + std::vector<Constant*> ArgVec; + ArgVec.push_back(LHS); + ArgVec.push_back(RHS); + // Get the key type with both the opcode and predicate + const ExprMapKeyType Key(Instruction::VICmp, ArgVec, pred); + return ExprConstants->getOrCreate(LHS->getType(), Key); +} + +Constant * +ConstantExpr::getVFCmp(unsigned short pred, Constant* LHS, Constant* RHS) { + assert(isa<VectorType>(LHS->getType()) && + "Tried to create vfcmp operation on non-vector type!"); + assert(LHS->getType() == RHS->getType()); + assert(pred <= FCmpInst::LAST_FCMP_PREDICATE && "Invalid VFCmp Predicate"); + + const VectorType *VTy = cast<VectorType>(LHS->getType()); + unsigned NumElts = VTy->getNumElements(); + const Type *EltTy = VTy->getElementType(); + const Type *REltTy = IntegerType::get(EltTy->getPrimitiveSizeInBits()); + const Type *ResultTy = VectorType::get(REltTy, NumElts); + + SmallVector<Constant *, 8> Elts; + for (unsigned i = 0; i != NumElts; ++i) { + Constant *FC = ConstantFoldCompareInstruction(pred, LHS->getOperand(i), + RHS->getOperand(i)); + if (FC) { + uint64_t Val = cast<ConstantInt>(FC)->getZExtValue(); + if (Val != 0ULL) + Elts.push_back(ConstantInt::getAllOnesValue(REltTy)); + else + Elts.push_back(ConstantInt::get(REltTy, 0ULL)); + } + } + if (Elts.size() == NumElts) + return ConstantVector::get(&Elts[0], Elts.size()); + + // Look up the constant in the table first to ensure uniqueness + std::vector<Constant*> ArgVec; + ArgVec.push_back(LHS); + ArgVec.push_back(RHS); + // Get the key type with both the opcode and predicate + const ExprMapKeyType Key(Instruction::VFCmp, ArgVec, pred); + return ExprConstants->getOrCreate(ResultTy, Key); +} + Constant *ConstantExpr::getExtractElementTy(const Type *ReqTy, Constant *Val, Constant *Idx) { if (Constant *FC = ConstantFoldExtractElementInstruction(Val, Idx)) diff --git a/lib/VMCore/Instruction.cpp b/lib/VMCore/Instruction.cpp index 2316b48..3330847 100644 --- a/lib/VMCore/Instruction.cpp +++ b/lib/VMCore/Instruction.cpp @@ -128,6 +128,8 @@ const char *Instruction::getOpcodeName(unsigned OpCode) { // Other instructions... case ICmp: return "icmp"; case FCmp: return "fcmp"; + case VICmp: return "vicmp"; + case VFCmp: return "vfcmp"; case PHI: return "phi"; case Select: return "select"; case Call: return "call"; diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp index e901f3e..d34aa59 100644 --- a/lib/VMCore/Instructions.cpp +++ b/lib/VMCore/Instructions.cpp @@ -2332,9 +2332,10 @@ BitCastInst::BitCastInst( // CmpInst Classes //===----------------------------------------------------------------------===// -CmpInst::CmpInst(OtherOps op, unsigned short predicate, Value *LHS, Value *RHS, - const std::string &Name, Instruction *InsertBefore) - : Instruction(Type::Int1Ty, op, +CmpInst::CmpInst(const Type *ty, OtherOps op, unsigned short predicate, + Value *LHS, Value *RHS, const std::string &Name, + Instruction *InsertBefore) + : Instruction(ty, op, OperandTraits<CmpInst>::op_begin(this), OperandTraits<CmpInst>::operands(this), InsertBefore) { @@ -2342,34 +2343,12 @@ CmpInst::CmpInst(OtherOps op, unsigned short predicate, Value *LHS, Value *RHS, Op<1>().init(RHS, this); SubclassData = predicate; setName(Name); - if (op == Instruction::ICmp) { - assert(predicate >= ICmpInst::FIRST_ICMP_PREDICATE && - predicate <= ICmpInst::LAST_ICMP_PREDICATE && - "Invalid ICmp predicate value"); - const Type* Op0Ty = getOperand(0)->getType(); - const Type* Op1Ty = getOperand(1)->getType(); - assert(Op0Ty == Op1Ty && - "Both operands to ICmp instruction are not of the same type!"); - // Check that the operands are the right type - assert((Op0Ty->isInteger() || isa<PointerType>(Op0Ty)) && - "Invalid operand types for ICmp instruction"); - return; - } - assert(op == Instruction::FCmp && "Invalid CmpInst opcode"); - assert(predicate <= FCmpInst::LAST_FCMP_PREDICATE && - "Invalid FCmp predicate value"); - const Type* Op0Ty = getOperand(0)->getType(); - const Type* Op1Ty = getOperand(1)->getType(); - assert(Op0Ty == Op1Ty && - "Both operands to FCmp instruction are not of the same type!"); - // Check that the operands are the right type - assert(Op0Ty->isFloatingPoint() && - "Invalid operand types for FCmp instruction"); -} - -CmpInst::CmpInst(OtherOps op, unsigned short predicate, Value *LHS, Value *RHS, - const std::string &Name, BasicBlock *InsertAtEnd) - : Instruction(Type::Int1Ty, op, +} + +CmpInst::CmpInst(const Type *ty, OtherOps op, unsigned short predicate, + Value *LHS, Value *RHS, const std::string &Name, + BasicBlock *InsertAtEnd) + : Instruction(ty, op, OperandTraits<CmpInst>::op_begin(this), OperandTraits<CmpInst>::operands(this), InsertAtEnd) { @@ -2377,52 +2356,44 @@ CmpInst::CmpInst(OtherOps op, unsigned short predicate, Value *LHS, Value *RHS, Op<1>().init(RHS, this); SubclassData = predicate; setName(Name); - if (op == Instruction::ICmp) { - assert(predicate >= ICmpInst::FIRST_ICMP_PREDICATE && - predicate <= ICmpInst::LAST_ICMP_PREDICATE && - "Invalid ICmp predicate value"); - - const Type* Op0Ty = getOperand(0)->getType(); - const Type* Op1Ty = getOperand(1)->getType(); - assert(Op0Ty == Op1Ty && - "Both operands to ICmp instruction are not of the same type!"); - // Check that the operands are the right type - assert((Op0Ty->isInteger() || isa<PointerType>(Op0Ty)) && - "Invalid operand types for ICmp instruction"); - return; - } - assert(op == Instruction::FCmp && "Invalid CmpInst opcode"); - assert(predicate <= FCmpInst::LAST_FCMP_PREDICATE && - "Invalid FCmp predicate value"); - const Type* Op0Ty = getOperand(0)->getType(); - const Type* Op1Ty = getOperand(1)->getType(); - assert(Op0Ty == Op1Ty && - "Both operands to FCmp instruction are not of the same type!"); - // Check that the operands are the right type - assert(Op0Ty->isFloatingPoint() && - "Invalid operand types for FCmp instruction"); } CmpInst * CmpInst::create(OtherOps Op, unsigned short predicate, Value *S1, Value *S2, const std::string &Name, Instruction *InsertBefore) { if (Op == Instruction::ICmp) { - return new ICmpInst(ICmpInst::Predicate(predicate), S1, S2, Name, + return new ICmpInst(CmpInst::Predicate(predicate), S1, S2, Name, + InsertBefore); + } + if (Op == Instruction::FCmp) { + return new FCmpInst(CmpInst::Predicate(predicate), S1, S2, Name, InsertBefore); } - return new FCmpInst(FCmpInst::Predicate(predicate), S1, S2, Name, - InsertBefore); + if (Op == Instruction::VICmp) { + return new VICmpInst(CmpInst::Predicate(predicate), S1, S2, Name, + InsertBefore); + } + return new VFCmpInst(CmpInst::Predicate(predicate), S1, S2, Name, + InsertBefore); } CmpInst * CmpInst::create(OtherOps Op, unsigned short predicate, Value *S1, Value *S2, const std::string &Name, BasicBlock *InsertAtEnd) { if (Op == Instruction::ICmp) { - return new ICmpInst(ICmpInst::Predicate(predicate), S1, S2, Name, + return new ICmpInst(CmpInst::Predicate(predicate), S1, S2, Name, + InsertAtEnd); + } + if (Op == Instruction::FCmp) { + return new FCmpInst(CmpInst::Predicate(predicate), S1, S2, Name, InsertAtEnd); } - return new FCmpInst(FCmpInst::Predicate(predicate), S1, S2, Name, - InsertAtEnd); + if (Op == Instruction::VICmp) { + return new VICmpInst(CmpInst::Predicate(predicate), S1, S2, Name, + InsertAtEnd); + } + return new VFCmpInst(CmpInst::Predicate(predicate), S1, S2, Name, + InsertAtEnd); } void CmpInst::swapOperands() { @@ -2813,6 +2784,13 @@ ICmpInst* ICmpInst::clone() const { return new ICmpInst(getPredicate(), Op<0>(), Op<1>()); } +VFCmpInst* VFCmpInst::clone() const { + return new VFCmpInst(getPredicate(), Op<0>(), Op<1>()); +} +VICmpInst* VICmpInst::clone() const { + return new VICmpInst(getPredicate(), Op<0>(), Op<1>()); +} + MallocInst *MallocInst::clone() const { return new MallocInst(*this); } AllocaInst *AllocaInst::clone() const { return new AllocaInst(*this); } FreeInst *FreeInst::clone() const { return new FreeInst(getOperand(0)); } |