From: Chris Lattner Date: Tue, 10 Sep 2002 15:45:53 +0000 (+0000) Subject: Add capability to insert an instruction into a basic block immediately after X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=2aa831120c97fa4725aea97b0b3e67e8d95b4f38;p=oota-llvm.git Add capability to insert an instruction into a basic block immediately after it is created, as part of the ctor call. Eliminate the GenericBinaryInst class git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@3653 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/VMCore/InstrTypes.cpp b/lib/VMCore/InstrTypes.cpp index 954719aa950..b53f480b148 100644 --- a/lib/VMCore/InstrTypes.cpp +++ b/lib/VMCore/InstrTypes.cpp @@ -1,4 +1,4 @@ -//===-- InstrTypes.cpp - Implement Instruction subclasses --------*- C++ -*--=// +//===-- InstrTypes.cpp - Implement Instruction subclasses -------*- C++ -*-===// // // This file implements // @@ -15,25 +15,15 @@ // TerminatorInst Class //===----------------------------------------------------------------------===// -TerminatorInst::TerminatorInst(Instruction::TermOps iType) - : Instruction(Type::VoidTy, iType, "") { +TerminatorInst::TerminatorInst(Instruction::TermOps iType, Instruction *IB) + : Instruction(Type::VoidTy, iType, "", IB) { } -TerminatorInst::TerminatorInst(const Type *Ty, Instruction::TermOps iType, - const std::string &Name) - : Instruction(Ty, iType, Name) { -} - - //===----------------------------------------------------------------------===// // PHINode Class //===----------------------------------------------------------------------===// -PHINode::PHINode(const Type *Ty, const std::string &name) - : Instruction(Ty, Instruction::PHINode, name) { -} - -PHINode::PHINode(const PHINode &PN) +PHINode::PHINode(const PHINode &PN) : Instruction(PN.getType(), Instruction::PHINode) { Operands.reserve(PN.Operands.size()); for (unsigned i = 0; i < PN.Operands.size(); i+=2) { diff --git a/lib/VMCore/Instruction.cpp b/lib/VMCore/Instruction.cpp index 4368b7e1092..2084e69ede6 100644 --- a/lib/VMCore/Instruction.cpp +++ b/lib/VMCore/Instruction.cpp @@ -9,13 +9,21 @@ #include "llvm/Type.h" #include "Support/LeakDetector.h" -Instruction::Instruction(const Type *ty, unsigned it, const std::string &Name) +Instruction::Instruction(const Type *ty, unsigned it, const std::string &Name, + Instruction *InsertBefore) : User(ty, Value::InstructionVal, Name) { Parent = 0; iType = it; // Make sure that we get added to a basicblock LeakDetector::addGarbageObject(this); + + // If requested, insert this instruction into a basic block... + if (InsertBefore) { + assert(InsertBefore->getParent() && + "Instruction to insert before is not in a basic block!"); + InsertBefore->getParent()->getInstList().insert(InsertBefore, this); + } } void Instruction::setParent(BasicBlock *P) { diff --git a/lib/VMCore/iBranch.cpp b/lib/VMCore/iBranch.cpp index fe5c060c8d8..1561c3b7095 100644 --- a/lib/VMCore/iBranch.cpp +++ b/lib/VMCore/iBranch.cpp @@ -9,8 +9,9 @@ #include "llvm/BasicBlock.h" #include "llvm/Type.h" -BranchInst::BranchInst(BasicBlock *True, BasicBlock *False, Value *Cond) - : TerminatorInst(Instruction::Br) { +BranchInst::BranchInst(BasicBlock *True, BasicBlock *False, Value *Cond, + Instruction *InsertBefore) + : TerminatorInst(Instruction::Br, InsertBefore) { assert(True != 0 && "True branch destination may not be null!!!"); Operands.reserve(False ? 3 : 1); Operands.push_back(Use(True, this)); diff --git a/lib/VMCore/iCall.cpp b/lib/VMCore/iCall.cpp index 9e5ca017875..3a0545f1742 100644 --- a/lib/VMCore/iCall.cpp +++ b/lib/VMCore/iCall.cpp @@ -14,10 +14,10 @@ //===----------------------------------------------------------------------===// CallInst::CallInst(Value *Func, const std::vector ¶ms, - const std::string &Name) + const std::string &Name, Instruction *InsertBefore) : Instruction(cast(cast(Func->getType()) ->getElementType())->getReturnType(), - Instruction::Call, Name) { + Instruction::Call, Name, InsertBefore) { Operands.reserve(1+params.size()); Operands.push_back(Use(Func, this)); @@ -46,10 +46,10 @@ CallInst::CallInst(const CallInst &CI) InvokeInst::InvokeInst(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, const std::vector ¶ms, - const std::string &Name) + const std::string &Name, Instruction *InsertBefore) : TerminatorInst(cast(cast(Func->getType()) ->getElementType())->getReturnType(), - Instruction::Invoke, Name) { + Instruction::Invoke, Name, InsertBefore) { Operands.reserve(3+params.size()); Operands.push_back(Use(Func, this)); Operands.push_back(Use((Value*)IfNormal, this)); diff --git a/lib/VMCore/iMemory.cpp b/lib/VMCore/iMemory.cpp index 4ec9e26fbe2..4f6cefdb261 100644 --- a/lib/VMCore/iMemory.cpp +++ b/lib/VMCore/iMemory.cpp @@ -8,14 +8,9 @@ #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" -static inline const Type *checkType(const Type *Ty) { - assert(Ty && "Invalid indices for type!"); - return Ty; -} - AllocationInst::AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy, - const std::string &Name) - : Instruction(Ty, iTy, Name) { + const std::string &Name, Instruction *InsertBef) + : Instruction(Ty, iTy, Name, InsertBef) { assert(isa(Ty) && "Can't allocate a non pointer type!"); // ArraySize defaults to 1. @@ -37,14 +32,25 @@ const Type *AllocationInst::getAllocatedType() const { return getType()->getElementType(); } +//===----------------------------------------------------------------------===// +// FreeInst Implementation +//===----------------------------------------------------------------------===// + +FreeInst::FreeInst(Value *Ptr, Instruction *InsertBefore) + : Instruction(Type::VoidTy, Free, "", InsertBefore) { + assert(isa(Ptr->getType()) && "Can't free nonpointer!"); + Operands.reserve(1); + Operands.push_back(Use(Ptr, this)); +} + //===----------------------------------------------------------------------===// // LoadInst Implementation //===----------------------------------------------------------------------===// -LoadInst::LoadInst(Value *Ptr, const std::string &Name) +LoadInst::LoadInst(Value *Ptr, const std::string &Name, Instruction *InsertBef) : Instruction(cast(Ptr->getType())->getElementType(), - Load, Name) { + Load, Name, InsertBef) { Operands.reserve(1); Operands.push_back(Use(Ptr, this)); } @@ -54,8 +60,8 @@ LoadInst::LoadInst(Value *Ptr, const std::string &Name) // StoreInst Implementation //===----------------------------------------------------------------------===// -StoreInst::StoreInst(Value *Val, Value *Ptr) - : Instruction(Type::VoidTy, Store, "") { +StoreInst::StoreInst(Value *Val, Value *Ptr, Instruction *InsertBefore) + : Instruction(Type::VoidTy, Store, "", InsertBefore) { Operands.reserve(2); Operands.push_back(Use(Val, this)); @@ -67,11 +73,19 @@ StoreInst::StoreInst(Value *Val, Value *Ptr) // GetElementPtrInst Implementation //===----------------------------------------------------------------------===// +// checkType - Simple wrapper function to give a better assertion failure +// message on bad indexes for a gep instruction. +// +static inline const Type *checkType(const Type *Ty) { + assert(Ty && "Invalid indices for type!"); + return Ty; +} + GetElementPtrInst::GetElementPtrInst(Value *Ptr, const std::vector &Idx, - const std::string &Name) + const std::string &Name, Instruction *InBe) : Instruction(PointerType::get(checkType(getIndexedType(Ptr->getType(), Idx, true))), - GetElementPtr, Name) { + GetElementPtr, Name, InBe) { assert(getIndexedType(Ptr->getType(), Idx, true) && "gep operands invalid!"); Operands.reserve(1+Idx.size()); Operands.push_back(Use(Ptr, this)); @@ -107,15 +121,3 @@ const Type* GetElementPtrInst::getIndexedType(const Type *Ptr, } return CurIDX == Idx.size() ? Ptr : 0; } - - -//===----------------------------------------------------------------------===// -// FreeInst Implementation -//===----------------------------------------------------------------------===// - -FreeInst::FreeInst(Value *Ptr) : Instruction(Type::VoidTy, Free, "") { - assert(isa(Ptr->getType()) && "Can't free nonpointer!"); - Operands.reserve(1); - Operands.push_back(Use(Ptr, this)); -} - diff --git a/lib/VMCore/iOperators.cpp b/lib/VMCore/iOperators.cpp index c7d757eb11c..956d7d5bdba 100644 --- a/lib/VMCore/iOperators.cpp +++ b/lib/VMCore/iOperators.cpp @@ -7,33 +7,54 @@ #include "llvm/iOperators.h" #include "llvm/Type.h" #include "llvm/Constants.h" +#include "llvm/BasicBlock.h" //===----------------------------------------------------------------------===// // BinaryOperator Class //===----------------------------------------------------------------------===// +BinaryOperator::BinaryOperator(BinaryOps iType, Value *S1, Value *S2, + const Type *Ty, const std::string &Name, + Instruction *InsertBefore) + : Instruction(Ty, iType, Name, InsertBefore) { + Operands.reserve(2); + Operands.push_back(Use(S1, this)); + Operands.push_back(Use(S2, this)); + assert(Operands[0] && Operands[1] && + Operands[0]->getType() == Operands[1]->getType()); +} + + + + BinaryOperator *BinaryOperator::create(BinaryOps Op, Value *S1, Value *S2, - const std::string &Name) { + const std::string &Name, + Instruction *InsertBefore) { + 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); + return new SetCondInst(Op, S1, S2, Name, InsertBefore); default: - return new GenericBinaryInst(Op, S1, S2, Name); + return new BinaryOperator(Op, S1, S2, S1->getType(), Name, InsertBefore); } } -BinaryOperator *BinaryOperator::createNeg(Value *Op, const std::string &Name) { - return new GenericBinaryInst(Instruction::Sub, - Constant::getNullValue(Op->getType()), Op, Name); +BinaryOperator *BinaryOperator::createNeg(Value *Op, const std::string &Name, + Instruction *InsertBefore) { + return new BinaryOperator(Instruction::Sub, + Constant::getNullValue(Op->getType()), Op, + Op->getType(), Name, InsertBefore); } -BinaryOperator *BinaryOperator::createNot(Value *Op, const std::string &Name) { - return new GenericBinaryInst(Instruction::Xor, Op, - ConstantIntegral::getAllOnesValue(Op->getType()), - Name); +BinaryOperator *BinaryOperator::createNot(Value *Op, const std::string &Name, + Instruction *InsertBefore) { + return new BinaryOperator(Instruction::Xor, Op, + ConstantIntegral::getAllOnesValue(Op->getType()), + Op->getType(), Name, InsertBefore); } @@ -111,15 +132,12 @@ bool BinaryOperator::swapOperands() { // SetCondInst Class //===----------------------------------------------------------------------===// -SetCondInst::SetCondInst(BinaryOps opType, Value *S1, Value *S2, - const std::string &Name) - : BinaryOperator(opType, S1, S2, Name) { - - OpType = opType; - setType(Type::BoolTy); // setcc instructions always return bool type. +SetCondInst::SetCondInst(BinaryOps Opcode, Value *S1, Value *S2, + const std::string &Name, Instruction *InsertBefore) + : BinaryOperator(Opcode, S1, S2, Type::BoolTy, Name, InsertBefore) { - // Make sure it's a valid type... - assert(getOpcodeName() != 0); + // 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. diff --git a/lib/VMCore/iSwitch.cpp b/lib/VMCore/iSwitch.cpp index 402610cded2..a63adfdfcfd 100644 --- a/lib/VMCore/iSwitch.cpp +++ b/lib/VMCore/iSwitch.cpp @@ -7,11 +7,12 @@ #include "llvm/iTerminators.h" #include "llvm/BasicBlock.h" -SwitchInst::SwitchInst(Value *V, BasicBlock *DefDest) - : TerminatorInst(Instruction::Switch) { - assert(V && DefDest); +SwitchInst::SwitchInst(Value *V, BasicBlock *DefaultDest, + Instruction *InsertBefore) + : TerminatorInst(Instruction::Switch, InsertBefore) { + assert(V && DefaultDest); Operands.push_back(Use(V, this)); - Operands.push_back(Use(DefDest, this)); + Operands.push_back(Use(DefaultDest, this)); } SwitchInst::SwitchInst(const SwitchInst &SI)