diff --git a/include/llvm/InstrTypes.h b/include/llvm/InstrTypes.h index df64c9bd0ee..c615888d818 100644 --- a/include/llvm/InstrTypes.h +++ b/include/llvm/InstrTypes.h @@ -76,8 +76,17 @@ public: class BinaryOperator : public Instruction { protected: + void init(BinaryOps iType, Value *S1, Value *S2); BinaryOperator(BinaryOps iType, Value *S1, Value *S2, const Type *Ty, - const std::string &Name, Instruction *InsertBefore); + const std::string &Name, Instruction *InsertBefore) + : Instruction(Ty, iType, Name, InsertBefore) { + init(iType, S1, S2); + } + BinaryOperator(BinaryOps iType, Value *S1, Value *S2, const Type *Ty, + const std::string &Name, BasicBlock *InsertAtEnd) + : Instruction(Ty, iType, Name, InsertAtEnd) { + init(iType, S1, S2); + } public: @@ -90,6 +99,14 @@ public: const std::string &Name = "", Instruction *InsertBefore = 0); + /// create() - Construct a binary instruction, given the opcode and the two + /// operands. Also automatically insert this instruction to the end of the + /// BasicBlock specified. + /// + static BinaryOperator *create(BinaryOps Op, Value *S1, Value *S2, + const std::string &Name, + BasicBlock *InsertAtEnd); + /// Helper functions to construct and inspect unary operations (NEG and NOT) /// via binary operators SUB and XOR: @@ -99,8 +116,12 @@ public: /// static BinaryOperator *createNeg(Value *Op, const std::string &Name = "", Instruction *InsertBefore = 0); + static BinaryOperator *createNeg(Value *Op, const std::string &Name, + BasicBlock *InsertAtEnd); static BinaryOperator *createNot(Value *Op, const std::string &Name = "", Instruction *InsertBefore = 0); + static BinaryOperator *createNot(Value *Op, const std::string &Name, + BasicBlock *InsertAtEnd); /// isNeg, isNot - Check if the given Value is a NEG or NOT instruction. /// diff --git a/include/llvm/iMemory.h b/include/llvm/iMemory.h index a794ca54023..1f9f25fce89 100644 --- a/include/llvm/iMemory.h +++ b/include/llvm/iMemory.h @@ -30,8 +30,12 @@ class PointerType; /// class AllocationInst : public Instruction { protected: + void init(const Type *Ty, Value *ArraySize, unsigned iTy); AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy, const std::string &Name = "", Instruction *InsertBefore = 0); + AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy, + const std::string &Name, BasicBlock *InsertAtEnd); + public: /// isArrayAllocation - Return true if there is an allocation size parameter @@ -79,9 +83,13 @@ public: class MallocInst : public AllocationInst { MallocInst(const MallocInst &MI); public: - MallocInst(const Type *Ty, Value *ArraySize = 0, const std::string &Name = "", - Instruction *InsertBefore = 0) + explicit MallocInst(const Type *Ty, Value *ArraySize = 0, + const std::string &Name = "", + Instruction *InsertBefore = 0) : AllocationInst(Ty, ArraySize, Malloc, Name, InsertBefore) {} + MallocInst(const Type *Ty, Value *ArraySize, const std::string &Name, + BasicBlock *InsertAtEnd) + : AllocationInst(Ty, ArraySize, Malloc, Name, InsertAtEnd) {} virtual Instruction *clone() const { return new MallocInst(*this); @@ -107,9 +115,13 @@ public: class AllocaInst : public AllocationInst { AllocaInst(const AllocaInst &); public: - AllocaInst(const Type *Ty, Value *ArraySize = 0, const std::string &Name = "", - Instruction *InsertBefore = 0) + explicit AllocaInst(const Type *Ty, Value *ArraySize = 0, + const std::string &Name = "", + Instruction *InsertBefore = 0) : AllocationInst(Ty, ArraySize, Alloca, Name, InsertBefore) {} + AllocaInst(const Type *Ty, Value *ArraySize, const std::string &Name, + BasicBlock *InsertAtEnd) + : AllocationInst(Ty, ArraySize, Alloca, Name, InsertAtEnd) {} virtual Instruction *clone() const { return new AllocaInst(*this); @@ -132,8 +144,12 @@ public: /// FreeInst - an instruction to deallocate memory /// -struct FreeInst : public Instruction { - FreeInst(Value *Ptr, Instruction *InsertBefore = 0); +class FreeInst : public Instruction { + void init(Value *Ptr); + +public: + explicit FreeInst(Value *Ptr, Instruction *InsertBefore = 0); + FreeInst(Value *Ptr, BasicBlock *InsertAfter); virtual Instruction *clone() const { return new FreeInst(Operands[0]); } @@ -169,8 +185,11 @@ class LoadInst : public Instruction { } public: LoadInst(Value *Ptr, const std::string &Name, Instruction *InsertBefore); + LoadInst(Value *Ptr, const std::string &Name, BasicBlock *InsertAtEnd); LoadInst(Value *Ptr, const std::string &Name = "", bool isVolatile = false, Instruction *InsertBefore = 0); + LoadInst(Value *Ptr, const std::string &Name, bool isVolatile, + BasicBlock *InsertAtEnd); /// isVolatile - Return true if this is a load from a volatile memory /// location. @@ -221,8 +240,10 @@ class StoreInst : public Instruction { } public: StoreInst(Value *Val, Value *Ptr, Instruction *InsertBefore); + StoreInst(Value *Val, Value *Ptr, BasicBlock *InsertAtEnd); StoreInst(Value *Val, Value *Ptr, bool isVolatile = false, Instruction *InsertBefore = 0); + StoreInst(Value *Val, Value *Ptr, bool isVolatile, BasicBlock *InsertAtEnd); /// isVolatile - Return true if this is a load from a volatile memory @@ -272,6 +293,8 @@ class GetElementPtrInst : public Instruction { public: GetElementPtrInst(Value *Ptr, const std::vector &Idx, const std::string &Name = "", Instruction *InsertBefore =0); + GetElementPtrInst(Value *Ptr, const std::vector &Idx, + const std::string &Name, BasicBlock *InsertAtEnd); virtual Instruction *clone() const { return new GetElementPtrInst(*this); } // getType - Overload to return most specific pointer type... diff --git a/include/llvm/iOperators.h b/include/llvm/iOperators.h index ecf99172a1e..e384e051d8e 100644 --- a/include/llvm/iOperators.h +++ b/include/llvm/iOperators.h @@ -26,6 +26,8 @@ class SetCondInst : public BinaryOperator { public: SetCondInst(BinaryOps Opcode, Value *LHS, Value *RHS, const std::string &Name = "", Instruction *InsertBefore = 0); + SetCondInst(BinaryOps Opcode, Value *LHS, Value *RHS, + const std::string &Name, BasicBlock *InsertAtEnd); /// getInverseCondition - Return the inverse of the current condition opcode. /// For example seteq -> setne, setgt -> setle, setlt -> setge, etc... diff --git a/include/llvm/iOther.h b/include/llvm/iOther.h index ba76227e4ab..18779f9c328 100644 --- a/include/llvm/iOther.h +++ b/include/llvm/iOther.h @@ -31,12 +31,20 @@ class CastInst : public Instruction { Operands.reserve(1); Operands.push_back(Use(CI.Operands[0], this)); } + void init(Value *S) { + Operands.reserve(1); + Operands.push_back(Use(S, this)); + } public: CastInst(Value *S, const Type *Ty, const std::string &Name = "", Instruction *InsertBefore = 0) : Instruction(Ty, Cast, Name, InsertBefore) { - Operands.reserve(1); - Operands.push_back(Use(S, this)); + init(S); + } + CastInst(Value *S, const Type *Ty, const std::string &Name, + BasicBlock *InsertAtEnd) + : Instruction(Ty, Cast, Name, InsertAtEnd) { + init(S); } virtual Instruction *clone() const { return new CastInst(*this); } @@ -61,15 +69,25 @@ public: /// class CallInst : public Instruction { CallInst(const CallInst &CI); + void init(Value *Func, const std::vector &Params); + void init(Value *Func, Value *Actual); + void init(Value *Func); + public: CallInst(Value *F, const std::vector &Par, const std::string &Name = "", Instruction *InsertBefore = 0); + CallInst(Value *F, const std::vector &Par, + const std::string &Name, BasicBlock *InsertAtEnd); - // Alternate CallInst ctors w/ no actuals & one actual, respectively. - CallInst(Value *F, const std::string &Name = "", - Instruction *InsertBefore = 0); + // Alternate CallInst ctors w/ one actual & no actuals, respectively. CallInst(Value *F, Value *Actual, const std::string& Name = "", Instruction *InsertBefore = 0); + CallInst(Value *F, Value *Actual, const std::string& Name, + BasicBlock *InsertAtEnd); + explicit CallInst(Value *F, const std::string &Name = "", + Instruction *InsertBefore = 0); + explicit CallInst(Value *F, const std::string &Name, + BasicBlock *InsertAtEnd); virtual Instruction *clone() const { return new CallInst(*this); } bool mayWriteToMemory() const { return true; } @@ -106,16 +124,25 @@ class ShiftInst : public Instruction { Operands.push_back(Use(SI.Operands[0], this)); Operands.push_back(Use(SI.Operands[1], this)); } -public: - ShiftInst(OtherOps Opcode, Value *S, Value *SA, const std::string &Name = "", - Instruction *InsertBefore = 0) - : Instruction(S->getType(), Opcode, Name, InsertBefore) { + void init(OtherOps Opcode, Value *S, Value *SA) { assert((Opcode == Shl || Opcode == Shr) && "ShiftInst Opcode invalid!"); Operands.reserve(2); Operands.push_back(Use(S, this)); Operands.push_back(Use(SA, this)); } +public: + ShiftInst(OtherOps Opcode, Value *S, Value *SA, const std::string &Name = "", + Instruction *InsertBefore = 0) + : Instruction(S->getType(), Opcode, Name, InsertBefore) { + init(Opcode, S, SA); + } + ShiftInst(OtherOps Opcode, Value *S, Value *SA, const std::string &Name, + BasicBlock *InsertAtEnd) + : Instruction(S->getType(), Opcode, Name, InsertAtEnd) { + init(Opcode, S, SA); + } + OtherOps getOpcode() const { return static_cast(Instruction::getOpcode()); } @@ -146,16 +173,25 @@ class SelectInst : public Instruction { Operands.push_back(Use(SI.Operands[1], this)); Operands.push_back(Use(SI.Operands[2], this)); } -public: - SelectInst(Value *C, Value *S1, Value *S2, const std::string &Name = "", - Instruction *InsertBefore = 0) - : Instruction(S1->getType(), Instruction::Select, Name, InsertBefore) { + void init(Value *C, Value *S1, Value *S2) { Operands.reserve(3); Operands.push_back(Use(C, this)); Operands.push_back(Use(S1, this)); Operands.push_back(Use(S2, this)); } +public: + SelectInst(Value *C, Value *S1, Value *S2, const std::string &Name = "", + Instruction *InsertBefore = 0) + : Instruction(S1->getType(), Instruction::Select, Name, InsertBefore) { + init(C, S1, S2); + } + SelectInst(Value *C, Value *S1, Value *S2, const std::string &Name, + BasicBlock *InsertAtEnd) + : Instruction(S1->getType(), Instruction::Select, Name, InsertAtEnd) { + init(C, S1, S2); + } + Value *getCondition() const { return Operands[0]; } Value *getTrueValue() const { return Operands[1]; } Value *getFalseValue() const { return Operands[2]; } @@ -187,17 +223,25 @@ public: /// class VANextInst : public Instruction { PATypeHolder ArgTy; + void init(Value *List) { + Operands.reserve(1); + Operands.push_back(Use(List, this)); + } VANextInst(const VANextInst &VAN) : Instruction(VAN.getType(), VANext), ArgTy(VAN.getArgType()) { - Operands.reserve(1); - Operands.push_back(Use(VAN.Operands[0], this)); + init(VAN.Operands[0]); } + public: VANextInst(Value *List, const Type *Ty, const std::string &Name = "", Instruction *InsertBefore = 0) : Instruction(List->getType(), VANext, Name, InsertBefore), ArgTy(Ty) { - Operands.reserve(1); - Operands.push_back(Use(List, this)); + init(List); + } + VANextInst(Value *List, const Type *Ty, const std::string &Name, + BasicBlock *InsertAtEnd) + : Instruction(List->getType(), VANext, Name, InsertAtEnd), ArgTy(Ty) { + init(List); } const Type *getArgType() const { return ArgTy; } @@ -223,17 +267,24 @@ public: /// an argument of the specified type given a va_list. /// class VAArgInst : public Instruction { + void init(Value* List) { + Operands.reserve(1); + Operands.push_back(Use(List, this)); + } VAArgInst(const VAArgInst &VAA) : Instruction(VAA.getType(), VAArg) { - Operands.reserve(1); - Operands.push_back(Use(VAA.Operands[0], this)); + init(VAA.Operands[0]); } public: VAArgInst(Value *List, const Type *Ty, const std::string &Name = "", Instruction *InsertBefore = 0) : Instruction(Ty, VAArg, Name, InsertBefore) { - Operands.reserve(1); - Operands.push_back(Use(List, this)); + init(List); + } + VAArgInst(Value *List, const Type *Ty, const std::string &Name, + BasicBlock *InsertAtEnd) + : Instruction(Ty, VAArg, Name, InsertAtEnd) { + init(List); } virtual Instruction *clone() const { return new VAArgInst(*this); } diff --git a/include/llvm/iPHINode.h b/include/llvm/iPHINode.h index 8899dd95ded..22ba9a0578d 100644 --- a/include/llvm/iPHINode.h +++ b/include/llvm/iPHINode.h @@ -36,6 +36,10 @@ public: : Instruction(Ty, Instruction::PHI, Name, InsertBefore) { } + PHINode(const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd) + : Instruction(Ty, Instruction::PHI, Name, InsertAtEnd) { + } + virtual Instruction *clone() const { return new PHINode(*this); } /// getNumIncomingValues - Return the number of incoming edges diff --git a/lib/VMCore/iCall.cpp b/lib/VMCore/iCall.cpp index edd55933014..9a81f7948f9 100644 --- a/lib/VMCore/iCall.cpp +++ b/lib/VMCore/iCall.cpp @@ -23,43 +23,23 @@ using namespace llvm; // CallInst Implementation //===----------------------------------------------------------------------===// -CallInst::CallInst(Value *Func, const std::vector ¶ms, - const std::string &Name, Instruction *InsertBefore) - : Instruction(cast(cast(Func->getType()) - ->getElementType())->getReturnType(), - Instruction::Call, Name, InsertBefore) { - Operands.reserve(1+params.size()); +void CallInst::init(Value *Func, const std::vector &Params) +{ + Operands.reserve(1+Params.size()); Operands.push_back(Use(Func, this)); const FunctionType *FTy = cast(cast(Func->getType())->getElementType()); - assert((params.size() == FTy->getNumParams() || - (FTy->isVarArg() && params.size() > FTy->getNumParams())) && + assert((Params.size() == FTy->getNumParams() || + (FTy->isVarArg() && Params.size() > FTy->getNumParams())) && "Calling a function with bad signature"); - for (unsigned i = 0; i != params.size(); i++) - Operands.push_back(Use(params[i], this)); + for (unsigned i = 0; i != Params.size(); i++) + Operands.push_back(Use(Params[i], this)); } -CallInst::CallInst(Value *Func, const std::string &Name, - Instruction *InsertBefore) - : Instruction(cast(cast(Func->getType()) - ->getElementType())->getReturnType(), - Instruction::Call, Name, InsertBefore) { - Operands.reserve(1); - Operands.push_back(Use(Func, this)); - - const FunctionType *MTy = - cast(cast(Func->getType())->getElementType()); - - assert(MTy->getNumParams() == 0 && "Calling a function with bad signature"); -} - -CallInst::CallInst(Value *Func, Value* A, const std::string &Name, - Instruction *InsertBefore) - : Instruction(cast(cast(Func->getType()) - ->getElementType())->getReturnType(), - Instruction::Call, Name, InsertBefore) { +void CallInst::init(Value *Func, Value *Actual) +{ Operands.reserve(2); Operands.push_back(Use(Func, this)); @@ -69,7 +49,66 @@ CallInst::CallInst(Value *Func, Value* A, const std::string &Name, assert((MTy->getNumParams() == 1 || (MTy->isVarArg() && MTy->getNumParams() == 0)) && "Calling a function with bad signature"); - Operands.push_back(Use(A, this)); + Operands.push_back(Use(Actual, this)); +} + +void CallInst::init(Value *Func) +{ + Operands.reserve(1); + Operands.push_back(Use(Func, this)); + + const FunctionType *MTy = + cast(cast(Func->getType())->getElementType()); + + assert(MTy->getNumParams() == 0 && "Calling a function with bad signature"); +} + +CallInst::CallInst(Value *Func, const std::vector &Params, + const std::string &Name, Instruction *InsertBefore) + : Instruction(cast(cast(Func->getType()) + ->getElementType())->getReturnType(), + Instruction::Call, Name, InsertBefore) { + init(Func, Params); +} + +CallInst::CallInst(Value *Func, const std::vector &Params, + const std::string &Name, BasicBlock *InsertAtEnd) + : Instruction(cast(cast(Func->getType()) + ->getElementType())->getReturnType(), + Instruction::Call, Name, InsertAtEnd) { + init(Func, Params); +} + +CallInst::CallInst(Value *Func, Value* Actual, const std::string &Name, + Instruction *InsertBefore) + : Instruction(cast(cast(Func->getType()) + ->getElementType())->getReturnType(), + Instruction::Call, Name, InsertBefore) { + init(Func, Actual); +} + +CallInst::CallInst(Value *Func, Value* Actual, const std::string &Name, + BasicBlock *InsertAtEnd) + : Instruction(cast(cast(Func->getType()) + ->getElementType())->getReturnType(), + Instruction::Call, Name, InsertAtEnd) { + init(Func, Actual); +} + +CallInst::CallInst(Value *Func, const std::string &Name, + Instruction *InsertBefore) + : Instruction(cast(cast(Func->getType()) + ->getElementType())->getReturnType(), + Instruction::Call, Name, InsertBefore) { + init(Func); +} + +CallInst::CallInst(Value *Func, const std::string &Name, + BasicBlock *InsertAtEnd) + : Instruction(cast(cast(Func->getType()) + ->getElementType())->getReturnType(), + Instruction::Call, Name, InsertAtEnd) { + init(Func); } CallInst::CallInst(const CallInst &CI) diff --git a/lib/VMCore/iMemory.cpp b/lib/VMCore/iMemory.cpp index 2b731b45c5a..bcba93e253a 100644 --- a/lib/VMCore/iMemory.cpp +++ b/lib/VMCore/iMemory.cpp @@ -16,10 +16,8 @@ #include "llvm/DerivedTypes.h" using namespace llvm; -AllocationInst::AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy, - const std::string &Name, Instruction *InsertBef) - : Instruction(PointerType::get(Ty), iTy, Name, InsertBef) { - +void AllocationInst::init(const Type *Ty, Value *ArraySize, unsigned iTy) +{ // ArraySize defaults to 1. if (!ArraySize) ArraySize = ConstantUInt::get(Type::UIntTy, 1); @@ -30,6 +28,20 @@ AllocationInst::AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy, Operands.push_back(Use(ArraySize, this)); } +AllocationInst::AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy, + const std::string &Name, + Instruction *InsertBefore) + : Instruction(PointerType::get(Ty), iTy, Name, InsertBefore) { + init(Ty, ArraySize, iTy); +} + +AllocationInst::AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy, + const std::string &Name, + BasicBlock *InsertAtEnd) + : Instruction(PointerType::get(Ty), iTy, Name, InsertAtEnd) { + init(Ty, ArraySize, iTy); +} + bool AllocationInst::isArrayAllocation() const { return getOperand(0) != ConstantUInt::get(Type::UIntTy, 1); } @@ -52,13 +64,23 @@ MallocInst::MallocInst(const MallocInst &MI) // FreeInst Implementation //===----------------------------------------------------------------------===// -FreeInst::FreeInst(Value *Ptr, Instruction *InsertBefore) - : Instruction(Type::VoidTy, Free, "", InsertBefore) { - assert(isa(Ptr->getType()) && "Can't free nonpointer!"); +void FreeInst::init(Value *Ptr) +{ + assert(Ptr && isa(Ptr->getType()) && "Can't free nonpointer!"); Operands.reserve(1); Operands.push_back(Use(Ptr, this)); } +FreeInst::FreeInst(Value *Ptr, Instruction *InsertBefore) + : Instruction(Type::VoidTy, Free, "", InsertBefore) { + init(Ptr); +} + +FreeInst::FreeInst(Value *Ptr, BasicBlock *InsertAtEnd) + : Instruction(Type::VoidTy, Free, "", InsertAtEnd) { + init(Ptr); +} + //===----------------------------------------------------------------------===// // LoadInst Implementation @@ -70,6 +92,12 @@ LoadInst::LoadInst(Value *Ptr, const std::string &Name, Instruction *InsertBef) init(Ptr); } +LoadInst::LoadInst(Value *Ptr, const std::string &Name, BasicBlock *InsertAE) + : Instruction(cast(Ptr->getType())->getElementType(), + Load, Name, InsertAE), Volatile(false) { + init(Ptr); +} + LoadInst::LoadInst(Value *Ptr, const std::string &Name, bool isVolatile, Instruction *InsertBef) : Instruction(cast(Ptr->getType())->getElementType(), @@ -77,6 +105,13 @@ LoadInst::LoadInst(Value *Ptr, const std::string &Name, bool isVolatile, init(Ptr); } +LoadInst::LoadInst(Value *Ptr, const std::string &Name, bool isVolatile, + BasicBlock *InsertAE) + : Instruction(cast(Ptr->getType())->getElementType(), + Load, Name, InsertAE), Volatile(isVolatile) { + init(Ptr); +} + //===----------------------------------------------------------------------===// // StoreInst Implementation //===----------------------------------------------------------------------===// @@ -86,12 +121,23 @@ StoreInst::StoreInst(Value *Val, Value *Ptr, Instruction *InsertBefore) init(Val, Ptr); } +StoreInst::StoreInst(Value *Val, Value *Ptr, BasicBlock *InsertAtEnd) + : Instruction(Type::VoidTy, Store, "", InsertAtEnd), Volatile(false) { + init(Val, Ptr); +} + StoreInst::StoreInst(Value *Val, Value *Ptr, bool isVolatile, Instruction *InsertBefore) : Instruction(Type::VoidTy, Store, "", InsertBefore), Volatile(isVolatile) { init(Val, Ptr); } +StoreInst::StoreInst(Value *Val, Value *Ptr, bool isVolatile, + BasicBlock *InsertAtEnd) + : Instruction(Type::VoidTy, Store, "", InsertAtEnd), Volatile(isVolatile) { + init(Val, Ptr); +} + //===----------------------------------------------------------------------===// // GetElementPtrInst Implementation @@ -122,6 +168,14 @@ GetElementPtrInst::GetElementPtrInst(Value *Ptr, const std::vector &Idx, init(Ptr, Idx); } +GetElementPtrInst::GetElementPtrInst(Value *Ptr, const std::vector &Idx, + const std::string &Name, BasicBlock *IAE) + : Instruction(PointerType::get(checkType(getIndexedType(Ptr->getType(), + Idx, true))), + GetElementPtr, Name, IAE) { + init(Ptr, Idx); +} + // getIndexedType - Returns the type of the element that would be loaded with // a load instruction with the specified parameters. // diff --git a/lib/VMCore/iOperators.cpp b/lib/VMCore/iOperators.cpp index 977849e22cc..b2569e61836 100644 --- a/lib/VMCore/iOperators.cpp +++ b/lib/VMCore/iOperators.cpp @@ -21,11 +21,8 @@ using namespace llvm; // BinaryOperator Class //===----------------------------------------------------------------------===// -BinaryOperator::BinaryOperator(BinaryOps iType, Value *S1, Value *S2, - const Type *Ty, const std::string &Name, - Instruction *InsertBefore) - : Instruction(Ty, iType, Name, InsertBefore) { - +void BinaryOperator::init(BinaryOps iType, Value *S1, Value *S2) +{ Operands.reserve(2); Operands.push_back(Use(S1, this)); Operands.push_back(Use(S2, this)); @@ -36,30 +33,27 @@ BinaryOperator::BinaryOperator(BinaryOps iType, Value *S1, Value *S2, case Add: case Sub: case Mul: case Div: case Rem: - assert(Ty == S1->getType() && + assert(getType() == S1->getType() && "Arithmetic operation should return same type as operands!"); - assert((Ty->isInteger() || Ty->isFloatingPoint()) && + assert((getType()->isInteger() || getType()->isFloatingPoint()) && "Tried to create an arithmetic operation on a non-arithmetic type!"); break; case And: case Or: case Xor: - assert(Ty == S1->getType() && + assert(getType() == S1->getType() && "Logical operation should return same type as operands!"); - assert(Ty->isIntegral() && + assert(getType()->isIntegral() && "Tried to create an logical operation on a non-integral type!"); break; case SetLT: case SetGT: case SetLE: case SetGE: case SetEQ: case SetNE: - assert(Ty == Type::BoolTy && "Setcc must return bool!"); + assert(getType() == Type::BoolTy && "Setcc must return bool!"); default: break; } #endif } - - - BinaryOperator *BinaryOperator::create(BinaryOps Op, Value *S1, Value *S2, const std::string &Name, Instruction *InsertBefore) { @@ -76,6 +70,22 @@ BinaryOperator *BinaryOperator::create(BinaryOps Op, Value *S1, Value *S2, } } +BinaryOperator *BinaryOperator::create(BinaryOps Op, Value *S1, Value *S2, + const std::string &Name, + BasicBlock *InsertAtEnd) { + assert(S1->getType() == S2->getType() && + "Cannot create binary operator with two operands of differing type!"); + switch (Op) { + // Binary comparison operators... + case SetLT: case SetGT: case SetLE: + case SetGE: case SetEQ: case SetNE: + return new SetCondInst(Op, S1, S2, Name, InsertAtEnd); + + default: + return new BinaryOperator(Op, S1, S2, S1->getType(), Name, InsertAtEnd); + } +} + BinaryOperator *BinaryOperator::createNeg(Value *Op, const std::string &Name, Instruction *InsertBefore) { if (!Op->getType()->isFloatingPoint()) @@ -88,6 +98,18 @@ BinaryOperator *BinaryOperator::createNeg(Value *Op, const std::string &Name, Op->getType(), Name, InsertBefore); } +BinaryOperator *BinaryOperator::createNeg(Value *Op, const std::string &Name, + BasicBlock *InsertAtEnd) { + if (!Op->getType()->isFloatingPoint()) + return new BinaryOperator(Instruction::Sub, + Constant::getNullValue(Op->getType()), Op, + Op->getType(), Name, InsertAtEnd); + else + return new BinaryOperator(Instruction::Sub, + ConstantFP::get(Op->getType(), -0.0), Op, + Op->getType(), Name, InsertAtEnd); +} + BinaryOperator *BinaryOperator::createNot(Value *Op, const std::string &Name, Instruction *InsertBefore) { return new BinaryOperator(Instruction::Xor, Op, @@ -95,6 +117,13 @@ BinaryOperator *BinaryOperator::createNot(Value *Op, const std::string &Name, Op->getType(), Name, InsertBefore); } +BinaryOperator *BinaryOperator::createNot(Value *Op, const std::string &Name, + BasicBlock *InsertAtEnd) { + return new BinaryOperator(Instruction::Xor, Op, + ConstantIntegral::getAllOnesValue(Op->getType()), + Op->getType(), Name, InsertAtEnd); +} + // isConstantAllOnes - Helper function for several functions below static inline bool isConstantAllOnes(const Value *V) { @@ -173,6 +202,14 @@ SetCondInst::SetCondInst(BinaryOps Opcode, Value *S1, Value *S2, assert(getInverseCondition(Opcode)); } +SetCondInst::SetCondInst(BinaryOps Opcode, Value *S1, Value *S2, + const std::string &Name, BasicBlock *InsertAtEnd) + : BinaryOperator(Opcode, S1, S2, Type::BoolTy, Name, InsertAtEnd) { + + // Make sure it's a valid type... getInverseCondition will assert out if not. + assert(getInverseCondition(Opcode)); +} + // getInverseCondition - Return the inverse of the current condition opcode. // For example seteq -> setne, setgt -> setle, setlt -> setge, etc... //