diff options
Diffstat (limited to 'lib/VMCore')
29 files changed, 807 insertions, 1054 deletions
diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp index 7a1b7dd..ff6084d 100644 --- a/lib/VMCore/AsmWriter.cpp +++ b/lib/VMCore/AsmWriter.cpp @@ -831,7 +831,8 @@ static void WriteOptimizationInfo(raw_ostream &Out, const User *U) { Out << " nuw"; if (OBO->hasNoSignedWrap()) Out << " nsw"; - } else if (const SDivOperator *Div = dyn_cast<SDivOperator>(U)) { + } else if (const PossiblyExactOperator *Div = + dyn_cast<PossiblyExactOperator>(U)) { if (Div->isExact()) Out << " exact"; } else if (const GEPOperator *GEP = dyn_cast<GEPOperator>(U)) { @@ -1337,9 +1338,12 @@ void AssemblyWriter::printModule(const Module *M) { CurPos = NewLine+1; NewLine = Asm.find_first_of('\n', CurPos); } - Out << "module asm \""; - PrintEscapedString(std::string(Asm.begin()+CurPos, Asm.end()), Out); - Out << "\"\n"; + std::string rest(Asm.begin()+CurPos, Asm.end()); + if (!rest.empty()) { + Out << "module asm \""; + PrintEscapedString(rest, Out); + Out << "\"\n"; + } } // Loop over the dependent libraries and emit them. @@ -1459,6 +1463,7 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) { if (GV->isThreadLocal()) Out << "thread_local "; if (unsigned AddressSpace = GV->getType()->getAddressSpace()) Out << "addrspace(" << AddressSpace << ") "; + if (GV->hasUnnamedAddr()) Out << "unnamed_addr "; Out << (GV->isConstant() ? "constant " : "global "); TypePrinter.print(GV->getType()->getElementType(), Out); @@ -1628,6 +1633,8 @@ void AssemblyWriter::printFunction(const Function *F) { Out << "..."; // Output varargs portion of signature! } Out << ')'; + if (F->hasUnnamedAddr()) + Out << " unnamed_addr"; Attributes FnAttrs = Attrs.getFnAttributes(); if (FnAttrs != Attribute::None) Out << ' ' << Attribute::getAsString(Attrs.getFnAttributes()); @@ -2043,15 +2050,7 @@ static void WriteMDNodeComment(const MDNode *Node, return; Out.PadToColumn(50); - if (Tag == dwarf::DW_TAG_auto_variable) - Out << "; [ DW_TAG_auto_variable ]"; - else if (Tag == dwarf::DW_TAG_arg_variable) - Out << "; [ DW_TAG_arg_variable ]"; - else if (Tag == dwarf::DW_TAG_return_variable) - Out << "; [ DW_TAG_return_variable ]"; - else if (Tag == dwarf::DW_TAG_vector_type) - Out << "; [ DW_TAG_vector_type ]"; - else if (Tag == dwarf::DW_TAG_user_base) + if (Tag == dwarf::DW_TAG_user_base) Out << "; [ DW_TAG_user_base ]"; else if (Tag.isIntN(32)) { if (const char *TagName = dwarf::TagString(Tag.getZExtValue())) diff --git a/lib/VMCore/Attributes.cpp b/lib/VMCore/Attributes.cpp index 477111a..92152a3 100644 --- a/lib/VMCore/Attributes.cpp +++ b/lib/VMCore/Attributes.cpp @@ -15,8 +15,8 @@ #include "llvm/Type.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/FoldingSet.h" -#include "llvm/System/Atomic.h" -#include "llvm/System/Mutex.h" +#include "llvm/Support/Atomic.h" +#include "llvm/Support/Mutex.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/raw_ostream.h" @@ -106,6 +106,11 @@ Attributes Attribute::typeIncompatible(const Type *Ty) { // AttributeListImpl Definition //===----------------------------------------------------------------------===// +namespace llvm { + class AttributeListImpl; +} + +static ManagedStatic<FoldingSet<AttributeListImpl> > AttributesLists; namespace llvm { static ManagedStatic<sys::SmartMutex<true> > ALMutex; @@ -131,6 +136,8 @@ public: } void DropRef() { sys::SmartScopedLock<true> Lock(*ALMutex); + if (!AttributesLists.isConstructed()) + return; sys::cas_flag new_val = --RefCount; if (new_val == 0) delete this; @@ -147,8 +154,6 @@ public: }; } -static ManagedStatic<FoldingSet<AttributeListImpl> > AttributesLists; - AttributeListImpl::~AttributeListImpl() { // NOTE: Lock must be acquired by caller. AttributesLists->RemoveNode(this); diff --git a/lib/VMCore/AutoUpgrade.cpp b/lib/VMCore/AutoUpgrade.cpp index 64b0b51..b323540 100644 --- a/lib/VMCore/AutoUpgrade.cpp +++ b/lib/VMCore/AutoUpgrade.cpp @@ -859,7 +859,7 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) { for (unsigned i = 0; i != 8; ++i) Indices.push_back(ConstantInt::get(IntTy, shiftVal + i)); - Value *SV = ConstantVector::get(Indices.begin(), Indices.size()); + Value *SV = ConstantVector::get(Indices); Rep = Builder.CreateShuffleVector(Op2, Op1, SV, "palignr"); Rep = Builder.CreateBitCast(Rep, F->getReturnType()); } @@ -915,7 +915,7 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) { for (unsigned i = 0; i != 16; ++i) Indices.push_back(ConstantInt::get(IntTy, shiftVal + i)); - Value *SV = ConstantVector::get(Indices.begin(), Indices.size()); + Value *SV = ConstantVector::get(Indices); Rep = Builder.CreateShuffleVector(Op2, Op1, SV, "palignr"); Rep = Builder.CreateBitCast(Rep, F->getReturnType()); } diff --git a/lib/VMCore/BasicBlock.cpp b/lib/VMCore/BasicBlock.cpp index 8ad5373..955a028 100644 --- a/lib/VMCore/BasicBlock.cpp +++ b/lib/VMCore/BasicBlock.cpp @@ -248,10 +248,11 @@ void BasicBlock::removePredecessor(BasicBlock *Pred, // If all incoming values to the Phi are the same, we can replace the Phi // with that value. Value* PNV = 0; - if (!DontDeleteUselessPHIs && (PNV = PN->hasConstantValue())) { - PN->replaceAllUsesWith(PNV); - PN->eraseFromParent(); - } + if (!DontDeleteUselessPHIs && (PNV = PN->hasConstantValue())) + if (PNV != PN) { + PN->replaceAllUsesWith(PNV); + PN->eraseFromParent(); + } } } } diff --git a/lib/VMCore/CMakeLists.txt b/lib/VMCore/CMakeLists.txt index 0ff260f..1abd031 100644 --- a/lib/VMCore/CMakeLists.txt +++ b/lib/VMCore/CMakeLists.txt @@ -30,6 +30,7 @@ add_llvm_library(LLVMCore Type.cpp TypeSymbolTable.cpp Use.cpp + User.cpp Value.cpp ValueSymbolTable.cpp ValueTypes.cpp diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp index 9a91daf..573efb7 100644 --- a/lib/VMCore/ConstantFold.cpp +++ b/lib/VMCore/ConstantFold.cpp @@ -42,6 +42,10 @@ using namespace llvm; /// input vector constant are all simple integer or FP values. static Constant *BitCastConstantVector(ConstantVector *CV, const VectorType *DstTy) { + + if (CV->isAllOnesValue()) return Constant::getAllOnesValue(DstTy); + if (CV->isNullValue()) return Constant::getNullValue(DstTy); + // If this cast changes element count then we can't handle it here: // doing so requires endianness information. This should be handled by // Analysis/ConstantFolding.cpp @@ -145,7 +149,7 @@ static Constant *FoldBitCast(Constant *V, const Type *DestTy) { // This allows for other simplifications (although some of them // can only be handled by Analysis/ConstantFolding.cpp). if (isa<ConstantInt>(V) || isa<ConstantFP>(V)) - return ConstantExpr::getBitCast(ConstantVector::get(&V, 1), DestPTy); + return ConstantExpr::getBitCast(ConstantVector::get(V), DestPTy); } // Finally, implement bitcast folding now. The code below doesn't handle @@ -202,7 +206,7 @@ static Constant *ExtractConstantBytes(Constant *C, unsigned ByteStart, APInt V = CI->getValue(); if (ByteStart) V = V.lshr(ByteStart*8); - V.trunc(ByteSize*8); + V = V.trunc(ByteSize*8); return ConstantInt::get(CI->getContext(), V); } @@ -511,10 +515,14 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, Constant *V, return Constant::getNullValue(DestTy); return UndefValue::get(DestTy); } + // No compile-time operations on this type yet. if (V->getType()->isPPC_FP128Ty() || DestTy->isPPC_FP128Ty()) return 0; + if (V->isNullValue() && !DestTy->isX86_MMXTy()) + return Constant::getNullValue(DestTy); + // If the cast operand is a constant expression, there's a few things we can // do to try to simplify it. if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) { @@ -637,9 +645,7 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, Constant *V, case Instruction::SIToFP: if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) { APInt api = CI->getValue(); - const uint64_t zero[] = {0, 0}; - APFloat apf = APFloat(APInt(DestTy->getPrimitiveSizeInBits(), - 2, zero)); + APFloat apf(APInt::getNullValue(DestTy->getPrimitiveSizeInBits()), true); (void)apf.convertFromAPInt(api, opc==Instruction::SIToFP, APFloat::rmNearestTiesToEven); @@ -649,25 +655,22 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, Constant *V, case Instruction::ZExt: if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) { uint32_t BitWidth = cast<IntegerType>(DestTy)->getBitWidth(); - APInt Result(CI->getValue()); - Result.zext(BitWidth); - return ConstantInt::get(V->getContext(), Result); + return ConstantInt::get(V->getContext(), + CI->getValue().zext(BitWidth)); } return 0; case Instruction::SExt: if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) { uint32_t BitWidth = cast<IntegerType>(DestTy)->getBitWidth(); - APInt Result(CI->getValue()); - Result.sext(BitWidth); - return ConstantInt::get(V->getContext(), Result); + return ConstantInt::get(V->getContext(), + CI->getValue().sext(BitWidth)); } return 0; case Instruction::Trunc: { uint32_t DestBitWidth = cast<IntegerType>(DestTy)->getBitWidth(); if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) { - APInt Result(CI->getValue()); - Result.trunc(DestBitWidth); - return ConstantInt::get(V->getContext(), Result); + return ConstantInt::get(V->getContext(), + CI->getValue().trunc(DestBitWidth)); } // The input must be a constantexpr. See if we can simplify this based on @@ -690,10 +693,58 @@ Constant *llvm::ConstantFoldSelectInstruction(Constant *Cond, if (ConstantInt *CB = dyn_cast<ConstantInt>(Cond)) return CB->getZExtValue() ? V1 : V2; + // Check for zero aggregate and ConstantVector of zeros + if (Cond->isNullValue()) return V2; + + if (ConstantVector* CondV = dyn_cast<ConstantVector>(Cond)) { + + if (CondV->isAllOnesValue()) return V1; + + const VectorType *VTy = cast<VectorType>(V1->getType()); + ConstantVector *CP1 = dyn_cast<ConstantVector>(V1); + ConstantVector *CP2 = dyn_cast<ConstantVector>(V2); + + if ((CP1 || isa<ConstantAggregateZero>(V1)) && + (CP2 || isa<ConstantAggregateZero>(V2))) { + + // Find the element type of the returned vector + const Type *EltTy = VTy->getElementType(); + unsigned NumElem = VTy->getNumElements(); + std::vector<Constant*> Res(NumElem); + + bool Valid = true; + for (unsigned i = 0; i < NumElem; ++i) { + ConstantInt* c = dyn_cast<ConstantInt>(CondV->getOperand(i)); + if (!c) { + Valid = false; + break; + } + Constant *C1 = CP1 ? CP1->getOperand(i) : Constant::getNullValue(EltTy); + Constant *C2 = CP2 ? CP2->getOperand(i) : Constant::getNullValue(EltTy); + Res[i] = c->getZExtValue() ? C1 : C2; + } + // If we were able to build the vector, return it + if (Valid) return ConstantVector::get(Res); + } + } + + if (isa<UndefValue>(V1)) return V2; if (isa<UndefValue>(V2)) return V1; if (isa<UndefValue>(Cond)) return V1; if (V1 == V2) return V1; + + if (ConstantExpr *TrueVal = dyn_cast<ConstantExpr>(V1)) { + if (TrueVal->getOpcode() == Instruction::Select) + if (TrueVal->getOperand(0) == Cond) + return ConstantExpr::getSelect(Cond, TrueVal->getOperand(1), V2); + } + if (ConstantExpr *FalseVal = dyn_cast<ConstantExpr>(V2)) { + if (FalseVal->getOpcode() == Instruction::Select) + if (FalseVal->getOperand(0) == Cond) + return ConstantExpr::getSelect(Cond, V1, FalseVal->getOperand(2)); + } + return 0; } @@ -821,7 +872,7 @@ Constant *llvm::ConstantFoldShuffleVectorInstruction(Constant *V1, Result.push_back(InElt); } - return ConstantVector::get(&Result[0], Result.size()); + return ConstantVector::get(Result); } Constant *llvm::ConstantFoldExtractValueInstruction(Constant *Agg, @@ -982,8 +1033,8 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, return Constant::getNullValue(C1->getType()); // X lshr undef -> 0 // undef lshr X -> 0 case Instruction::AShr: - if (!isa<UndefValue>(C2)) - return C1; // undef ashr X --> undef + if (!isa<UndefValue>(C2)) // undef ashr X --> all ones + return Constant::getAllOnesValue(C1->getType()); else if (isa<UndefValue>(C1)) return C1; // undef ashr undef -> undef else @@ -1343,8 +1394,7 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, // Given ((a + b) + c), if (b + c) folds to something interesting, return // (a + (b + c)). - if (Instruction::isAssociative(Opcode, C1->getType()) && - CE1->getOpcode() == Opcode) { + if (Instruction::isAssociative(Opcode) && CE1->getOpcode() == Opcode) { Constant *T = ConstantExpr::get(Opcode, CE1->getOperand(1), C2); if (!isa<ConstantExpr>(T) || cast<ConstantExpr>(T)->getOpcode() != Opcode) return ConstantExpr::get(Opcode, CE1->getOperand(0), T); @@ -1413,7 +1463,7 @@ static bool isMaybeZeroSizedType(const Type *Ty) { /// first is less than the second, return -1, if the second is less than the /// first, return 1. If the constants are not integral, return -2. /// -static int IdxCompare(Constant *C1, Constant *C2, const Type *ElTy) { +static int IdxCompare(Constant *C1, Constant *C2, const Type *ElTy) { if (C1 == C2) return 0; // Ok, we found a different index. If they are not ConstantInt, we can't do @@ -1896,11 +1946,11 @@ Constant *llvm::ConstantFoldCompareInstruction(unsigned short pred, // If we can constant fold the comparison of each element, constant fold // the whole vector comparison. SmallVector<Constant*, 4> ResElts; - for (unsigned i = 0, e = C1Elts.size(); i != e; ++i) { - // Compare the elements, producing an i1 result or constant expr. + // Compare the elements, producing an i1 result or constant expr. + for (unsigned i = 0, e = C1Elts.size(); i != e; ++i) ResElts.push_back(ConstantExpr::getCompare(pred, C1Elts[i], C2Elts[i])); - } - return ConstantVector::get(&ResElts[0], ResElts.size()); + + return ConstantVector::get(ResElts); } if (C1->getType()->isFloatingPointTy()) { @@ -1948,7 +1998,7 @@ Constant *llvm::ConstantFoldCompareInstruction(unsigned short pred, else if (pred == FCmpInst::FCMP_UGT || pred == FCmpInst::FCMP_OGT) Result = 1; break; - case ICmpInst::ICMP_NE: // We know that C1 != C2 + case FCmpInst::FCMP_ONE: // We know that C1 != C2 // We can only partially decide this relation. if (pred == FCmpInst::FCMP_OEQ || pred == FCmpInst::FCMP_UEQ) Result = 0; @@ -2073,56 +2123,55 @@ Constant *llvm::ConstantFoldCompareInstruction(unsigned short pred, /// isInBoundsIndices - Test whether the given sequence of *normalized* indices /// is "inbounds". -static bool isInBoundsIndices(Constant *const *Idxs, size_t NumIdx) { +template<typename IndexTy> +static bool isInBoundsIndices(IndexTy const *Idxs, size_t NumIdx) { // No indices means nothing that could be out of bounds. if (NumIdx == 0) return true; // If the first index is zero, it's in bounds. - if (Idxs[0]->isNullValue()) return true; + if (cast<Constant>(Idxs[0])->isNullValue()) return true; // If the first index is one and all the rest are zero, it's in bounds, // by the one-past-the-end rule. if (!cast<ConstantInt>(Idxs[0])->isOne()) return false; for (unsigned i = 1, e = NumIdx; i != e; ++i) - if (!Idxs[i]->isNullValue()) + if (!cast<Constant>(Idxs[i])->isNullValue()) return false; return true; } -Constant *llvm::ConstantFoldGetElementPtr(Constant *C, - bool inBounds, - Constant* const *Idxs, - unsigned NumIdx) { +template<typename IndexTy> +static Constant *ConstantFoldGetElementPtrImpl(Constant *C, + bool inBounds, + IndexTy const *Idxs, + unsigned NumIdx) { + Constant *Idx0 = cast<Constant>(Idxs[0]); if (NumIdx == 0 || - (NumIdx == 1 && Idxs[0]->isNullValue())) + (NumIdx == 1 && Idx0->isNullValue())) return C; if (isa<UndefValue>(C)) { const PointerType *Ptr = cast<PointerType>(C->getType()); - const Type *Ty = GetElementPtrInst::getIndexedType(Ptr, - (Value **)Idxs, - (Value **)Idxs+NumIdx); + const Type *Ty = GetElementPtrInst::getIndexedType(Ptr, Idxs, Idxs+NumIdx); assert(Ty != 0 && "Invalid indices for GEP!"); return UndefValue::get(PointerType::get(Ty, Ptr->getAddressSpace())); } - Constant *Idx0 = Idxs[0]; if (C->isNullValue()) { bool isNull = true; for (unsigned i = 0, e = NumIdx; i != e; ++i) - if (!Idxs[i]->isNullValue()) { + if (!cast<Constant>(Idxs[i])->isNullValue()) { isNull = false; break; } if (isNull) { const PointerType *Ptr = cast<PointerType>(C->getType()); - const Type *Ty = GetElementPtrInst::getIndexedType(Ptr, - (Value**)Idxs, - (Value**)Idxs+NumIdx); + const Type *Ty = GetElementPtrInst::getIndexedType(Ptr, Idxs, + Idxs+NumIdx); assert(Ty != 0 && "Invalid indices for GEP!"); - return ConstantPointerNull::get( - PointerType::get(Ty,Ptr->getAddressSpace())); + return ConstantPointerNull::get(PointerType::get(Ty, + Ptr->getAddressSpace())); } } @@ -2173,9 +2222,9 @@ Constant *llvm::ConstantFoldGetElementPtr(Constant *C, } // Implement folding of: - // int* getelementptr ([2 x int]* bitcast ([3 x int]* %X to [2 x int]*), - // long 0, long 0) - // To: int* getelementptr ([3 x int]* %X, long 0, long 0) + // i32* getelementptr ([2 x i32]* bitcast ([3 x i32]* %X to [2 x i32]*), + // i64 0, i64 0) + // To: i32* getelementptr ([3 x i32]* %X, i64 0, i64 0) // if (CE->isCast() && NumIdx > 1 && Idx0->isNullValue()) { if (const PointerType *SPT = @@ -2214,7 +2263,7 @@ Constant *llvm::ConstantFoldGetElementPtr(Constant *C, ATy->getNumElements()); NewIdxs[i] = ConstantExpr::getSRem(CI, Factor); - Constant *PrevIdx = Idxs[i-1]; + Constant *PrevIdx = cast<Constant>(Idxs[i-1]); Constant *Div = ConstantExpr::getSDiv(CI, Factor); // Before adding, extend both operands to i64 to avoid @@ -2242,7 +2291,7 @@ Constant *llvm::ConstantFoldGetElementPtr(Constant *C, // If we did any factoring, start over with the adjusted indices. if (!NewIdxs.empty()) { for (unsigned i = 0; i != NumIdx; ++i) - if (!NewIdxs[i]) NewIdxs[i] = Idxs[i]; + if (!NewIdxs[i]) NewIdxs[i] = cast<Constant>(Idxs[i]); return inBounds ? ConstantExpr::getInBoundsGetElementPtr(C, NewIdxs.data(), NewIdxs.size()) : @@ -2257,3 +2306,17 @@ Constant *llvm::ConstantFoldGetElementPtr(Constant *C, return 0; } + +Constant *llvm::ConstantFoldGetElementPtr(Constant *C, + bool inBounds, + Constant* const *Idxs, + unsigned NumIdx) { + return ConstantFoldGetElementPtrImpl(C, inBounds, Idxs, NumIdx); +} + +Constant *llvm::ConstantFoldGetElementPtr(Constant *C, + bool inBounds, + Value* const *Idxs, + unsigned NumIdx) { + return ConstantFoldGetElementPtrImpl(C, inBounds, Idxs, NumIdx); +} diff --git a/lib/VMCore/ConstantFold.h b/lib/VMCore/ConstantFold.h index d2dbbdd..0ecd7b4 100644 --- a/lib/VMCore/ConstantFold.h +++ b/lib/VMCore/ConstantFold.h @@ -49,6 +49,8 @@ namespace llvm { Constant *C1, Constant *C2); Constant *ConstantFoldGetElementPtr(Constant *C, bool inBounds, Constant* const *Idxs, unsigned NumIdx); + Constant *ConstantFoldGetElementPtr(Constant *C, bool inBounds, + Value* const *Idxs, unsigned NumIdx); } // End llvm namespace #endif diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp index 16eaca8..7a4dcf9 100644 --- a/lib/VMCore/Constants.cpp +++ b/lib/VMCore/Constants.cpp @@ -33,6 +33,7 @@ #include "llvm/ADT/SmallVector.h" #include <algorithm> #include <map> +#include <cstdarg> using namespace llvm; //===----------------------------------------------------------------------===// @@ -40,22 +41,25 @@ using namespace llvm; //===----------------------------------------------------------------------===// // Constructor to create a '0' constant of arbitrary type... -static const uint64_t zero[2] = {0, 0}; Constant *Constant::getNullValue(const Type *Ty) { switch (Ty->getTypeID()) { case Type::IntegerTyID: return ConstantInt::get(Ty, 0); case Type::FloatTyID: - return ConstantFP::get(Ty->getContext(), APFloat(APInt(32, 0))); + return ConstantFP::get(Ty->getContext(), + APFloat::getZero(APFloat::IEEEsingle)); case Type::DoubleTyID: - return ConstantFP::get(Ty->getContext(), APFloat(APInt(64, 0))); + return ConstantFP::get(Ty->getContext(), + APFloat::getZero(APFloat::IEEEdouble)); case Type::X86_FP80TyID: - return ConstantFP::get(Ty->getContext(), APFloat(APInt(80, 2, zero))); + return ConstantFP::get(Ty->getContext(), + APFloat::getZero(APFloat::x87DoubleExtended)); case Type::FP128TyID: return ConstantFP::get(Ty->getContext(), - APFloat(APInt(128, 2, zero), true)); + APFloat::getZero(APFloat::IEEEquad)); case Type::PPC_FP128TyID: - return ConstantFP::get(Ty->getContext(), APFloat(APInt(128, 2, zero))); + return ConstantFP::get(Ty->getContext(), + APFloat(APInt::getNullValue(128))); case Type::PointerTyID: return ConstantPointerNull::get(cast<PointerType>(Ty)); case Type::StructTyID: @@ -69,7 +73,7 @@ Constant *Constant::getNullValue(const Type *Ty) { } } -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. @@ -86,12 +90,18 @@ Constant* Constant::getIntegerValue(const Type *Ty, const APInt &V) { 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())); - - std::vector<Constant*> Elts; + + if (Ty->isFloatingPointTy()) { + APFloat FL = APFloat::getAllOnesValue(Ty->getPrimitiveSizeInBits(), + !Ty->isPPC_FP128Ty()); + return ConstantFP::get(Ty->getContext(), FL); + } + + SmallVector<Constant*, 16> Elts; const VectorType *VTy = cast<VectorType>(Ty); Elts.resize(VTy->getNumElements(), getAllOnesValue(VTy->getElementType())); assert(Elts[0] && "Not a vector integer type!"); @@ -253,6 +263,59 @@ void Constant::getVectorElements(SmallVectorImpl<Constant*> &Elts) const { } +/// removeDeadUsersOfConstant - If the specified constantexpr is dead, remove +/// it. This involves recursively eliminating any dead users of the +/// constantexpr. +static bool removeDeadUsersOfConstant(const Constant *C) { + if (isa<GlobalValue>(C)) return false; // Cannot remove this + + while (!C->use_empty()) { + const Constant *User = dyn_cast<Constant>(C->use_back()); + if (!User) return false; // Non-constant usage; + if (!removeDeadUsersOfConstant(User)) + return false; // Constant wasn't dead + } + + const_cast<Constant*>(C)->destroyConstant(); + return true; +} + + +/// removeDeadConstantUsers - If there are any dead constant users dangling +/// off of this constant, remove them. This method is useful for clients +/// that want to check to see if a global is unused, but don't want to deal +/// with potentially dead constants hanging off of the globals. +void Constant::removeDeadConstantUsers() const { + Value::const_use_iterator I = use_begin(), E = use_end(); + Value::const_use_iterator LastNonDeadUser = E; + while (I != E) { + const Constant *User = dyn_cast<Constant>(*I); + if (User == 0) { + LastNonDeadUser = I; + ++I; + continue; + } + + if (!removeDeadUsersOfConstant(User)) { + // If the constant wasn't dead, remember that this was the last live use + // and move on to the next constant. + LastNonDeadUser = I; + ++I; + continue; + } + + // If the constant was dead, then the iterator is invalidated. + if (LastNonDeadUser == E) { + I = use_begin(); + if (I == E) break; + } else { + I = LastNonDeadUser; + ++I; + } + } +} + + //===----------------------------------------------------------------------===// // ConstantInt @@ -263,22 +326,44 @@ ConstantInt::ConstantInt(const IntegerType *Ty, const APInt& V) assert(V.getBitWidth() == Ty->getBitWidth() && "Invalid constant for type"); } -ConstantInt* ConstantInt::getTrue(LLVMContext &Context) { +ConstantInt *ConstantInt::getTrue(LLVMContext &Context) { LLVMContextImpl *pImpl = Context.pImpl; - if (pImpl->TheTrueVal) - return pImpl->TheTrueVal; - else - return (pImpl->TheTrueVal = - ConstantInt::get(IntegerType::get(Context, 1), 1)); + if (!pImpl->TheTrueVal) + pImpl->TheTrueVal = ConstantInt::get(Type::getInt1Ty(Context), 1); + return pImpl->TheTrueVal; } -ConstantInt* ConstantInt::getFalse(LLVMContext &Context) { +ConstantInt *ConstantInt::getFalse(LLVMContext &Context) { LLVMContextImpl *pImpl = Context.pImpl; - if (pImpl->TheFalseVal) - return pImpl->TheFalseVal; - else - return (pImpl->TheFalseVal = - ConstantInt::get(IntegerType::get(Context, 1), 0)); + if (!pImpl->TheFalseVal) + pImpl->TheFalseVal = ConstantInt::get(Type::getInt1Ty(Context), 0); + return pImpl->TheFalseVal; +} + +Constant *ConstantInt::getTrue(const Type *Ty) { + const VectorType *VTy = dyn_cast<VectorType>(Ty); + if (!VTy) { + assert(Ty->isIntegerTy(1) && "True must be i1 or vector of i1."); + return ConstantInt::getTrue(Ty->getContext()); + } + assert(VTy->getElementType()->isIntegerTy(1) && + "True must be vector of i1 or i1."); + SmallVector<Constant*, 16> Splat(VTy->getNumElements(), + ConstantInt::getTrue(Ty->getContext())); + return ConstantVector::get(Splat); +} + +Constant *ConstantInt::getFalse(const Type *Ty) { + const VectorType *VTy = dyn_cast<VectorType>(Ty); + if (!VTy) { + assert(Ty->isIntegerTy(1) && "False must be i1 or vector of i1."); + return ConstantInt::getFalse(Ty->getContext()); + } + assert(VTy->getElementType()->isIntegerTy(1) && + "False must be vector of i1 or i1."); + SmallVector<Constant*, 16> Splat(VTy->getNumElements(), + ConstantInt::getFalse(Ty->getContext())); + return ConstantVector::get(Splat); } @@ -287,7 +372,7 @@ ConstantInt* ConstantInt::getFalse(LLVMContext &Context) { // operator== and operator!= to ensure that the DenseMap doesn't attempt to // compare APInt's of different widths, which would violate an APInt class // invariant which generates an assertion. -ConstantInt *ConstantInt::get(LLVMContext &Context, const APInt& V) { +ConstantInt *ConstantInt::get(LLVMContext &Context, const APInt &V) { // Get the corresponding integer type for the bit width of the value. const IntegerType *ITy = IntegerType::get(Context, V.getBitWidth()); // get an existing value or the insertion position @@ -297,14 +382,13 @@ ConstantInt *ConstantInt::get(LLVMContext &Context, const APInt& V) { return Slot; } -Constant* ConstantInt::get(const Type* Ty, uint64_t V, bool isSigned) { - Constant *C = get(cast<IntegerType>(Ty->getScalarType()), - V, isSigned); +Constant *ConstantInt::get(const Type *Ty, uint64_t V, bool isSigned) { + Constant *C = get(cast<IntegerType>(Ty->getScalarType()), V, isSigned); // For vectors, broadcast the value. if (const VectorType *VTy = dyn_cast<VectorType>(Ty)) - return ConstantVector::get( - std::vector<Constant *>(VTy->getNumElements(), C)); + return ConstantVector::get(SmallVector<Constant*, + 16>(VTy->getNumElements(), C)); return C; } @@ -322,7 +406,7 @@ Constant *ConstantInt::getSigned(const Type *Ty, int64_t V) { 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!"); @@ -330,7 +414,7 @@ Constant* ConstantInt::get(const Type* Ty, const APInt& V) { // For vectors, broadcast the value. if (const VectorType *VTy = dyn_cast<VectorType>(Ty)) return ConstantVector::get( - std::vector<Constant *>(VTy->getNumElements(), C)); + SmallVector<Constant *, 16>(VTy->getNumElements(), C)); return C; } @@ -361,7 +445,7 @@ static const fltSemantics *TypeToFloatSemantics(const Type *Ty) { /// 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); @@ -373,13 +457,13 @@ Constant* ConstantFP::get(const Type* Ty, double V) { // For vectors, broadcast the value. if (const VectorType *VTy = dyn_cast<VectorType>(Ty)) return ConstantVector::get( - std::vector<Constant *>(VTy->getNumElements(), C)); + SmallVector<Constant *, 16>(VTy->getNumElements(), C)); return C; } -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); @@ -388,7 +472,7 @@ Constant* ConstantFP::get(const Type* Ty, StringRef Str) { // For vectors, broadcast the value. if (const VectorType *VTy = dyn_cast<VectorType>(Ty)) return ConstantVector::get( - std::vector<Constant *>(VTy->getNumElements(), C)); + SmallVector<Constant *, 16>(VTy->getNumElements(), C)); return C; } @@ -402,12 +486,12 @@ ConstantFP* ConstantFP::getNegativeZero(const Type* Ty) { } -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(), + SmallVector<Constant*, 16> zeros(PTy->getNumElements(), getNegativeZero(PTy->getElementType())); - return ConstantVector::get(PTy, zeros); + return ConstantVector::get(zeros); } if (Ty->isFloatingPointTy()) @@ -510,7 +594,7 @@ Constant *ConstantArray::get(const ArrayType *Ty, } -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)); @@ -522,7 +606,7 @@ Constant* ConstantArray::get(const ArrayType* T, Constant* const* Vals, /// 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)); @@ -538,8 +622,6 @@ Constant* ConstantArray::get(LLVMContext &Context, StringRef Str, return get(ATy, ElementVals); } - - ConstantStruct::ConstantStruct(const StructType *T, const std::vector<Constant*> &V) : Constant(T, ConstantStructVal, @@ -558,7 +640,7 @@ ConstantStruct::ConstantStruct(const StructType *T, } // ConstantStruct accessors. -Constant* ConstantStruct::get(const StructType* T, +Constant *ConstantStruct::get(const StructType* T, const std::vector<Constant*>& V) { LLVMContextImpl* pImpl = T->getContext().pImpl; @@ -570,7 +652,7 @@ Constant* ConstantStruct::get(const StructType* T, 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()); @@ -579,36 +661,48 @@ Constant* ConstantStruct::get(LLVMContext &Context, 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); } +Constant* ConstantStruct::get(LLVMContext &Context, bool Packed, + Constant * Val, ...) { + va_list ap; + std::vector<Constant*> Values; + va_start(ap, Val); + while (Val) { + Values.push_back(Val); + Val = va_arg(ap, llvm::Constant*); + } + va_end(ap); + return get(Context, Values, Packed); +} + ConstantVector::ConstantVector(const VectorType *T, const std::vector<Constant*> &V) : Constant(T, ConstantVectorVal, OperandTraits<ConstantVector>::op_end(this) - V.size(), V.size()) { Use *OL = OperandList; - for (std::vector<Constant*>::const_iterator I = V.begin(), E = V.end(); - I != E; ++I, ++OL) { - Constant *C = *I; - assert(C->getType() == T->getElementType() && + for (std::vector<Constant*>::const_iterator I = V.begin(), E = V.end(); + I != E; ++I, ++OL) { + Constant *C = *I; + assert(C->getType() == T->getElementType() && "Initializer for vector element doesn't match vector element type!"); *OL = C; } } // ConstantVector accessors. -Constant* ConstantVector::get(const VectorType* T, - const std::vector<Constant*>& V) { - assert(!V.empty() && "Vectors can't be empty"); - LLVMContext &Context = T->getContext(); - LLVMContextImpl *pImpl = Context.pImpl; - - // If this is an all-undef or alll-zero vector, return a +Constant *ConstantVector::get(const VectorType *T, + const std::vector<Constant*> &V) { + assert(!V.empty() && "Vectors can't be empty"); + LLVMContextImpl *pImpl = T->getContext().pImpl; + + // If this is an all-undef or all-zero vector, return a // ConstantAggregateZero or UndefValue. Constant *C = V[0]; bool isZero = C->isNullValue(); @@ -630,61 +724,10 @@ Constant* ConstantVector::get(const VectorType* T, return pImpl->VectorConstants.getOrCreate(T, 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(ArrayRef<Constant*> V) { // FIXME: make this the primary ctor method. - return get(std::vector<Constant*>(Vals, Vals+NumVals)); -} - -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) { - assert(C->getType()->isIntOrIntVectorTy() && - "Cannot NEG a nonintegral value!"); - return getNUWSub(ConstantFP::getZeroValueForNegation(C->getType()), C); -} - -Constant* ConstantExpr::getNSWAdd(Constant* C1, Constant* C2) { - return getTy(C1->getType(), Instruction::Add, C1, C2, - OverflowingBinaryOperator::NoSignedWrap); -} - -Constant* ConstantExpr::getNUWAdd(Constant* C1, Constant* C2) { - return getTy(C1->getType(), Instruction::Add, C1, C2, - OverflowingBinaryOperator::NoUnsignedWrap); -} - -Constant* ConstantExpr::getNSWSub(Constant* C1, Constant* C2) { - return getTy(C1->getType(), Instruction::Sub, C1, C2, - OverflowingBinaryOperator::NoSignedWrap); -} - -Constant* ConstantExpr::getNUWSub(Constant* C1, Constant* C2) { - return getTy(C1->getType(), Instruction::Sub, C1, C2, - OverflowingBinaryOperator::NoUnsignedWrap); -} - -Constant* ConstantExpr::getNSWMul(Constant* C1, Constant* C2) { - return getTy(C1->getType(), Instruction::Mul, C1, C2, - OverflowingBinaryOperator::NoSignedWrap); -} - -Constant* ConstantExpr::getNUWMul(Constant* C1, Constant* C2) { - return getTy(C1->getType(), Instruction::Mul, C1, C2, - OverflowingBinaryOperator::NoUnsignedWrap); -} - -Constant* ConstantExpr::getExactSDiv(Constant* C1, Constant* C2) { - return getTy(C1->getType(), Instruction::SDiv, C1, C2, - SDivOperator::IsExact); + assert(!V.empty() && "Vectors cannot be empty"); + return get(VectorType::get(V.front()->getType(), V.size()), V.vec()); } // Utility function for determining if a ConstantExpr is a CastOp or not. This @@ -812,7 +855,7 @@ ConstantExpr::getWithOperandReplaced(unsigned OpNo, Constant *Op) const { /// 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) { @@ -1034,7 +1077,7 @@ bool ConstantVector::isAllOnesValue() const { /// getSplatValue - If this is a splat constant, where all of the /// elements have the same value, return that value. Otherwise return null. -Constant *ConstantVector::getSplatValue() { +Constant *ConstantVector::getSplatValue() const { // Check out first element. Constant *Elt = getOperand(0); // Then make sure all remaining elements point to the same value. @@ -1241,7 +1284,7 @@ Constant *ConstantExpr::getFPCast(Constant *C, const Type *Ty) { if (SrcBits == DstBits) return C; // Avoid a useless cast Instruction::CastOps opcode = - (SrcBits > DstBits ? Instruction::FPTrunc : Instruction::FPExt); + (SrcBits > DstBits ? Instruction::FPTrunc : Instruction::FPExt); return getCast(opcode, C, Ty); } @@ -1482,7 +1525,7 @@ Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2, 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); @@ -1492,7 +1535,7 @@ Constant* ConstantExpr::getSizeOf(const Type* Ty) { 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(), @@ -1506,12 +1549,12 @@ Constant* ConstantExpr::getAlignOf(const Type* Ty) { 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[] = { @@ -1547,44 +1590,17 @@ Constant *ConstantExpr::getSelectTy(const Type *ReqTy, Constant *C, return pImpl->ExprConstants.getOrCreate(ReqTy, Key); } +template<typename IndexTy> Constant *ConstantExpr::getGetElementPtrTy(const Type *ReqTy, Constant *C, - Value* const *Idxs, - unsigned NumIdx) { - assert(GetElementPtrInst::getIndexedType(C->getType(), Idxs, - Idxs+NumIdx) == - cast<PointerType>(ReqTy)->getElementType() && - "GEP indices invalid!"); - - if (Constant *FC = ConstantFoldGetElementPtr(C, /*inBounds=*/false, - (Constant**)Idxs, NumIdx)) - return FC; // Fold a few common cases... - - assert(C->getType()->isPointerTy() && - "Non-pointer type for constant GetElementPtr expression"); - // Look up the constant in the table first to ensure uniqueness - std::vector<Constant*> ArgVec; - ArgVec.reserve(NumIdx+1); - ArgVec.push_back(C); - for (unsigned i = 0; i != NumIdx; ++i) - ArgVec.push_back(cast<Constant>(Idxs[i])); - const ExprMapKeyType Key(Instruction::GetElementPtr, ArgVec); - - LLVMContextImpl *pImpl = ReqTy->getContext().pImpl; - return pImpl->ExprConstants.getOrCreate(ReqTy, Key); -} - -Constant *ConstantExpr::getInBoundsGetElementPtrTy(const Type *ReqTy, - Constant *C, - Value *const *Idxs, - unsigned NumIdx) { + IndexTy const *Idxs, + unsigned NumIdx, bool InBounds) { assert(GetElementPtrInst::getIndexedType(C->getType(), Idxs, Idxs+NumIdx) == cast<PointerType>(ReqTy)->getElementType() && "GEP indices invalid!"); - if (Constant *FC = ConstantFoldGetElementPtr(C, /*inBounds=*/true, - (Constant**)Idxs, NumIdx)) - return FC; // Fold a few common cases... + if (Constant *FC = ConstantFoldGetElementPtr(C, InBounds, Idxs, NumIdx)) + return FC; // Fold a few common cases. assert(C->getType()->isPointerTy() && "Non-pointer type for constant GetElementPtr expression"); @@ -1595,42 +1611,31 @@ Constant *ConstantExpr::getInBoundsGetElementPtrTy(const Type *ReqTy, for (unsigned i = 0; i != NumIdx; ++i) ArgVec.push_back(cast<Constant>(Idxs[i])); const ExprMapKeyType Key(Instruction::GetElementPtr, ArgVec, 0, - GEPOperator::IsInBounds); + InBounds ? GEPOperator::IsInBounds : 0); LLVMContextImpl *pImpl = ReqTy->getContext().pImpl; return pImpl->ExprConstants.getOrCreate(ReqTy, Key); } -Constant *ConstantExpr::getGetElementPtr(Constant *C, Value* const *Idxs, - unsigned NumIdx) { - // Get the result type of the getelementptr! - const Type *Ty = - GetElementPtrInst::getIndexedType(C->getType(), Idxs, Idxs+NumIdx); - assert(Ty && "GEP indices invalid!"); - unsigned As = cast<PointerType>(C->getType())->getAddressSpace(); - return getGetElementPtrTy(PointerType::get(Ty, As), C, Idxs, NumIdx); -} - -Constant *ConstantExpr::getInBoundsGetElementPtr(Constant *C, - Value* const *Idxs, - unsigned NumIdx) { +template<typename IndexTy> +Constant *ConstantExpr::getGetElementPtrImpl(Constant *C, IndexTy const *Idxs, + unsigned NumIdx, bool InBounds) { // Get the result type of the getelementptr! const Type *Ty = GetElementPtrInst::getIndexedType(C->getType(), Idxs, Idxs+NumIdx); assert(Ty && "GEP indices invalid!"); unsigned As = cast<PointerType>(C->getType())->getAddressSpace(); - return getInBoundsGetElementPtrTy(PointerType::get(Ty, As), C, Idxs, NumIdx); + return getGetElementPtrTy(PointerType::get(Ty, As), C, Idxs, NumIdx,InBounds); } -Constant *ConstantExpr::getGetElementPtr(Constant *C, Constant* const *Idxs, - unsigned NumIdx) { - return getGetElementPtr(C, (Value* const *)Idxs, NumIdx); +Constant *ConstantExpr::getGetElementPtr(Constant *C, Value* const *Idxs, + unsigned NumIdx, bool InBounds) { + return getGetElementPtrImpl(C, Idxs, NumIdx, InBounds); } -Constant *ConstantExpr::getInBoundsGetElementPtr(Constant *C, - Constant* const *Idxs, - unsigned NumIdx) { - return getInBoundsGetElementPtr(C, (Value* const *)Idxs, NumIdx); +Constant *ConstantExpr::getGetElementPtr(Constant *C, Constant *const *Idxs, + unsigned NumIdx, bool InBounds) { + return getGetElementPtrImpl(C, Idxs, NumIdx, InBounds); } Constant * @@ -1804,98 +1809,111 @@ Constant *ConstantExpr::getExtractValue(Constant *Agg, return getExtractValueTy(ReqTy, Agg, IdxList, NumIdx); } -Constant* ConstantExpr::getNeg(Constant* C) { +Constant *ConstantExpr::getNeg(Constant *C, bool HasNUW, bool HasNSW) { assert(C->getType()->isIntOrIntVectorTy() && "Cannot NEG a nonintegral value!"); - return get(Instruction::Sub, - ConstantFP::getZeroValueForNegation(C->getType()), - C); + return getSub(ConstantFP::getZeroValueForNegation(C->getType()), + C, HasNUW, HasNSW); } -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, - ConstantFP::getZeroValueForNegation(C->getType()), - C); + return getFSub(ConstantFP::getZeroValueForNegation(C->getType()), 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) { - return get(Instruction::Add, C1, C2); +Constant *ConstantExpr::getAdd(Constant *C1, Constant *C2, + bool HasNUW, bool HasNSW) { + unsigned Flags = (HasNUW ? OverflowingBinaryOperator::NoUnsignedWrap : 0) | + (HasNSW ? OverflowingBinaryOperator::NoSignedWrap : 0); + return get(Instruction::Add, C1, C2, Flags); } -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) { - return get(Instruction::Sub, C1, C2); +Constant *ConstantExpr::getSub(Constant *C1, Constant *C2, + bool HasNUW, bool HasNSW) { + unsigned Flags = (HasNUW ? OverflowingBinaryOperator::NoUnsignedWrap : 0) | + (HasNSW ? OverflowingBinaryOperator::NoSignedWrap : 0); + return get(Instruction::Sub, C1, C2, Flags); } -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) { - return get(Instruction::Mul, C1, C2); +Constant *ConstantExpr::getMul(Constant *C1, Constant *C2, + bool HasNUW, bool HasNSW) { + unsigned Flags = (HasNUW ? OverflowingBinaryOperator::NoUnsignedWrap : 0) | + (HasNSW ? OverflowingBinaryOperator::NoSignedWrap : 0); + return get(Instruction::Mul, C1, C2, Flags); } -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) { - return get(Instruction::UDiv, C1, C2); +Constant *ConstantExpr::getUDiv(Constant *C1, Constant *C2, bool isExact) { + return get(Instruction::UDiv, C1, C2, + isExact ? PossiblyExactOperator::IsExact : 0); } -Constant* ConstantExpr::getSDiv(Constant* C1, Constant* C2) { - return get(Instruction::SDiv, C1, C2); +Constant *ConstantExpr::getSDiv(Constant *C1, Constant *C2, bool isExact) { + return get(Instruction::SDiv, C1, C2, + isExact ? PossiblyExactOperator::IsExact : 0); } -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) { - return get(Instruction::Shl, C1, C2); +Constant *ConstantExpr::getShl(Constant *C1, Constant *C2, + bool HasNUW, bool HasNSW) { + unsigned Flags = (HasNUW ? OverflowingBinaryOperator::NoUnsignedWrap : 0) | + (HasNSW ? OverflowingBinaryOperator::NoSignedWrap : 0); + return get(Instruction::Shl, C1, C2, Flags); } -Constant* ConstantExpr::getLShr(Constant* C1, Constant* C2) { - return get(Instruction::LShr, C1, C2); +Constant *ConstantExpr::getLShr(Constant *C1, Constant *C2, bool isExact) { + return get(Instruction::LShr, C1, C2, + isExact ? PossiblyExactOperator::IsExact : 0); } -Constant* ConstantExpr::getAShr(Constant* C1, Constant* C2) { - return get(Instruction::AShr, C1, C2); +Constant *ConstantExpr::getAShr(Constant *C1, Constant *C2, bool isExact) { + return get(Instruction::AShr, C1, C2, + isExact ? PossiblyExactOperator::IsExact : 0); } // destroyConstant - Remove the constant from the constant table... @@ -2127,7 +2145,8 @@ void ConstantExpr::replaceUsesOfWithOnConstant(Value *From, Value *ToV, Indices.push_back(Val); } Replacement = ConstantExpr::getGetElementPtr(Pointer, - &Indices[0], Indices.size()); + &Indices[0], Indices.size(), + cast<GEPOperator>(this)->isInBounds()); } else if (getOpcode() == Instruction::ExtractValue) { Constant *Agg = getOperand(0); if (Agg == From) Agg = To; diff --git a/lib/VMCore/ConstantsContext.h b/lib/VMCore/ConstantsContext.h index 1c04c3e..ffc673f 100644 --- a/lib/VMCore/ConstantsContext.h +++ b/lib/VMCore/ConstantsContext.h @@ -239,54 +239,64 @@ struct CompareConstantExpr : public ConstantExpr { }; template <> -struct OperandTraits<UnaryConstantExpr> : public FixedNumOperandTraits<1> { +struct OperandTraits<UnaryConstantExpr> : + public FixedNumOperandTraits<UnaryConstantExpr, 1> { }; DEFINE_TRANSPARENT_OPERAND_ACCESSORS(UnaryConstantExpr, Value) template <> -struct OperandTraits<BinaryConstantExpr> : public FixedNumOperandTraits<2> { +struct OperandTraits<BinaryConstantExpr> : + public FixedNumOperandTraits<BinaryConstantExpr, 2> { }; DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BinaryConstantExpr, Value) template <> -struct OperandTraits<SelectConstantExpr> : public FixedNumOperandTraits<3> { +struct OperandTraits<SelectConstantExpr> : + public FixedNumOperandTraits<SelectConstantExpr, 3> { }; DEFINE_TRANSPARENT_OPERAND_ACCESSORS(SelectConstantExpr, Value) template <> -struct OperandTraits<ExtractElementConstantExpr> : public FixedNumOperandTraits<2> { +struct OperandTraits<ExtractElementConstantExpr> : + public FixedNumOperandTraits<ExtractElementConstantExpr, 2> { }; DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ExtractElementConstantExpr, Value) template <> -struct OperandTraits<InsertElementConstantExpr> : public FixedNumOperandTraits<3> { +struct OperandTraits<InsertElementConstantExpr> : + public FixedNumOperandTraits<InsertElementConstantExpr, 3> { }; DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertElementConstantExpr, Value) template <> -struct OperandTraits<ShuffleVectorConstantExpr> : public FixedNumOperandTraits<3> { +struct OperandTraits<ShuffleVectorConstantExpr> : + public FixedNumOperandTraits<ShuffleVectorConstantExpr, 3> { }; DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ShuffleVectorConstantExpr, Value) template <> -struct OperandTraits<ExtractValueConstantExpr> : public FixedNumOperandTraits<1> { +struct OperandTraits<ExtractValueConstantExpr> : + public FixedNumOperandTraits<ExtractValueConstantExpr, 1> { }; DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ExtractValueConstantExpr, Value) template <> -struct OperandTraits<InsertValueConstantExpr> : public FixedNumOperandTraits<2> { +struct OperandTraits<InsertValueConstantExpr> : + public FixedNumOperandTraits<InsertValueConstantExpr, 2> { }; DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertValueConstantExpr, Value) template <> -struct OperandTraits<GetElementPtrConstantExpr> : public VariadicOperandTraits<1> { +struct OperandTraits<GetElementPtrConstantExpr> : + public VariadicOperandTraits<GetElementPtrConstantExpr, 1> { }; DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GetElementPtrConstantExpr, Value) template <> -struct OperandTraits<CompareConstantExpr> : public FixedNumOperandTraits<2> { +struct OperandTraits<CompareConstantExpr> : + public FixedNumOperandTraits<CompareConstantExpr, 2> { }; DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CompareConstantExpr, Value) diff --git a/lib/VMCore/Core.cpp b/lib/VMCore/Core.cpp index b2be64c..35c3a2e 100644 --- a/lib/VMCore/Core.cpp +++ b/lib/VMCore/Core.cpp @@ -28,6 +28,7 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/Support/system_error.h" #include <cassert> #include <cstdlib> #include <cstring> @@ -36,7 +37,6 @@ using namespace llvm; void llvm::initializeCore(PassRegistry &Registry) { initializeDominatorTreePass(Registry); - initializeDominanceFrontierPass(Registry); initializePrintModulePassPass(Registry); initializePrintFunctionPassPass(Registry); initializeVerifierPass(Registry); @@ -128,6 +128,10 @@ LLVMTypeRef LLVMGetTypeByName(LLVMModuleRef M, const char *Name) { return wrap(unwrap(M)->getTypeByName(Name)); } +const char *LLVMGetTypeName(LLVMModuleRef M, LLVMTypeRef Ty) { + return unwrap(M)->getTypeName(unwrap(Ty)).c_str(); +} + void LLVMDumpModule(LLVMModuleRef M) { unwrap(M)->dump(); } @@ -138,6 +142,12 @@ void LLVMSetModuleInlineAsm(LLVMModuleRef M, const char *Asm) { } +/*--.. Operations on module contexts ......................................--*/ +LLVMContextRef LLVMGetModuleContext(LLVMModuleRef M) { + return wrap(&unwrap(M)->getContext()); +} + + /*===-- Operations on types -----------------------------------------------===*/ /*--.. Operations on all types (mostly) ....................................--*/ @@ -547,6 +557,14 @@ LLVMValueRef LLVMConstInt(LLVMTypeRef IntTy, unsigned long long N, return wrap(ConstantInt::get(unwrap<IntegerType>(IntTy), N, SignExtend != 0)); } +LLVMValueRef LLVMConstIntOfArbitraryPrecision(LLVMTypeRef IntTy, + unsigned NumWords, + const uint64_t Words[]) { + IntegerType *Ty = unwrap<IntegerType>(IntTy); + return wrap(ConstantInt::get(Ty->getContext(), + APInt(Ty->getBitWidth(), NumWords, Words))); +} + LLVMValueRef LLVMConstIntOfString(LLVMTypeRef IntTy, const char Str[], uint8_t Radix) { return wrap(ConstantInt::get(unwrap<IntegerType>(IntTy), StringRef(Str), @@ -615,8 +633,8 @@ LLVMValueRef LLVMConstStruct(LLVMValueRef *ConstantVals, unsigned Count, Packed); } LLVMValueRef LLVMConstVector(LLVMValueRef *ScalarConstantVals, unsigned Size) { - return wrap(ConstantVector::get( - unwrap<Constant>(ScalarConstantVals, Size), Size)); + return wrap(ConstantVector::get(ArrayRef<Constant*>( + unwrap<Constant>(ScalarConstantVals, Size), Size))); } /*--.. Constant expressions ................................................--*/ @@ -633,74 +651,62 @@ LLVMValueRef LLVMSizeOf(LLVMTypeRef Ty) { } LLVMValueRef LLVMConstNeg(LLVMValueRef ConstantVal) { - return wrap(ConstantExpr::getNeg( - unwrap<Constant>(ConstantVal))); + return wrap(ConstantExpr::getNeg(unwrap<Constant>(ConstantVal))); } LLVMValueRef LLVMConstNSWNeg(LLVMValueRef ConstantVal) { - return wrap(ConstantExpr::getNSWNeg( - unwrap<Constant>(ConstantVal))); + return wrap(ConstantExpr::getNSWNeg(unwrap<Constant>(ConstantVal))); } LLVMValueRef LLVMConstNUWNeg(LLVMValueRef ConstantVal) { - return wrap(ConstantExpr::getNUWNeg( - unwrap<Constant>(ConstantVal))); + return wrap(ConstantExpr::getNUWNeg(unwrap<Constant>(ConstantVal))); } LLVMValueRef LLVMConstFNeg(LLVMValueRef ConstantVal) { - return wrap(ConstantExpr::getFNeg( - unwrap<Constant>(ConstantVal))); + return wrap(ConstantExpr::getFNeg(unwrap<Constant>(ConstantVal))); } LLVMValueRef LLVMConstNot(LLVMValueRef ConstantVal) { - return wrap(ConstantExpr::getNot( - unwrap<Constant>(ConstantVal))); + return wrap(ConstantExpr::getNot(unwrap<Constant>(ConstantVal))); } LLVMValueRef LLVMConstAdd(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { - return wrap(ConstantExpr::getAdd( - unwrap<Constant>(LHSConstant), + return wrap(ConstantExpr::getAdd(unwrap<Constant>(LHSConstant), unwrap<Constant>(RHSConstant))); } LLVMValueRef LLVMConstNSWAdd(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { - return wrap(ConstantExpr::getNSWAdd( - unwrap<Constant>(LHSConstant), + return wrap(ConstantExpr::getNSWAdd(unwrap<Constant>(LHSConstant), unwrap<Constant>(RHSConstant))); } LLVMValueRef LLVMConstNUWAdd(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { - return wrap(ConstantExpr::getNUWAdd( - unwrap<Constant>(LHSConstant), + return wrap(ConstantExpr::getNUWAdd(unwrap<Constant>(LHSConstant), unwrap<Constant>(RHSConstant))); } LLVMValueRef LLVMConstFAdd(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { - return wrap(ConstantExpr::getFAdd( - unwrap<Constant>(LHSConstant), + return wrap(ConstantExpr::getFAdd(unwrap<Constant>(LHSConstant), unwrap<Constant>(RHSConstant))); } LLVMValueRef LLVMConstSub(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { - return wrap(ConstantExpr::getSub( - unwrap<Constant>(LHSConstant), + return wrap(ConstantExpr::getSub(unwrap<Constant>(LHSConstant), unwrap<Constant>(RHSConstant))); } LLVMValueRef LLVMConstNSWSub(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { - return wrap(ConstantExpr::getNSWSub( - unwrap<Constant>(LHSConstant), + return wrap(ConstantExpr::getNSWSub(unwrap<Constant>(LHSConstant), unwrap<Constant>(RHSConstant))); } LLVMValueRef LLVMConstNUWSub(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { - return wrap(ConstantExpr::getNUWSub( - unwrap<Constant>(LHSConstant), + return wrap(ConstantExpr::getNUWSub(unwrap<Constant>(LHSConstant), unwrap<Constant>(RHSConstant))); } @@ -710,89 +716,75 @@ LLVMValueRef LLVMConstFSub(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { } LLVMValueRef LLVMConstMul(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { - return wrap(ConstantExpr::getMul( - unwrap<Constant>(LHSConstant), + return wrap(ConstantExpr::getMul(unwrap<Constant>(LHSConstant), unwrap<Constant>(RHSConstant))); } LLVMValueRef LLVMConstNSWMul(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { - return wrap(ConstantExpr::getNSWMul( - unwrap<Constant>(LHSConstant), + return wrap(ConstantExpr::getNSWMul(unwrap<Constant>(LHSConstant), unwrap<Constant>(RHSConstant))); } LLVMValueRef LLVMConstNUWMul(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { - return wrap(ConstantExpr::getNUWMul( - unwrap<Constant>(LHSConstant), + return wrap(ConstantExpr::getNUWMul(unwrap<Constant>(LHSConstant), unwrap<Constant>(RHSConstant))); } LLVMValueRef LLVMConstFMul(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { - return wrap(ConstantExpr::getFMul( - unwrap<Constant>(LHSConstant), + return wrap(ConstantExpr::getFMul(unwrap<Constant>(LHSConstant), unwrap<Constant>(RHSConstant))); } LLVMValueRef LLVMConstUDiv(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { - return wrap(ConstantExpr::getUDiv( - unwrap<Constant>(LHSConstant), + return wrap(ConstantExpr::getUDiv(unwrap<Constant>(LHSConstant), unwrap<Constant>(RHSConstant))); } LLVMValueRef LLVMConstSDiv(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { - return wrap(ConstantExpr::getSDiv( - unwrap<Constant>(LHSConstant), + return wrap(ConstantExpr::getSDiv(unwrap<Constant>(LHSConstant), unwrap<Constant>(RHSConstant))); } LLVMValueRef LLVMConstExactSDiv(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { - return wrap(ConstantExpr::getExactSDiv( - unwrap<Constant>(LHSConstant), + return wrap(ConstantExpr::getExactSDiv(unwrap<Constant>(LHSConstant), unwrap<Constant>(RHSConstant))); } LLVMValueRef LLVMConstFDiv(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { - return wrap(ConstantExpr::getFDiv( - unwrap<Constant>(LHSConstant), + return wrap(ConstantExpr::getFDiv(unwrap<Constant>(LHSConstant), unwrap<Constant>(RHSConstant))); } LLVMValueRef LLVMConstURem(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { - return wrap(ConstantExpr::getURem( - unwrap<Constant>(LHSConstant), + return wrap(ConstantExpr::getURem(unwrap<Constant>(LHSConstant), unwrap<Constant>(RHSConstant))); } LLVMValueRef LLVMConstSRem(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { - return wrap(ConstantExpr::getSRem( - unwrap<Constant>(LHSConstant), + return wrap(ConstantExpr::getSRem(unwrap<Constant>(LHSConstant), unwrap<Constant>(RHSConstant))); } LLVMValueRef LLVMConstFRem(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { - return wrap(ConstantExpr::getFRem( - unwrap<Constant>(LHSConstant), + return wrap(ConstantExpr::getFRem(unwrap<Constant>(LHSConstant), unwrap<Constant>(RHSConstant))); } LLVMValueRef LLVMConstAnd(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { - return wrap(ConstantExpr::getAnd( - unwrap<Constant>(LHSConstant), + return wrap(ConstantExpr::getAnd(unwrap<Constant>(LHSConstant), unwrap<Constant>(RHSConstant))); } LLVMValueRef LLVMConstOr(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { - return wrap(ConstantExpr::getOr( - unwrap<Constant>(LHSConstant), + return wrap(ConstantExpr::getOr(unwrap<Constant>(LHSConstant), unwrap<Constant>(RHSConstant))); } LLVMValueRef LLVMConstXor(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { - return wrap(ConstantExpr::getXor( - unwrap<Constant>(LHSConstant), + return wrap(ConstantExpr::getXor(unwrap<Constant>(LHSConstant), unwrap<Constant>(RHSConstant))); } @@ -811,27 +803,23 @@ LLVMValueRef LLVMConstFCmp(LLVMRealPredicate Predicate, } LLVMValueRef LLVMConstShl(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { - return wrap(ConstantExpr::getShl( - unwrap<Constant>(LHSConstant), - unwrap<Constant>(RHSConstant))); + return wrap(ConstantExpr::getShl(unwrap<Constant>(LHSConstant), + unwrap<Constant>(RHSConstant))); } LLVMValueRef LLVMConstLShr(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { - return wrap(ConstantExpr::getLShr( - unwrap<Constant>(LHSConstant), + return wrap(ConstantExpr::getLShr(unwrap<Constant>(LHSConstant), unwrap<Constant>(RHSConstant))); } LLVMValueRef LLVMConstAShr(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { - return wrap(ConstantExpr::getAShr( - unwrap<Constant>(LHSConstant), + return wrap(ConstantExpr::getAShr(unwrap<Constant>(LHSConstant), unwrap<Constant>(RHSConstant))); } LLVMValueRef LLVMConstGEP(LLVMValueRef ConstantVal, LLVMValueRef *ConstantIndices, unsigned NumIndices) { - return wrap(ConstantExpr::getGetElementPtr( - unwrap<Constant>(ConstantVal), + return wrap(ConstantExpr::getGetElementPtr(unwrap<Constant>(ConstantVal), unwrap<Constant>(ConstantIndices, NumIndices), NumIndices)); @@ -846,38 +834,32 @@ LLVMValueRef LLVMConstInBoundsGEP(LLVMValueRef ConstantVal, } LLVMValueRef LLVMConstTrunc(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { - return wrap(ConstantExpr::getTrunc( - unwrap<Constant>(ConstantVal), + return wrap(ConstantExpr::getTrunc(unwrap<Constant>(ConstantVal), unwrap(ToType))); } LLVMValueRef LLVMConstSExt(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { - return wrap(ConstantExpr::getSExt( - unwrap<Constant>(ConstantVal), + return wrap(ConstantExpr::getSExt(unwrap<Constant>(ConstantVal), unwrap(ToType))); } LLVMValueRef LLVMConstZExt(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { - return wrap(ConstantExpr::getZExt( - unwrap<Constant>(ConstantVal), + return wrap(ConstantExpr::getZExt(unwrap<Constant>(ConstantVal), unwrap(ToType))); } LLVMValueRef LLVMConstFPTrunc(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { - return wrap(ConstantExpr::getFPTrunc( - unwrap<Constant>(ConstantVal), + return wrap(ConstantExpr::getFPTrunc(unwrap<Constant>(ConstantVal), unwrap(ToType))); } LLVMValueRef LLVMConstFPExt(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { - return wrap(ConstantExpr::getFPExtend( - unwrap<Constant>(ConstantVal), + return wrap(ConstantExpr::getFPExtend(unwrap<Constant>(ConstantVal), unwrap(ToType))); } LLVMValueRef LLVMConstUIToFP(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { - return wrap(ConstantExpr::getUIToFP( - unwrap<Constant>(ConstantVal), + return wrap(ConstantExpr::getUIToFP(unwrap<Constant>(ConstantVal), unwrap(ToType))); } @@ -892,92 +874,78 @@ LLVMValueRef LLVMConstFPToUI(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { } LLVMValueRef LLVMConstFPToSI(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { - return wrap(ConstantExpr::getFPToSI( - unwrap<Constant>(ConstantVal), + return wrap(ConstantExpr::getFPToSI(unwrap<Constant>(ConstantVal), unwrap(ToType))); } LLVMValueRef LLVMConstPtrToInt(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { - return wrap(ConstantExpr::getPtrToInt( - unwrap<Constant>(ConstantVal), + return wrap(ConstantExpr::getPtrToInt(unwrap<Constant>(ConstantVal), unwrap(ToType))); } LLVMValueRef LLVMConstIntToPtr(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { - return wrap(ConstantExpr::getIntToPtr( - unwrap<Constant>(ConstantVal), + return wrap(ConstantExpr::getIntToPtr(unwrap<Constant>(ConstantVal), unwrap(ToType))); } LLVMValueRef LLVMConstBitCast(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { - return wrap(ConstantExpr::getBitCast( - unwrap<Constant>(ConstantVal), + return wrap(ConstantExpr::getBitCast(unwrap<Constant>(ConstantVal), unwrap(ToType))); } LLVMValueRef LLVMConstZExtOrBitCast(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { - return wrap(ConstantExpr::getZExtOrBitCast( - unwrap<Constant>(ConstantVal), + return wrap(ConstantExpr::getZExtOrBitCast(unwrap<Constant>(ConstantVal), unwrap(ToType))); } LLVMValueRef LLVMConstSExtOrBitCast(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { - return wrap(ConstantExpr::getSExtOrBitCast( - unwrap<Constant>(ConstantVal), + return wrap(ConstantExpr::getSExtOrBitCast(unwrap<Constant>(ConstantVal), unwrap(ToType))); } LLVMValueRef LLVMConstTruncOrBitCast(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { - return wrap(ConstantExpr::getTruncOrBitCast( - unwrap<Constant>(ConstantVal), + return wrap(ConstantExpr::getTruncOrBitCast(unwrap<Constant>(ConstantVal), unwrap(ToType))); } LLVMValueRef LLVMConstPointerCast(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { - return wrap(ConstantExpr::getPointerCast( - unwrap<Constant>(ConstantVal), + return wrap(ConstantExpr::getPointerCast(unwrap<Constant>(ConstantVal), unwrap(ToType))); } LLVMValueRef LLVMConstIntCast(LLVMValueRef ConstantVal, LLVMTypeRef ToType, LLVMBool isSigned) { - return wrap(ConstantExpr::getIntegerCast( - unwrap<Constant>(ConstantVal), - unwrap(ToType), - isSigned)); + return wrap(ConstantExpr::getIntegerCast(unwrap<Constant>(ConstantVal), + unwrap(ToType), isSigned)); } LLVMValueRef LLVMConstFPCast(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { - return wrap(ConstantExpr::getFPCast( - unwrap<Constant>(ConstantVal), + return wrap(ConstantExpr::getFPCast(unwrap<Constant>(ConstantVal), unwrap(ToType))); } LLVMValueRef LLVMConstSelect(LLVMValueRef ConstantCondition, LLVMValueRef ConstantIfTrue, LLVMValueRef ConstantIfFalse) { - return wrap(ConstantExpr::getSelect( - unwrap<Constant>(ConstantCondition), + return wrap(ConstantExpr::getSelect(unwrap<Constant>(ConstantCondition), unwrap<Constant>(ConstantIfTrue), unwrap<Constant>(ConstantIfFalse))); } LLVMValueRef LLVMConstExtractElement(LLVMValueRef VectorConstant, LLVMValueRef IndexConstant) { - return wrap(ConstantExpr::getExtractElement( - unwrap<Constant>(VectorConstant), + return wrap(ConstantExpr::getExtractElement(unwrap<Constant>(VectorConstant), unwrap<Constant>(IndexConstant))); } LLVMValueRef LLVMConstInsertElement(LLVMValueRef VectorConstant, LLVMValueRef ElementValueConstant, LLVMValueRef IndexConstant) { - return wrap(ConstantExpr::getInsertElement( - unwrap<Constant>(VectorConstant), + return wrap(ConstantExpr::getInsertElement(unwrap<Constant>(VectorConstant), unwrap<Constant>(ElementValueConstant), unwrap<Constant>(IndexConstant))); } @@ -985,24 +953,21 @@ LLVMValueRef LLVMConstInsertElement(LLVMValueRef VectorConstant, LLVMValueRef LLVMConstShuffleVector(LLVMValueRef VectorAConstant, LLVMValueRef VectorBConstant, LLVMValueRef MaskConstant) { - return wrap(ConstantExpr::getShuffleVector( - unwrap<Constant>(VectorAConstant), + return wrap(ConstantExpr::getShuffleVector(unwrap<Constant>(VectorAConstant), unwrap<Constant>(VectorBConstant), unwrap<Constant>(MaskConstant))); } LLVMValueRef LLVMConstExtractValue(LLVMValueRef AggConstant, unsigned *IdxList, unsigned NumIdx) { - return wrap(ConstantExpr::getExtractValue( - unwrap<Constant>(AggConstant), + return wrap(ConstantExpr::getExtractValue(unwrap<Constant>(AggConstant), IdxList, NumIdx)); } LLVMValueRef LLVMConstInsertValue(LLVMValueRef AggConstant, LLVMValueRef ElementValueConstant, unsigned *IdxList, unsigned NumIdx) { - return wrap(ConstantExpr::getInsertValue( - unwrap<Constant>(AggConstant), + return wrap(ConstantExpr::getInsertValue(unwrap<Constant>(AggConstant), unwrap<Constant>(ElementValueConstant), IdxList, NumIdx)); } @@ -2206,25 +2171,27 @@ LLVMBool LLVMCreateMemoryBufferWithContentsOfFile( LLVMMemoryBufferRef *OutMemBuf, char **OutMessage) { - std::string Error; - if (MemoryBuffer *MB = MemoryBuffer::getFile(Path, &Error)) { - *OutMemBuf = wrap(MB); + OwningPtr<MemoryBuffer> MB; + error_code ec; + if (!(ec = MemoryBuffer::getFile(Path, MB))) { + *OutMemBuf = wrap(MB.take()); return 0; } - - *OutMessage = strdup(Error.c_str()); + + *OutMessage = strdup(ec.message().c_str()); return 1; } LLVMBool LLVMCreateMemoryBufferWithSTDIN(LLVMMemoryBufferRef *OutMemBuf, char **OutMessage) { - std::string Error; - if (MemoryBuffer *MB = MemoryBuffer::getSTDIN(&Error)) { - *OutMemBuf = wrap(MB); + OwningPtr<MemoryBuffer> MB; + error_code ec; + if (!(ec = MemoryBuffer::getSTDIN(MB))) { + *OutMemBuf = wrap(MB.take()); return 0; } - *OutMessage = strdup(Error.c_str()); + *OutMessage = strdup(ec.message().c_str()); return 1; } diff --git a/lib/VMCore/Dominators.cpp b/lib/VMCore/Dominators.cpp index b758168..c374b06 100644 --- a/lib/VMCore/Dominators.cpp +++ b/lib/VMCore/Dominators.cpp @@ -19,10 +19,10 @@ #include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" #include "llvm/ADT/DepthFirstIterator.h" -#include "llvm/ADT/SetOperations.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Analysis/DominatorInternals.h" +#include "llvm/Assembly/Writer.h" #include "llvm/Instructions.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/CommandLine.h" @@ -44,7 +44,7 @@ VerifyDomInfoX("verify-dom-info", cl::location(VerifyDomInfo), //===----------------------------------------------------------------------===// // // Provide public access to DominatorTree information. Implementation details -// can be found in DominatorCalculation.h. +// can be found in DominatorInternals.h. // //===----------------------------------------------------------------------===// @@ -67,7 +67,14 @@ void DominatorTree::verifyAnalysis() const { DominatorTree OtherDT; OtherDT.getBase().recalculate(F); - assert(!compare(OtherDT) && "Invalid DominatorTree info!"); + if (compare(OtherDT)) { + errs() << "DominatorTree is not up to date! Computed:\n"; + print(errs()); + + errs() << "\nActual:\n"; + OtherDT.print(errs()); + abort(); + } } void DominatorTree::print(raw_ostream &OS, const Module *) const { @@ -98,266 +105,3 @@ bool DominatorTree::dominates(const Instruction *A, const Instruction *B) const{ return &*I == A; } - - - -//===----------------------------------------------------------------------===// -// DominanceFrontier Implementation -//===----------------------------------------------------------------------===// - -char DominanceFrontier::ID = 0; -INITIALIZE_PASS_BEGIN(DominanceFrontier, "domfrontier", - "Dominance Frontier Construction", true, true) -INITIALIZE_PASS_DEPENDENCY(DominatorTree) -INITIALIZE_PASS_END(DominanceFrontier, "domfrontier", - "Dominance Frontier Construction", true, true) - -void DominanceFrontier::verifyAnalysis() const { - if (!VerifyDomInfo) return; - - DominatorTree &DT = getAnalysis<DominatorTree>(); - - DominanceFrontier OtherDF; - const std::vector<BasicBlock*> &DTRoots = DT.getRoots(); - OtherDF.calculate(DT, DT.getNode(DTRoots[0])); - assert(!compare(OtherDF) && "Invalid DominanceFrontier info!"); -} - -// NewBB is split and now it has one successor. Update dominance frontier to -// reflect this change. -void DominanceFrontier::splitBlock(BasicBlock *NewBB) { - assert(NewBB->getTerminator()->getNumSuccessors() == 1 && - "NewBB should have a single successor!"); - BasicBlock *NewBBSucc = NewBB->getTerminator()->getSuccessor(0); - - // NewBBSucc inherits original NewBB frontier. - DominanceFrontier::iterator NewBBI = find(NewBB); - if (NewBBI != end()) - addBasicBlock(NewBBSucc, NewBBI->second); - - // If NewBB dominates NewBBSucc, then DF(NewBB) is now going to be the - // DF(NewBBSucc) without the stuff that the new block does not dominate - // a predecessor of. - DominatorTree &DT = getAnalysis<DominatorTree>(); - DomTreeNode *NewBBNode = DT.getNode(NewBB); - DomTreeNode *NewBBSuccNode = DT.getNode(NewBBSucc); - if (DT.dominates(NewBBNode, NewBBSuccNode)) { - DominanceFrontier::iterator DFI = find(NewBBSucc); - if (DFI != end()) { - DominanceFrontier::DomSetType Set = DFI->second; - // Filter out stuff in Set that we do not dominate a predecessor of. - for (DominanceFrontier::DomSetType::iterator SetI = Set.begin(), - E = Set.end(); SetI != E;) { - bool DominatesPred = false; - for (pred_iterator PI = pred_begin(*SetI), E = pred_end(*SetI); - PI != E; ++PI) - if (DT.dominates(NewBBNode, DT.getNode(*PI))) { - DominatesPred = true; - break; - } - if (!DominatesPred) - Set.erase(SetI++); - else - ++SetI; - } - - if (NewBBI != end()) { - for (DominanceFrontier::DomSetType::iterator SetI = Set.begin(), - E = Set.end(); SetI != E; ++SetI) { - BasicBlock *SB = *SetI; - addToFrontier(NewBBI, SB); - } - } else - addBasicBlock(NewBB, Set); - } - - } else { - // DF(NewBB) is {NewBBSucc} because NewBB does not strictly dominate - // NewBBSucc, but it does dominate itself (and there is an edge (NewBB -> - // NewBBSucc)). NewBBSucc is the single successor of NewBB. - DominanceFrontier::DomSetType NewDFSet; - NewDFSet.insert(NewBBSucc); - addBasicBlock(NewBB, NewDFSet); - } - - // Now update dominance frontiers which either used to contain NewBBSucc - // or which now need to include NewBB. - - // Collect the set of blocks which dominate a predecessor of NewBB or - // NewSuccBB and which don't dominate both. This is an initial - // approximation of the blocks whose dominance frontiers will need updates. - SmallVector<DomTreeNode *, 16> AllPredDoms; - - // Compute the block which dominates both NewBBSucc and NewBB. This is - // the immediate dominator of NewBBSucc unless NewBB dominates NewBBSucc. - // The code below which climbs dominator trees will stop at this point, - // because from this point up, dominance frontiers are unaffected. - DomTreeNode *DominatesBoth = 0; - if (NewBBSuccNode) { - DominatesBoth = NewBBSuccNode->getIDom(); - if (DominatesBoth == NewBBNode) - DominatesBoth = NewBBNode->getIDom(); - } - - // Collect the set of all blocks which dominate a predecessor of NewBB. - SmallPtrSet<DomTreeNode *, 8> NewBBPredDoms; - for (pred_iterator PI = pred_begin(NewBB), E = pred_end(NewBB); PI != E; ++PI) - for (DomTreeNode *DTN = DT.getNode(*PI); DTN; DTN = DTN->getIDom()) { - if (DTN == DominatesBoth) - break; - if (!NewBBPredDoms.insert(DTN)) - break; - AllPredDoms.push_back(DTN); - } - - // Collect the set of all blocks which dominate a predecessor of NewSuccBB. - SmallPtrSet<DomTreeNode *, 8> NewBBSuccPredDoms; - for (pred_iterator PI = pred_begin(NewBBSucc), - E = pred_end(NewBBSucc); PI != E; ++PI) - for (DomTreeNode *DTN = DT.getNode(*PI); DTN; DTN = DTN->getIDom()) { - if (DTN == DominatesBoth) - break; - if (!NewBBSuccPredDoms.insert(DTN)) - break; - if (!NewBBPredDoms.count(DTN)) - AllPredDoms.push_back(DTN); - } - - // Visit all relevant dominance frontiers and make any needed updates. - for (SmallVectorImpl<DomTreeNode *>::const_iterator I = AllPredDoms.begin(), - E = AllPredDoms.end(); I != E; ++I) { - DomTreeNode *DTN = *I; - iterator DFI = find((*I)->getBlock()); - - // Only consider nodes that have NewBBSucc in their dominator frontier. - if (DFI == end() || !DFI->second.count(NewBBSucc)) continue; - - // If the block dominates a predecessor of NewBB but does not properly - // dominate NewBB itself, add NewBB to its dominance frontier. - if (NewBBPredDoms.count(DTN) && - !DT.properlyDominates(DTN, NewBBNode)) - addToFrontier(DFI, NewBB); - - // If the block does not dominate a predecessor of NewBBSucc or - // properly dominates NewBBSucc itself, remove NewBBSucc from its - // dominance frontier. - if (!NewBBSuccPredDoms.count(DTN) || - DT.properlyDominates(DTN, NewBBSuccNode)) - removeFromFrontier(DFI, NewBBSucc); - } -} - -namespace { - class DFCalculateWorkObject { - public: - DFCalculateWorkObject(BasicBlock *B, BasicBlock *P, - const DomTreeNode *N, - const DomTreeNode *PN) - : currentBB(B), parentBB(P), Node(N), parentNode(PN) {} - BasicBlock *currentBB; - BasicBlock *parentBB; - const DomTreeNode *Node; - const DomTreeNode *parentNode; - }; -} - -const DominanceFrontier::DomSetType & -DominanceFrontier::calculate(const DominatorTree &DT, - const DomTreeNode *Node) { - BasicBlock *BB = Node->getBlock(); - DomSetType *Result = NULL; - - std::vector<DFCalculateWorkObject> workList; - SmallPtrSet<BasicBlock *, 32> visited; - - workList.push_back(DFCalculateWorkObject(BB, NULL, Node, NULL)); - do { - DFCalculateWorkObject *currentW = &workList.back(); - assert (currentW && "Missing work object."); - - BasicBlock *currentBB = currentW->currentBB; - BasicBlock *parentBB = currentW->parentBB; - const DomTreeNode *currentNode = currentW->Node; - const DomTreeNode *parentNode = currentW->parentNode; - assert (currentBB && "Invalid work object. Missing current Basic Block"); - assert (currentNode && "Invalid work object. Missing current Node"); - DomSetType &S = Frontiers[currentBB]; - - // Visit each block only once. - if (visited.count(currentBB) == 0) { - visited.insert(currentBB); - - // Loop over CFG successors to calculate DFlocal[currentNode] - for (succ_iterator SI = succ_begin(currentBB), SE = succ_end(currentBB); - SI != SE; ++SI) { - // Does Node immediately dominate this successor? - if (DT[*SI]->getIDom() != currentNode) - S.insert(*SI); - } - } - - // At this point, S is DFlocal. Now we union in DFup's of our children... - // Loop through and visit the nodes that Node immediately dominates (Node's - // children in the IDomTree) - bool visitChild = false; - for (DomTreeNode::const_iterator NI = currentNode->begin(), - NE = currentNode->end(); NI != NE; ++NI) { - DomTreeNode *IDominee = *NI; - BasicBlock *childBB = IDominee->getBlock(); - if (visited.count(childBB) == 0) { - workList.push_back(DFCalculateWorkObject(childBB, currentBB, - IDominee, currentNode)); - visitChild = true; - } - } - - // If all children are visited or there is any child then pop this block - // from the workList. - if (!visitChild) { - - if (!parentBB) { - Result = &S; - break; - } - - DomSetType::const_iterator CDFI = S.begin(), CDFE = S.end(); - DomSetType &parentSet = Frontiers[parentBB]; - for (; CDFI != CDFE; ++CDFI) { - if (!DT.properlyDominates(parentNode, DT[*CDFI])) - parentSet.insert(*CDFI); - } - workList.pop_back(); - } - - } while (!workList.empty()); - - return *Result; -} - -void DominanceFrontierBase::print(raw_ostream &OS, const Module* ) const { - for (const_iterator I = begin(), E = end(); I != E; ++I) { - OS << " DomFrontier for BB "; - if (I->first) - WriteAsOperand(OS, I->first, false); - else - OS << " <<exit node>>"; - OS << " is:\t"; - - const std::set<BasicBlock*> &BBs = I->second; - - for (std::set<BasicBlock*>::const_iterator I = BBs.begin(), E = BBs.end(); - I != E; ++I) { - OS << ' '; - if (*I) - WriteAsOperand(OS, *I, false); - else - OS << "<<exit node>>"; - } - OS << "\n"; - } -} - -void DominanceFrontierBase::dump() const { - print(dbgs()); -} - diff --git a/lib/VMCore/Function.cpp b/lib/VMCore/Function.cpp index 8f94efc..00d1d78 100644 --- a/lib/VMCore/Function.cpp +++ b/lib/VMCore/Function.cpp @@ -20,8 +20,8 @@ #include "llvm/Support/LeakDetector.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/StringPool.h" -#include "llvm/System/RWMutex.h" -#include "llvm/System/Threading.h" +#include "llvm/Support/RWMutex.h" +#include "llvm/Support/Threading.h" #include "SymbolTableListTraitsImpl.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/StringExtras.h" @@ -227,19 +227,10 @@ void Function::dropAllReferences() { for (iterator I = begin(), E = end(); I != E; ++I) I->dropAllReferences(); - // Delete all basic blocks. - while (!BasicBlocks.empty()) { - // If there is still a reference to the block, it must be a 'blockaddress' - // constant pointing to it. Just replace the BlockAddress with undef. - BasicBlock *BB = BasicBlocks.begin(); - if (!BB->use_empty()) { - BlockAddress *BA = cast<BlockAddress>(BB->use_back()); - BA->replaceAllUsesWith(UndefValue::get(BA->getType())); - BA->destroyConstant(); - } - - BB->eraseFromParent(); - } + // Delete all basic blocks. They are now unused, except possibly by + // blockaddresses, but BasicBlock's destructor takes care of those. + while (!BasicBlocks.empty()) + BasicBlocks.begin()->eraseFromParent(); } void Function::addAttribute(unsigned i, Attributes attr) { diff --git a/lib/VMCore/Globals.cpp b/lib/VMCore/Globals.cpp index 96716ee..60000ad 100644 --- a/lib/VMCore/Globals.cpp +++ b/lib/VMCore/Globals.cpp @@ -26,23 +26,6 @@ using namespace llvm; // GlobalValue Class //===----------------------------------------------------------------------===// -/// removeDeadUsersOfConstant - If the specified constantexpr is dead, remove -/// it. This involves recursively eliminating any dead users of the -/// constantexpr. -static bool removeDeadUsersOfConstant(const Constant *C) { - if (isa<GlobalValue>(C)) return false; // Cannot remove this - - while (!C->use_empty()) { - const Constant *User = dyn_cast<Constant>(C->use_back()); - if (!User) return false; // Non-constant usage; - if (!removeDeadUsersOfConstant(User)) - return false; // Constant wasn't dead - } - - const_cast<Constant*>(C)->destroyConstant(); - return true; -} - bool GlobalValue::isMaterializable() const { return getParent() && getParent()->isMaterializable(this); } @@ -56,38 +39,6 @@ void GlobalValue::Dematerialize() { getParent()->Dematerialize(this); } -/// removeDeadConstantUsers - If there are any dead constant users dangling -/// off of this global value, remove them. This method is useful for clients -/// that want to check to see if a global is unused, but don't want to deal -/// with potentially dead constants hanging off of the globals. -void GlobalValue::removeDeadConstantUsers() const { - Value::const_use_iterator I = use_begin(), E = use_end(); - Value::const_use_iterator LastNonDeadUser = E; - while (I != E) { - if (const Constant *User = dyn_cast<Constant>(*I)) { - if (!removeDeadUsersOfConstant(User)) { - // If the constant wasn't dead, remember that this was the last live use - // and move on to the next constant. - LastNonDeadUser = I; - ++I; - } else { - // If the constant was dead, then the iterator is invalidated. - if (LastNonDeadUser == E) { - I = use_begin(); - if (I == E) break; - } else { - I = LastNonDeadUser; - ++I; - } - } - } else { - LastNonDeadUser = I; - ++I; - } - } -} - - /// Override destroyConstant to make sure it doesn't get called on /// GlobalValue's because they shouldn't be treated like other constants. void GlobalValue::destroyConstant() { diff --git a/lib/VMCore/IRBuilder.cpp b/lib/VMCore/IRBuilder.cpp index c1b783c..595dea4 100644 --- a/lib/VMCore/IRBuilder.cpp +++ b/lib/VMCore/IRBuilder.cpp @@ -15,6 +15,7 @@ #include "llvm/Support/IRBuilder.h" #include "llvm/GlobalVariable.h" #include "llvm/Function.h" +#include "llvm/Intrinsics.h" #include "llvm/LLVMContext.h" using namespace llvm; @@ -36,3 +37,83 @@ const Type *IRBuilderBase::getCurrentFunctionReturnType() const { assert(BB && BB->getParent() && "No current function!"); return BB->getParent()->getReturnType(); } + +Value *IRBuilderBase::getCastedInt8PtrValue(Value *Ptr) { + const PointerType *PT = cast<PointerType>(Ptr->getType()); + if (PT->getElementType()->isIntegerTy(8)) + return Ptr; + + // Otherwise, we need to insert a bitcast. + PT = getInt8PtrTy(PT->getAddressSpace()); + BitCastInst *BCI = new BitCastInst(Ptr, PT, ""); + BB->getInstList().insert(InsertPt, BCI); + SetInstDebugLocation(BCI); + return BCI; +} + +static CallInst *createCallHelper(Value *Callee, Value *const* Ops, + unsigned NumOps, IRBuilderBase *Builder) { + CallInst *CI = CallInst::Create(Callee, Ops, Ops + NumOps, ""); + Builder->GetInsertBlock()->getInstList().insert(Builder->GetInsertPoint(),CI); + Builder->SetInstDebugLocation(CI); + return CI; +} + + +CallInst *IRBuilderBase:: +CreateMemSet(Value *Ptr, Value *Val, Value *Size, unsigned Align, + bool isVolatile, MDNode *TBAATag) { + Ptr = getCastedInt8PtrValue(Ptr); + Value *Ops[] = { Ptr, Val, Size, getInt32(Align), getInt1(isVolatile) }; + const Type *Tys[] = { Ptr->getType(), Size->getType() }; + Module *M = BB->getParent()->getParent(); + Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memset, Tys, 2); + + CallInst *CI = createCallHelper(TheFn, Ops, 5, this); + + // Set the TBAA info if present. + if (TBAATag) + CI->setMetadata(LLVMContext::MD_tbaa, TBAATag); + + return CI; +} + +CallInst *IRBuilderBase:: +CreateMemCpy(Value *Dst, Value *Src, Value *Size, unsigned Align, + bool isVolatile, MDNode *TBAATag) { + Dst = getCastedInt8PtrValue(Dst); + Src = getCastedInt8PtrValue(Src); + + Value *Ops[] = { Dst, Src, Size, getInt32(Align), getInt1(isVolatile) }; + const Type *Tys[] = { Dst->getType(), Src->getType(), Size->getType() }; + Module *M = BB->getParent()->getParent(); + Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memcpy, Tys, 3); + + CallInst *CI = createCallHelper(TheFn, Ops, 5, this); + + // Set the TBAA info if present. + if (TBAATag) + CI->setMetadata(LLVMContext::MD_tbaa, TBAATag); + + return CI; +} + +CallInst *IRBuilderBase:: +CreateMemMove(Value *Dst, Value *Src, Value *Size, unsigned Align, + bool isVolatile, MDNode *TBAATag) { + Dst = getCastedInt8PtrValue(Dst); + Src = getCastedInt8PtrValue(Src); + + Value *Ops[] = { Dst, Src, Size, getInt32(Align), getInt1(isVolatile) }; + const Type *Tys[] = { Dst->getType(), Src->getType(), Size->getType() }; + Module *M = BB->getParent()->getParent(); + Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memmove, Tys, 3); + + CallInst *CI = createCallHelper(TheFn, Ops, 5, this); + + // Set the TBAA info if present. + if (TBAATag) + CI->setMetadata(LLVMContext::MD_tbaa, TBAATag); + + return CI; +} diff --git a/lib/VMCore/Instruction.cpp b/lib/VMCore/Instruction.cpp index fdddba9..2c8b8b2 100644 --- a/lib/VMCore/Instruction.cpp +++ b/lib/VMCore/Instruction.cpp @@ -200,12 +200,10 @@ bool Instruction::isIdenticalToWhenDefined(const Instruction *I) const { if (const CallInst *CI = dyn_cast<CallInst>(this)) return CI->isTailCall() == cast<CallInst>(I)->isTailCall() && CI->getCallingConv() == cast<CallInst>(I)->getCallingConv() && - CI->getAttributes().getRawPointer() == - cast<CallInst>(I)->getAttributes().getRawPointer(); + CI->getAttributes() == cast<CallInst>(I)->getAttributes(); if (const InvokeInst *CI = dyn_cast<InvokeInst>(this)) return CI->getCallingConv() == cast<InvokeInst>(I)->getCallingConv() && - CI->getAttributes().getRawPointer() == - cast<InvokeInst>(I)->getAttributes().getRawPointer(); + CI->getAttributes() == cast<InvokeInst>(I)->getAttributes(); if (const InsertValueInst *IVI = dyn_cast<InsertValueInst>(this)) { if (IVI->getNumIndices() != cast<InsertValueInst>(I)->getNumIndices()) return false; @@ -253,12 +251,11 @@ bool Instruction::isSameOperationAs(const Instruction *I) const { if (const CallInst *CI = dyn_cast<CallInst>(this)) return CI->isTailCall() == cast<CallInst>(I)->isTailCall() && CI->getCallingConv() == cast<CallInst>(I)->getCallingConv() && - CI->getAttributes().getRawPointer() == - cast<CallInst>(I)->getAttributes().getRawPointer(); + CI->getAttributes() == cast<CallInst>(I)->getAttributes(); if (const InvokeInst *CI = dyn_cast<InvokeInst>(this)) return CI->getCallingConv() == cast<InvokeInst>(I)->getCallingConv() && - CI->getAttributes().getRawPointer() == - cast<InvokeInst>(I)->getAttributes().getRawPointer(); + CI->getAttributes() == + cast<InvokeInst>(I)->getAttributes(); if (const InsertValueInst *IVI = dyn_cast<InsertValueInst>(this)) { if (IVI->getNumIndices() != cast<InsertValueInst>(I)->getNumIndices()) return false; @@ -348,7 +345,7 @@ bool Instruction::mayThrow() const { /// /// In LLVM, the Add, Mul, And, Or, and Xor operators are associative. /// -bool Instruction::isAssociative(unsigned Opcode, const Type *Ty) { +bool Instruction::isAssociative(unsigned Opcode) { return Opcode == And || Opcode == Or || Opcode == Xor || Opcode == Add || Opcode == Mul; } diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp index 7306d86..d129028 100644 --- a/lib/VMCore/Instructions.cpp +++ b/lib/VMCore/Instructions.cpp @@ -19,7 +19,6 @@ #include "llvm/Instructions.h" #include "llvm/Module.h" #include "llvm/Operator.h" -#include "llvm/Analysis/Dominators.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/CallSite.h" #include "llvm/Support/ConstantRange.h" @@ -97,8 +96,7 @@ PHINode::PHINode(const PHINode &PN) } PHINode::~PHINode() { - if (OperandList) - dropHungoffUses(OperandList); + dropHungoffUses(); } // removeIncomingValue - Remove an incoming value. This is useful if a @@ -159,66 +157,18 @@ void PHINode::resizeOperands(unsigned NumOps) { Use *NewOps = allocHungoffUses(NumOps); std::copy(OldOps, OldOps + e, NewOps); OperandList = NewOps; - if (OldOps) Use::zap(OldOps, OldOps + e, true); + Use::zap(OldOps, OldOps + e, true); } /// hasConstantValue - If the specified PHI node always merges together the same /// value, return the value, otherwise return null. -/// -/// If the PHI has undef operands, but all the rest of the operands are -/// some unique value, return that value if it can be proved that the -/// value dominates the PHI. If DT is null, use a conservative check, -/// otherwise use DT to test for dominance. -/// -Value *PHINode::hasConstantValue(const DominatorTree *DT) const { - // If the PHI node only has one incoming value, eliminate the PHI node. - if (getNumIncomingValues() == 1) { - if (getIncomingValue(0) != this) // not X = phi X - return getIncomingValue(0); - return UndefValue::get(getType()); // Self cycle is dead. - } - - // Otherwise if all of the incoming values are the same for the PHI, replace - // the PHI node with the incoming value. - // - Value *InVal = 0; - bool HasUndefInput = false; - for (unsigned i = 0, e = getNumIncomingValues(); i != e; ++i) - if (isa<UndefValue>(getIncomingValue(i))) { - HasUndefInput = true; - } else if (getIncomingValue(i) != this) { // Not the PHI node itself... - if (InVal && getIncomingValue(i) != InVal) - return 0; // Not the same, bail out. - InVal = getIncomingValue(i); - } - - // The only case that could cause InVal to be null is if we have a PHI node - // that only has entries for itself. In this case, there is no entry into the - // loop, so kill the PHI. - // - if (InVal == 0) InVal = UndefValue::get(getType()); - - // If we have a PHI node like phi(X, undef, X), where X is defined by some - // instruction, we cannot always return X as the result of the PHI node. Only - // do this if X is not an instruction (thus it must dominate the PHI block), - // or if the client is prepared to deal with this possibility. - if (!HasUndefInput || !isa<Instruction>(InVal)) - return InVal; - - Instruction *IV = cast<Instruction>(InVal); - if (DT) { - // We have a DominatorTree. Do a precise test. - if (!DT->dominates(IV, this)) - return 0; - } else { - // If it is in the entry block, it obviously dominates everything. - if (IV->getParent() != &IV->getParent()->getParent()->getEntryBlock() || - isa<InvokeInst>(IV)) - return 0; // Cannot guarantee that InVal dominates this PHINode. - } - - // All of the incoming values are the same, return the value now. - return InVal; +Value *PHINode::hasConstantValue() const { + // Exploit the fact that phi nodes always have at least one entry. + Value *ConstantValue = getIncomingValue(0); + for (unsigned i = 1, e = getNumIncomingValues(); i != e; ++i) + if (getIncomingValue(i) != ConstantValue) + return 0; // Incoming values not all the same. + return ConstantValue; } @@ -235,7 +185,7 @@ void CallInst::init(Value *Func, Value* const *Params, unsigned NumParams) { const FunctionType *FTy = cast<FunctionType>(cast<PointerType>(Func->getType())->getElementType()); - FTy = FTy; // silence warning. + (void)FTy; // silence warning. assert((NumParams == FTy->getNumParams() || (FTy->isVarArg() && NumParams > FTy->getNumParams())) && @@ -256,7 +206,7 @@ void CallInst::init(Value *Func, Value *Actual1, Value *Actual2) { const FunctionType *FTy = cast<FunctionType>(cast<PointerType>(Func->getType())->getElementType()); - FTy = FTy; // silence warning. + (void)FTy; // silence warning. assert((FTy->getNumParams() == 2 || (FTy->isVarArg() && FTy->getNumParams() < 2)) && @@ -276,7 +226,7 @@ void CallInst::init(Value *Func, Value *Actual) { const FunctionType *FTy = cast<FunctionType>(cast<PointerType>(Func->getType())->getElementType()); - FTy = FTy; // silence warning. + (void)FTy; // silence warning. assert((FTy->getNumParams() == 1 || (FTy->isVarArg() && FTy->getNumParams() == 0)) && @@ -292,7 +242,7 @@ void CallInst::init(Value *Func) { const FunctionType *FTy = cast<FunctionType>(cast<PointerType>(Func->getType())->getElementType()); - FTy = FTy; // silence warning. + (void)FTy; // silence warning. assert(FTy->getNumParams() == 0 && "Calling a function with bad signature"); } @@ -549,7 +499,7 @@ void InvokeInst::init(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException, Op<-1>() = IfException; const FunctionType *FTy = cast<FunctionType>(cast<PointerType>(Fn->getType())->getElementType()); - FTy = FTy; // silence warning. + (void)FTy; // silence warning. assert(((NumArgs == FTy->getNumParams()) || (FTy->isVarArg() && NumArgs > FTy->getNumParams())) && @@ -779,31 +729,6 @@ BranchInst::BranchInst(const BranchInst &BI) : SubclassOptionalData = BI.SubclassOptionalData; } - -Use* Use::getPrefix() { - PointerIntPair<Use**, 2, PrevPtrTag> &PotentialPrefix(this[-1].Prev); - if (PotentialPrefix.getOpaqueValue()) - return 0; - - return reinterpret_cast<Use*>((char*)&PotentialPrefix + 1); -} - -BranchInst::~BranchInst() { - if (NumOperands == 1) { - if (Use *Prefix = OperandList->getPrefix()) { - Op<-1>() = 0; - // - // mark OperandList to have a special value for scrutiny - // by baseclass destructors and operator delete - OperandList = Prefix; - } else { - NumOperands = 3; - OperandList = op_begin(); - } - } -} - - BasicBlock *BranchInst::getSuccessorV(unsigned idx) const { return getSuccessor(idx); } @@ -1248,6 +1173,12 @@ const Type* GetElementPtrInst::getIndexedType(const Type *Ptr, } const Type* GetElementPtrInst::getIndexedType(const Type *Ptr, + Constant* const *Idxs, + unsigned NumIdx) { + return getIndexedTypeInternal(Ptr, Idxs, NumIdx); +} + +const Type* GetElementPtrInst::getIndexedType(const Type *Ptr, uint64_t const *Idxs, unsigned NumIdx) { return getIndexedTypeInternal(Ptr, Idxs, NumIdx); @@ -1473,6 +1404,8 @@ int ShuffleVectorInst::getMaskValue(unsigned i) const { void InsertValueInst::init(Value *Agg, Value *Val, const unsigned *Idx, unsigned NumIdx, const Twine &Name) { assert(NumOperands == 2 && "NumOperands not initialized?"); + assert(ExtractValueInst::getIndexedType(Agg->getType(), Idx, Idx + NumIdx) == + Val->getType() && "Inserted value must match indexed type!"); Op<0>() = Agg; Op<1>() = Val; @@ -1483,6 +1416,8 @@ void InsertValueInst::init(Value *Agg, Value *Val, const unsigned *Idx, void InsertValueInst::init(Value *Agg, Value *Val, unsigned Idx, const Twine &Name) { assert(NumOperands == 2 && "NumOperands not initialized?"); + assert(ExtractValueInst::getIndexedType(Agg->getType(), Idx) == Val->getType() + && "Inserted value must match indexed type!"); Op<0>() = Agg; Op<1>() = Val; @@ -1555,13 +1490,26 @@ ExtractValueInst::ExtractValueInst(const ExtractValueInst &EVI) const Type* ExtractValueInst::getIndexedType(const Type *Agg, const unsigned *Idxs, unsigned NumIdx) { - unsigned CurIdx = 0; - for (; CurIdx != NumIdx; ++CurIdx) { - const CompositeType *CT = dyn_cast<CompositeType>(Agg); - if (!CT || CT->isPointerTy() || CT->isVectorTy()) return 0; + for (unsigned CurIdx = 0; CurIdx != NumIdx; ++CurIdx) { unsigned Index = Idxs[CurIdx]; - if (!CT->indexValid(Index)) return 0; - Agg = CT->getTypeAtIndex(Index); + // We can't use CompositeType::indexValid(Index) here. + // indexValid() always returns true for arrays because getelementptr allows + // out-of-bounds indices. Since we don't allow those for extractvalue and + // insertvalue we need to check array indexing manually. + // Since the only other types we can index into are struct types it's just + // as easy to check those manually as well. + if (const ArrayType *AT = dyn_cast<ArrayType>(Agg)) { + if (Index >= AT->getNumElements()) + return 0; + } else if (const StructType *ST = dyn_cast<StructType>(Agg)) { + if (Index >= ST->getNumElements()) + return 0; + } else { + // Not a valid type to index into. + return 0; + } + + Agg = cast<CompositeType>(Agg)->getTypeAtIndex(Index); // If the new type forwards to another type, then it is in the middle // of being refined to another type (and hence, may have dropped all @@ -1570,7 +1518,7 @@ const Type* ExtractValueInst::getIndexedType(const Type *Agg, if (const Type *Ty = Agg->getForwardedType()) Agg = Ty; } - return CurIdx == NumIdx ? Agg : 0; + return Agg; } const Type* ExtractValueInst::getIndexedType(const Type *Agg, @@ -1611,7 +1559,7 @@ BinaryOperator::BinaryOperator(BinaryOps iType, Value *S1, Value *S2, void BinaryOperator::init(BinaryOps iType) { Value *LHS = getOperand(0), *RHS = getOperand(1); - LHS = LHS; RHS = RHS; // Silence warnings. + (void)LHS; (void)RHS; // Silence warnings. assert(LHS->getType() == RHS->getType() && "Binary operator operand types must match!"); #ifndef NDEBUG @@ -1874,7 +1822,7 @@ void BinaryOperator::setHasNoSignedWrap(bool b) { } void BinaryOperator::setIsExact(bool b) { - cast<SDivOperator>(this)->setIsExact(b); + cast<PossiblyExactOperator>(this)->setIsExact(b); } bool BinaryOperator::hasNoUnsignedWrap() const { @@ -1886,7 +1834,7 @@ bool BinaryOperator::hasNoSignedWrap() const { } bool BinaryOperator::isExact() const { - return cast<SDivOperator>(this)->isExact(); + return cast<PossiblyExactOperator>(this)->isExact(); } //===----------------------------------------------------------------------===// @@ -2768,14 +2716,14 @@ void CmpInst::swapOperands() { cast<FCmpInst>(this)->swapOperands(); } -bool CmpInst::isCommutative() { - if (ICmpInst *IC = dyn_cast<ICmpInst>(this)) +bool CmpInst::isCommutative() const { + if (const ICmpInst *IC = dyn_cast<ICmpInst>(this)) return IC->isCommutative(); return cast<FCmpInst>(this)->isCommutative(); } -bool CmpInst::isEquality() { - if (ICmpInst *IC = dyn_cast<ICmpInst>(this)) +bool CmpInst::isEquality() const { + if (const ICmpInst *IC = dyn_cast<ICmpInst>(this)) return IC->isEquality(); return cast<FCmpInst>(this)->isEquality(); } @@ -2988,9 +2936,9 @@ bool CmpInst::isFalseWhenEqual(unsigned short predicate) { // SwitchInst Implementation //===----------------------------------------------------------------------===// -void SwitchInst::init(Value *Value, BasicBlock *Default, unsigned NumCases) { - assert(Value && Default); - ReservedSpace = 2+NumCases*2; +void SwitchInst::init(Value *Value, BasicBlock *Default, unsigned NumReserved) { + assert(Value && Default && NumReserved); + ReservedSpace = NumReserved; NumOperands = 2; OperandList = allocHungoffUses(ReservedSpace); @@ -3006,7 +2954,7 @@ SwitchInst::SwitchInst(Value *Value, BasicBlock *Default, unsigned NumCases, Instruction *InsertBefore) : TerminatorInst(Type::getVoidTy(Value->getContext()), Instruction::Switch, 0, 0, InsertBefore) { - init(Value, Default, NumCases); + init(Value, Default, 2+NumCases*2); } /// SwitchInst ctor - Create a new switch instruction, specifying a value to @@ -3017,14 +2965,15 @@ SwitchInst::SwitchInst(Value *Value, BasicBlock *Default, unsigned NumCases, BasicBlock *InsertAtEnd) : TerminatorInst(Type::getVoidTy(Value->getContext()), Instruction::Switch, 0, 0, InsertAtEnd) { - init(Value, Default, NumCases); + init(Value, Default, 2+NumCases*2); } SwitchInst::SwitchInst(const SwitchInst &SI) - : TerminatorInst(Type::getVoidTy(SI.getContext()), Instruction::Switch, - allocHungoffUses(SI.getNumOperands()), SI.getNumOperands()) { + : TerminatorInst(SI.getType(), Instruction::Switch, 0, 0) { + init(SI.getCondition(), SI.getDefaultDest(), SI.getNumOperands()); + NumOperands = SI.getNumOperands(); Use *OL = OperandList, *InOL = SI.OperandList; - for (unsigned i = 0, E = SI.getNumOperands(); i != E; i+=2) { + for (unsigned i = 2, E = SI.getNumOperands(); i != E; i += 2) { OL[i] = InOL[i]; OL[i+1] = InOL[i+1]; } @@ -3032,7 +2981,7 @@ SwitchInst::SwitchInst(const SwitchInst &SI) } SwitchInst::~SwitchInst() { - dropHungoffUses(OperandList); + dropHungoffUses(); } @@ -3060,14 +3009,10 @@ void SwitchInst::removeCase(unsigned idx) { unsigned NumOps = getNumOperands(); Use *OL = OperandList; - // Move everything after this operand down. - // - // FIXME: we could just swap with the end of the list, then erase. However, - // client might not expect this to happen. The code as it is thrashes the - // use/def lists, which is kinda lame. - for (unsigned i = (idx+1)*2; i != NumOps; i += 2) { - OL[i-2] = OL[i]; - OL[i-2+1] = OL[i+1]; + // Overwrite this case with the end of the list. + if ((idx + 1) * 2 != NumOps) { + OL[idx * 2] = OL[NumOps - 2]; + OL[idx * 2 + 1] = OL[NumOps - 1]; } // Nuke the last value. @@ -3103,7 +3048,7 @@ void SwitchInst::resizeOperands(unsigned NumOps) { NewOps[i] = OldOps[i]; } OperandList = NewOps; - if (OldOps) Use::zap(OldOps, OldOps + e, true); + Use::zap(OldOps, OldOps + e, true); } @@ -3118,7 +3063,7 @@ void SwitchInst::setSuccessorV(unsigned idx, BasicBlock *B) { } //===----------------------------------------------------------------------===// -// SwitchInst Implementation +// IndirectBrInst Implementation //===----------------------------------------------------------------------===// void IndirectBrInst::init(Value *Address, unsigned NumDests) { @@ -3158,7 +3103,7 @@ void IndirectBrInst::resizeOperands(unsigned NumOps) { for (unsigned i = 0; i != e; ++i) NewOps[i] = OldOps[i]; OperandList = NewOps; - if (OldOps) Use::zap(OldOps, OldOps + e, true); + Use::zap(OldOps, OldOps + e, true); } IndirectBrInst::IndirectBrInst(Value *Address, unsigned NumCases, @@ -3186,7 +3131,7 @@ IndirectBrInst::IndirectBrInst(const IndirectBrInst &IBI) } IndirectBrInst::~IndirectBrInst() { - dropHungoffUses(OperandList); + dropHungoffUses(); } /// addDestination - Add a destination. @@ -3360,8 +3305,7 @@ ReturnInst *ReturnInst::clone_impl() const { } BranchInst *BranchInst::clone_impl() const { - unsigned Ops(getNumOperands()); - return new(Ops, Ops == 1) BranchInst(*this); + return new(getNumOperands()) BranchInst(*this); } SwitchInst *SwitchInst::clone_impl() const { diff --git a/lib/VMCore/LLVMContext.cpp b/lib/VMCore/LLVMContext.cpp index 707faa8..1bd497d 100644 --- a/lib/VMCore/LLVMContext.cpp +++ b/lib/VMCore/LLVMContext.cpp @@ -19,7 +19,7 @@ #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/SourceMgr.h" #include "LLVMContextImpl.h" -#include <ctype.h> +#include <cctype> using namespace llvm; static ManagedStatic<LLVMContext> GlobalContext; @@ -32,7 +32,7 @@ LLVMContext::LLVMContext() : pImpl(new LLVMContextImpl(*this)) { // Create the fixed metadata kinds. This is done in the same order as the // MD_* enum values so that they correspond. - // Create the 'dbg' metadata kind. + // Create the 'dbg' metadata kind. unsigned DbgID = getMDKindID("dbg"); assert(DbgID == MD_dbg && "dbg kind id drifted"); (void)DbgID; @@ -54,15 +54,17 @@ void LLVMContext::removeModule(Module *M) { // Recoverable Backend Errors //===----------------------------------------------------------------------===// -void LLVMContext::setInlineAsmDiagnosticHandler(void *DiagHandler, - void *DiagContext) { +void LLVMContext:: +setInlineAsmDiagnosticHandler(InlineAsmDiagHandlerTy DiagHandler, + void *DiagContext) { pImpl->InlineAsmDiagHandler = DiagHandler; pImpl->InlineAsmDiagContext = DiagContext; } /// getInlineAsmDiagnosticHandler - Return the diagnostic handler set by /// setInlineAsmDiagnosticHandler. -void *LLVMContext::getInlineAsmDiagnosticHandler() const { +LLVMContext::InlineAsmDiagHandlerTy +LLVMContext::getInlineAsmDiagnosticHandler() const { return pImpl->InlineAsmDiagHandler; } @@ -92,13 +94,11 @@ void LLVMContext::emitError(unsigned LocCookie, StringRef ErrorStr) { errs() << "error: " << ErrorStr << "\n"; exit(1); } - + // If we do have an error handler, we can report the error and keep going. SMDiagnostic Diag("", "error: " + ErrorStr.str()); - - ((SourceMgr::DiagHandlerTy)(intptr_t)pImpl->InlineAsmDiagHandler) - (Diag, pImpl->InlineAsmDiagContext, LocCookie); - + + pImpl->InlineAsmDiagHandler(Diag, pImpl->InlineAsmDiagContext, LocCookie); } //===----------------------------------------------------------------------===// @@ -110,13 +110,13 @@ void LLVMContext::emitError(unsigned LocCookie, StringRef ErrorStr) { static bool isValidName(StringRef MDName) { if (MDName.empty()) return false; - - if (!isalpha(MDName[0])) + + if (!std::isalpha(MDName[0])) return false; - + for (StringRef::iterator I = MDName.begin() + 1, E = MDName.end(); I != E; ++I) { - if (!isalnum(*I) && *I != '_' && *I != '-' && *I != '.') + if (!std::isalnum(*I) && *I != '_' && *I != '-' && *I != '.') return false; } return true; diff --git a/lib/VMCore/LLVMContextImpl.h b/lib/VMCore/LLVMContextImpl.h index faeebb6..23971aa 100644 --- a/lib/VMCore/LLVMContextImpl.h +++ b/lib/VMCore/LLVMContextImpl.h @@ -119,7 +119,8 @@ public: /// will be automatically deleted if this context is deleted. SmallPtrSet<Module*, 4> OwnedModules; - void *InlineAsmDiagHandler, *InlineAsmDiagContext; + LLVMContext::InlineAsmDiagHandlerTy InlineAsmDiagHandler; + void *InlineAsmDiagContext; typedef DenseMap<DenseMapAPIntKeyInfo::KeyTy, ConstantInt*, DenseMapAPIntKeyInfo> IntMapTy; diff --git a/lib/VMCore/LeakDetector.cpp b/lib/VMCore/LeakDetector.cpp index a44f61d..f6651e9 100644 --- a/lib/VMCore/LeakDetector.cpp +++ b/lib/VMCore/LeakDetector.cpp @@ -16,8 +16,8 @@ #include "llvm/ADT/SmallPtrSet.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/ManagedStatic.h" -#include "llvm/System/Mutex.h" -#include "llvm/System/Threading.h" +#include "llvm/Support/Mutex.h" +#include "llvm/Support/Threading.h" #include "llvm/Value.h" using namespace llvm; diff --git a/lib/VMCore/Metadata.cpp b/lib/VMCore/Metadata.cpp index 0b8e8df..84a0975 100644 --- a/lib/VMCore/Metadata.cpp +++ b/lib/VMCore/Metadata.cpp @@ -232,6 +232,9 @@ MDNode *MDNode::getMDNode(LLVMContext &Context, Value *const *Vals, return N; } +MDNode *MDNode::get(LLVMContext &Context, ArrayRef<Value*> Vals) { + return getMDNode(Context, Vals.data(), Vals.size(), FL_Unknown); +} MDNode *MDNode::get(LLVMContext &Context, Value*const* Vals, unsigned NumVals) { return getMDNode(Context, Vals, NumVals, FL_Unknown); } diff --git a/lib/VMCore/PassManager.cpp b/lib/VMCore/PassManager.cpp index 88aaa5e..8bfef98 100644 --- a/lib/VMCore/PassManager.cpp +++ b/lib/VMCore/PassManager.cpp @@ -24,7 +24,7 @@ #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/PassNameParser.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/System/Mutex.h" +#include "llvm/Support/Mutex.h" #include <algorithm> #include <cstdio> #include <map> @@ -500,6 +500,10 @@ PMTopLevelManager::PMTopLevelManager(PMDataManager *PMDM) { void PMTopLevelManager::setLastUser(const SmallVectorImpl<Pass *> &AnalysisPasses, Pass *P) { + unsigned PDepth = 0; + if (P->getResolver()) + PDepth = P->getResolver()->getPMDataManager().getDepth(); + for (SmallVectorImpl<Pass *>::const_iterator I = AnalysisPasses.begin(), E = AnalysisPasses.end(); I != E; ++I) { Pass *AP = *I; @@ -508,13 +512,40 @@ PMTopLevelManager::setLastUser(const SmallVectorImpl<Pass *> &AnalysisPasses, if (P == AP) continue; + // Update the last users of passes that are required transitive by AP. + AnalysisUsage *AnUsage = findAnalysisUsage(AP); + const AnalysisUsage::VectorType &IDs = AnUsage->getRequiredTransitiveSet(); + SmallVector<Pass *, 12> LastUses; + SmallVector<Pass *, 12> LastPMUses; + for (AnalysisUsage::VectorType::const_iterator I = IDs.begin(), + E = IDs.end(); I != E; ++I) { + Pass *AnalysisPass = findAnalysisPass(*I); + assert(AnalysisPass && "Expected analysis pass to exist."); + AnalysisResolver *AR = AnalysisPass->getResolver(); + assert(AR && "Expected analysis resolver to exist."); + unsigned APDepth = AR->getPMDataManager().getDepth(); + + if (PDepth == APDepth) + LastUses.push_back(AnalysisPass); + else if (PDepth > APDepth) + LastPMUses.push_back(AnalysisPass); + } + + setLastUser(LastUses, P); + + // If this pass has a corresponding pass manager, push higher level + // analysis to this pass manager. + if (P->getResolver()) + setLastUser(LastPMUses, P->getResolver()->getPMDataManager().getAsPass()); + + // If AP is the last user of other passes then make P last user of // such passes. for (DenseMap<Pass *, Pass *>::iterator LUI = LastUser.begin(), LUE = LastUser.end(); LUI != LUE; ++LUI) { if (LUI->second == AP) // DenseMap iterator is not invalidated here because - // this is just updating exisitng entry. + // this is just updating existing entries. LastUser[LUI->first] = P; } } diff --git a/lib/VMCore/PassRegistry.cpp b/lib/VMCore/PassRegistry.cpp index 1fc26b0..c97a170 100644 --- a/lib/VMCore/PassRegistry.cpp +++ b/lib/VMCore/PassRegistry.cpp @@ -16,7 +16,7 @@ #include "llvm/PassSupport.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/ManagedStatic.h" -#include "llvm/System/Mutex.h" +#include "llvm/Support/Mutex.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/StringMap.h" @@ -106,7 +106,8 @@ void PassRegistry::registerPass(const PassInfo &PI, bool ShouldFree) { PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl()); bool Inserted = Impl->PassInfoMap.insert(std::make_pair(PI.getTypeInfo(),&PI)).second; - assert(Inserted && "Pass registered multiple times!"); Inserted=Inserted; + assert(Inserted && "Pass registered multiple times!"); + (void)Inserted; Impl->PassInfoStringMap[PI.getPassArgument()] = &PI; // Notify any listeners. diff --git a/lib/VMCore/Type.cpp b/lib/VMCore/Type.cpp index ba50e07..be28ad1 100644 --- a/lib/VMCore/Type.cpp +++ b/lib/VMCore/Type.cpp @@ -27,7 +27,7 @@ #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/System/Threading.h" +#include "llvm/Support/Threading.h" #include <algorithm> #include <cstdarg> using namespace llvm; @@ -1103,7 +1103,7 @@ void DerivedType::refineAbstractTypeTo(const Type *NewType) { while (!AbstractTypeUsers.empty() && NewTy != this) { AbstractTypeUser *User = AbstractTypeUsers.back(); - unsigned OldSize = AbstractTypeUsers.size(); OldSize=OldSize; + unsigned OldSize = AbstractTypeUsers.size(); (void)OldSize; #ifdef DEBUG_MERGE_TYPES DEBUG(dbgs() << " REFINING user " << OldSize-1 << "[" << (void*)User << "] of abstract type [" << (void*)this << " " @@ -1130,7 +1130,7 @@ void DerivedType::notifyUsesThatTypeBecameConcrete() { DEBUG(dbgs() << "typeIsREFINED type: " << (void*)this << " " << *this <<"\n"); #endif - unsigned OldSize = AbstractTypeUsers.size(); OldSize=OldSize; + unsigned OldSize = AbstractTypeUsers.size(); (void)OldSize; while (!AbstractTypeUsers.empty()) { AbstractTypeUser *ATU = AbstractTypeUsers.back(); ATU->typeBecameConcrete(this); diff --git a/lib/VMCore/TypesContext.h b/lib/VMCore/TypesContext.h index 5a90917..4694486 100644 --- a/lib/VMCore/TypesContext.h +++ b/lib/VMCore/TypesContext.h @@ -317,7 +317,7 @@ public: // The old record is now out-of-date, because one of the children has been // updated. Remove the obsolete entry from the map. unsigned NumErased = Map.erase(ValType::get(Ty)); - assert(NumErased && "Element not found!"); NumErased = NumErased; + assert(NumErased && "Element not found!"); (void)NumErased; // Remember the structural hash for the type before we start hacking on it, // in case we need it later. diff --git a/lib/VMCore/Use.cpp b/lib/VMCore/Use.cpp index fec710b..2258b8d 100644 --- a/lib/VMCore/Use.cpp +++ b/lib/VMCore/Use.cpp @@ -11,7 +11,7 @@ // //===----------------------------------------------------------------------===// -#include "llvm/User.h" +#include "llvm/Value.h" namespace llvm { @@ -85,7 +85,8 @@ const Use *Use::getImpliedUser() const { // Use initTags Implementation //===----------------------------------------------------------------------===// -Use *Use::initTags(Use * const Start, Use *Stop, ptrdiff_t Done) { +Use *Use::initTags(Use * const Start, Use *Stop) { + ptrdiff_t Done = 0; while (Done < 20) { if (Start == Stop--) return Start; @@ -97,20 +98,18 @@ Use *Use::initTags(Use * const Start, Use *Stop, ptrdiff_t Done) { oneDigitTag, oneDigitTag, oneDigitTag, oneDigitTag, stopTag }; - Stop->Prev.setFromOpaqueValue(reinterpret_cast<Use**>(tags[Done++])); - Stop->Val = 0; + new(Stop) Use(tags[Done++]); } ptrdiff_t Count = Done; while (Start != Stop) { --Stop; - Stop->Val = 0; if (!Count) { - Stop->Prev.setFromOpaqueValue(reinterpret_cast<Use**>(stopTag)); + new(Stop) Use(stopTag); ++Done; Count = Done; } else { - Stop->Prev.setFromOpaqueValue(reinterpret_cast<Use**>(Count & 1)); + new(Stop) Use(PrevPtrTag(Count & 1)); Count >>= 1; ++Done; } @@ -124,123 +123,24 @@ Use *Use::initTags(Use * const Start, Use *Stop, ptrdiff_t Done) { //===----------------------------------------------------------------------===// void Use::zap(Use *Start, const Use *Stop, bool del) { - if (del) { - while (Start != Stop) { - (--Stop)->~Use(); - } + while (Start != Stop) + (--Stop)->~Use(); + if (del) ::operator delete(Start); - return; - } - - while (Start != Stop) { - (Start++)->set(0); - } } //===----------------------------------------------------------------------===// -// AugmentedUse layout struct -//===----------------------------------------------------------------------===// - -struct AugmentedUse : public Use { - PointerIntPair<User*, 1, Tag> ref; - AugmentedUse(); // not implemented -}; - - -//===----------------------------------------------------------------------===// // Use getUser Implementation //===----------------------------------------------------------------------===// User *Use::getUser() const { const Use *End = getImpliedUser(); - const PointerIntPair<User*, 1, Tag>& ref( - static_cast<const AugmentedUse*>(End - 1)->ref); + const PointerIntPair<User*, 1, unsigned>& + ref(static_cast<const AugmentedUse*>(End - 1)->ref); User *She = ref.getPointer(); return ref.getInt() ? She : (User*)End; } -//===----------------------------------------------------------------------===// -// User allocHungoffUses Implementation -//===----------------------------------------------------------------------===// - -Use *User::allocHungoffUses(unsigned N) const { - Use *Begin = static_cast<Use*>(::operator new(sizeof(Use) * N - + sizeof(AugmentedUse) - - sizeof(Use))); - Use *End = Begin + N; - PointerIntPair<User*, 1, Tag>& ref(static_cast<AugmentedUse&>(End[-1]).ref); - ref.setPointer(const_cast<User*>(this)); - ref.setInt(tagOne); - return Use::initTags(Begin, End); -} - -//===----------------------------------------------------------------------===// -// User operator new Implementations -//===----------------------------------------------------------------------===// - -void *User::operator new(size_t s, unsigned Us) { - void *Storage = ::operator new(s + sizeof(Use) * Us); - Use *Start = static_cast<Use*>(Storage); - Use *End = Start + Us; - User *Obj = reinterpret_cast<User*>(End); - Obj->OperandList = Start; - Obj->NumOperands = Us; - Use::initTags(Start, End); - return Obj; -} - -/// Prefixed allocation - just before the first Use, allocate a NULL pointer. -/// The destructor can detect its presence and readjust the OperandList -/// for deletition. -/// -void *User::operator new(size_t s, unsigned Us, bool Prefix) { - // currently prefixed allocation only admissible for - // unconditional branch instructions - if (!Prefix) - return operator new(s, Us); - - assert(Us == 1 && "Other than one Use allocated?"); - typedef PointerIntPair<void*, 2, Use::PrevPtrTag> TaggedPrefix; - void *Raw = ::operator new(s + sizeof(TaggedPrefix) + sizeof(Use) * Us); - TaggedPrefix *Pre = static_cast<TaggedPrefix*>(Raw); - Pre->setFromOpaqueValue(0); - void *Storage = Pre + 1; // skip over prefix - Use *Start = static_cast<Use*>(Storage); - Use *End = Start + Us; - User *Obj = reinterpret_cast<User*>(End); - Obj->OperandList = Start; - Obj->NumOperands = Us; - Use::initTags(Start, End); - return Obj; -} - -//===----------------------------------------------------------------------===// -// User operator delete Implementation -//===----------------------------------------------------------------------===// - -void User::operator delete(void *Usr) { - User *Start = static_cast<User*>(Usr); - Use *Storage = static_cast<Use*>(Usr) - Start->NumOperands; - // - // look for a variadic User - if (Storage == Start->OperandList) { - ::operator delete(Storage); - return; - } - // - // check for the flag whether the destructor has detected a prefixed - // allocation, in which case we remove the flag and delete starting - // at OperandList - if (reinterpret_cast<intptr_t>(Start->OperandList) & 1) { - ::operator delete(reinterpret_cast<char*>(Start->OperandList) - 1); - return; - } - // - // in all other cases just delete the nullary User (covers hung-off - // uses also - ::operator delete(Usr); -} - } // End llvm namespace diff --git a/lib/VMCore/User.cpp b/lib/VMCore/User.cpp new file mode 100644 index 0000000..2f4587d --- /dev/null +++ b/lib/VMCore/User.cpp @@ -0,0 +1,81 @@ +//===-- User.cpp - Implement the User class -------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Constant.h" +#include "llvm/GlobalValue.h" +#include "llvm/User.h" + +namespace llvm { + +//===----------------------------------------------------------------------===// +// User Class +//===----------------------------------------------------------------------===// + +// replaceUsesOfWith - Replaces all references to the "From" definition with +// references to the "To" definition. +// +void User::replaceUsesOfWith(Value *From, Value *To) { + if (From == To) return; // Duh what? + + assert((!isa<Constant>(this) || isa<GlobalValue>(this)) && + "Cannot call User::replaceUsesOfWith on a constant!"); + + for (unsigned i = 0, E = getNumOperands(); i != E; ++i) + if (getOperand(i) == From) { // Is This operand is pointing to oldval? + // The side effects of this setOperand call include linking to + // "To", adding "this" to the uses list of To, and + // most importantly, removing "this" from the use list of "From". + setOperand(i, To); // Fix it now... + } +} + +//===----------------------------------------------------------------------===// +// User allocHungoffUses Implementation +//===----------------------------------------------------------------------===// + +Use *User::allocHungoffUses(unsigned N) const { + Use *Begin = static_cast<Use*>(::operator new(sizeof(Use) * N + + sizeof(AugmentedUse) + - sizeof(Use))); + Use *End = Begin + N; + PointerIntPair<User*, 1, unsigned>& + ref(static_cast<AugmentedUse&>(End[-1]).ref); + ref.setPointer(const_cast<User*>(this)); + ref.setInt(1); + return Use::initTags(Begin, End); +} + +//===----------------------------------------------------------------------===// +// User operator new Implementations +//===----------------------------------------------------------------------===// + +void *User::operator new(size_t s, unsigned Us) { + void *Storage = ::operator new(s + sizeof(Use) * Us); + Use *Start = static_cast<Use*>(Storage); + Use *End = Start + Us; + User *Obj = reinterpret_cast<User*>(End); + Obj->OperandList = Start; + Obj->NumOperands = Us; + Use::initTags(Start, End); + return Obj; +} + +//===----------------------------------------------------------------------===// +// User operator delete Implementation +//===----------------------------------------------------------------------===// + +void User::operator delete(void *Usr) { + User *Start = static_cast<User*>(Usr); + Use *Storage = static_cast<Use*>(Usr) - Start->NumOperands; + // If there were hung-off uses, they will have been freed already and + // NumOperands reset to 0, so here we just free the User itself. + ::operator delete(Storage); +} + +} // End llvm namespace diff --git a/lib/VMCore/Value.cpp b/lib/VMCore/Value.cpp index 9d0c2c5..29f6a80 100644 --- a/lib/VMCore/Value.cpp +++ b/lib/VMCore/Value.cpp @@ -255,7 +255,7 @@ void Value::takeName(Value *V) { // Get V's ST, this should always succed, because V has a name. ValueSymbolTable *VST; bool Failure = getSymTab(V, VST); - assert(!Failure && "V has a name, so it should have a ST!"); Failure=Failure; + assert(!Failure && "V has a name, so it should have a ST!"); (void)Failure; // If these values are both in the same symtab, we can do this very fast. // This works even if both values have no symtab yet. @@ -346,27 +346,6 @@ Value *Value::stripPointerCasts() { return V; } -Value *Value::getUnderlyingObject(unsigned MaxLookup) { - if (!getType()->isPointerTy()) - return this; - Value *V = this; - for (unsigned Count = 0; MaxLookup == 0 || Count < MaxLookup; ++Count) { - if (GEPOperator *GEP = dyn_cast<GEPOperator>(V)) { - V = GEP->getPointerOperand(); - } else if (Operator::getOpcode(V) == Instruction::BitCast) { - V = cast<Operator>(V)->getOperand(0); - } else if (GlobalAlias *GA = dyn_cast<GlobalAlias>(V)) { - if (GA->mayBeOverridden()) - return V; - V = GA->getAliasee(); - } else { - return V; - } - assert(V->getType()->isPointerTy() && "Unexpected operand type!"); - } - return V; -} - /// isDereferenceablePointer - Test if this value is always a pointer to /// allocated and suitably aligned memory for a simple load or store. bool Value::isDereferenceablePointer() const { @@ -384,6 +363,10 @@ bool Value::isDereferenceablePointer() const { if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(this)) return !GV->hasExternalWeakLinkage(); + // byval arguments are ok. + if (const Argument *A = dyn_cast<Argument>(this)) + return A->hasByValAttr(); + // For GEPs, determine if the indexing lands within the allocated object. if (const GEPOperator *GEP = dyn_cast<GEPOperator>(this)) { // Conservatively require that the base pointer be fully dereferenceable. @@ -655,26 +638,3 @@ void ValueHandleBase::ValueIsRAUWd(Value *Old, Value *New) { /// ~CallbackVH. Empty, but defined here to avoid emitting the vtable /// more than once. CallbackVH::~CallbackVH() {} - - -//===----------------------------------------------------------------------===// -// User Class -//===----------------------------------------------------------------------===// - -// replaceUsesOfWith - Replaces all references to the "From" definition with -// references to the "To" definition. -// -void User::replaceUsesOfWith(Value *From, Value *To) { - if (From == To) return; // Duh what? - - assert((!isa<Constant>(this) || isa<GlobalValue>(this)) && - "Cannot call User::replaceUsesOfWith on a constant!"); - - for (unsigned i = 0, E = getNumOperands(); i != E; ++i) - if (getOperand(i) == From) { // Is This operand is pointing to oldval? - // The side effects of this setOperand call include linking to - // "To", adding "this" to the uses list of To, and - // most importantly, removing "this" from the use list of "From". - setOperand(i, To); // Fix it now... - } -} diff --git a/lib/VMCore/ValueTypes.cpp b/lib/VMCore/ValueTypes.cpp index b59e202..c054ae4 100644 --- a/lib/VMCore/ValueTypes.cpp +++ b/lib/VMCore/ValueTypes.cpp @@ -109,7 +109,7 @@ std::string EVT::getEVTString() const { case MVT::ppcf128: return "ppcf128"; case MVT::isVoid: return "isVoid"; case MVT::Other: return "ch"; - case MVT::Flag: return "flag"; + case MVT::Glue: return "glue"; case MVT::x86mmx: return "x86mmx"; case MVT::v2i8: return "v2i8"; case MVT::v4i8: return "v4i8"; diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp index 2b87619..58ec6fe 100644 --- a/lib/VMCore/Verifier.cpp +++ b/lib/VMCore/Verifier.cpp @@ -484,6 +484,7 @@ void Verifier::visitGlobalAlias(GlobalAlias &GA) { "Aliasee cannot be NULL!", &GA); Assert1(GA.getType() == GA.getAliasee()->getType(), "Alias and aliasee types should match!", &GA); + Assert1(!GA.hasUnnamedAddr(), "Alias cannot have unnamed_addr!", &GA); if (!isa<GlobalValue>(GA.getAliasee())) { const ConstantExpr *CE = dyn_cast<ConstantExpr>(GA.getAliasee()); |