diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2011-02-20 12:57:14 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2011-02-20 12:57:14 +0000 |
commit | cf099d11218cb6f6c5cce947d6738e347f07fb12 (patch) | |
tree | d2b61ce94e654cb01a254d2195259db5f9cc3f3c /lib/VMCore | |
parent | 49011b52fcba02a6051957b84705159f52fae4e4 (diff) | |
download | src-test2-cf099d11218cb6f6c5cce947d6738e347f07fb12.tar.gz src-test2-cf099d11218cb6f6c5cce947d6738e347f07fb12.zip |
Notes
Diffstat (limited to 'lib/VMCore')
34 files changed, 1708 insertions, 1263 deletions
diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp index 831a9960463d..cbc874a53f63 100644 --- a/lib/VMCore/AsmWriter.cpp +++ b/lib/VMCore/AsmWriter.cpp @@ -198,6 +198,7 @@ void TypePrinting::CalcTypeName(const Type *Ty, case Type::PPC_FP128TyID: OS << "ppc_fp128"; break; case Type::LabelTyID: OS << "label"; break; case Type::MetadataTyID: OS << "metadata"; break; + case Type::X86_MMXTyID: OS << "x86_mmx"; break; case Type::IntegerTyID: OS << 'i' << cast<IntegerType>(Ty)->getBitWidth(); break; @@ -830,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)) { @@ -1057,11 +1059,6 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV, return; } - if (const MDNode *Node = dyn_cast<MDNode>(CV)) { - Out << "!" << Machine->getMetadataSlot(Node); - return; - } - if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV)) { Out << CE->getOpcodeName(); WriteOptimizationInfo(Out, CE); @@ -1165,7 +1162,11 @@ static void WriteAsOperandInternal(raw_ostream &Out, const Value *V, else Machine = new SlotTracker(Context); } - Out << '!' << Machine->getMetadataSlot(N); + int Slot = Machine->getMetadataSlot(N); + if (Slot == -1) + Out << "<badref>"; + else + Out << '!' << Slot; return; } @@ -1395,7 +1396,11 @@ void AssemblyWriter::printNamedMDNode(const NamedMDNode *NMD) { Out << "!" << NMD->getName() << " = !{"; for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) { if (i) Out << ", "; - Out << '!' << Machine.getMetadataSlot(NMD->getOperand(i)); + int Slot = Machine.getMetadataSlot(NMD->getOperand(i)); + if (Slot == -1) + Out << "<badref>"; + else + Out << '!' << Slot; } Out << "}\n"; } @@ -1455,6 +1460,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); @@ -1575,6 +1581,8 @@ void AssemblyWriter::printFunction(const Function *F) { case CallingConv::ARM_AAPCS: Out << "arm_aapcscc "; break; case CallingConv::ARM_AAPCS_VFP:Out << "arm_aapcs_vfpcc "; break; case CallingConv::MSP430_INTR: Out << "msp430_intrcc "; break; + case CallingConv::PTX_Kernel: Out << "ptx_kernel"; break; + case CallingConv::PTX_Device: Out << "ptx_device"; break; default: Out << "cc" << F->getCallingConv() << " "; break; } @@ -1622,6 +1630,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()); @@ -1843,6 +1853,8 @@ void AssemblyWriter::printInstruction(const Instruction &I) { case CallingConv::ARM_AAPCS: Out << " arm_aapcscc "; break; case CallingConv::ARM_AAPCS_VFP:Out << " arm_aapcs_vfpcc "; break; case CallingConv::MSP430_INTR: Out << " msp430_intrcc "; break; + case CallingConv::PTX_Kernel: Out << " ptx_kernel"; break; + case CallingConv::PTX_Device: Out << " ptx_device"; break; default: Out << " cc" << CI->getCallingConv(); break; } @@ -1897,6 +1909,8 @@ void AssemblyWriter::printInstruction(const Instruction &I) { case CallingConv::ARM_AAPCS: Out << " arm_aapcscc "; break; case CallingConv::ARM_AAPCS_VFP:Out << " arm_aapcs_vfpcc "; break; case CallingConv::MSP430_INTR: Out << " msp430_intrcc "; break; + case CallingConv::PTX_Kernel: Out << " ptx_kernel"; break; + case CallingConv::PTX_Device: Out << " ptx_device"; break; default: Out << " cc" << II->getCallingConv(); break; } @@ -2033,15 +2047,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 a000aee2ab45..92152a3b90ae 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" @@ -70,6 +70,8 @@ std::string Attribute::getAsString(Attributes Attrs) { Result += "noimplicitfloat "; if (Attrs & Attribute::Naked) Result += "naked "; + if (Attrs & Attribute::Hotpatch) + Result += "hotpatch "; if (Attrs & Attribute::StackAlignment) { Result += "alignstack("; Result += utostr(Attribute::getStackAlignmentFromAttrs(Attrs)); @@ -105,6 +107,14 @@ Attributes Attribute::typeIncompatible(const Type *Ty) { //===----------------------------------------------------------------------===// namespace llvm { + class AttributeListImpl; +} + +static ManagedStatic<FoldingSet<AttributeListImpl> > AttributesLists; + +namespace llvm { +static ManagedStatic<sys::SmartMutex<true> > ALMutex; + class AttributeListImpl : public FoldingSetNode { sys::cas_flag RefCount; @@ -120,10 +130,17 @@ public: RefCount = 0; } - void AddRef() { sys::AtomicIncrement(&RefCount); } + void AddRef() { + sys::SmartScopedLock<true> Lock(*ALMutex); + ++RefCount; + } void DropRef() { - sys::cas_flag old = sys::AtomicDecrement(&RefCount); - if (old == 0) delete this; + sys::SmartScopedLock<true> Lock(*ALMutex); + if (!AttributesLists.isConstructed()) + return; + sys::cas_flag new_val = --RefCount; + if (new_val == 0) + delete this; } void Profile(FoldingSetNodeID &ID) const { @@ -137,11 +154,8 @@ public: }; } -static ManagedStatic<sys::SmartMutex<true> > ALMutex; -static ManagedStatic<FoldingSet<AttributeListImpl> > AttributesLists; - AttributeListImpl::~AttributeListImpl() { - sys::SmartScopedLock<true> Lock(*ALMutex); + // NOTE: Lock must be acquired by caller. AttributesLists->RemoveNode(this); } @@ -195,6 +209,7 @@ AttrListPtr::AttrListPtr(const AttrListPtr &P) : AttrList(P.AttrList) { } const AttrListPtr &AttrListPtr::operator=(const AttrListPtr &RHS) { + sys::SmartScopedLock<true> Lock(*ALMutex); if (AttrList == RHS.AttrList) return *this; if (AttrList) AttrList->DropRef(); AttrList = RHS.AttrList; diff --git a/lib/VMCore/AutoUpgrade.cpp b/lib/VMCore/AutoUpgrade.cpp index 9330e141c341..b32354035644 100644 --- a/lib/VMCore/AutoUpgrade.cpp +++ b/lib/VMCore/AutoUpgrade.cpp @@ -288,37 +288,224 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) { break; case 'x': // This fixes all MMX shift intrinsic instructions to take a - // v1i64 instead of a v2i32 as the second parameter. - if (Name.compare(5,10,"x86.mmx.ps",10) == 0 && - (Name.compare(13,4,"psll", 4) == 0 || - Name.compare(13,4,"psra", 4) == 0 || - Name.compare(13,4,"psrl", 4) == 0) && Name[17] != 'i') { - - const llvm::Type *VT = - VectorType::get(IntegerType::get(FTy->getContext(), 64), 1); - - // We don't have to do anything if the parameter already has - // the correct type. - if (FTy->getParamType(1) == VT) + // x86_mmx instead of a v1i64, v2i32, v4i16, or v8i8. + if (Name.compare(5, 8, "x86.mmx.", 8) == 0) { + const Type *X86_MMXTy = VectorType::getX86_MMXTy(FTy->getContext()); + + if (Name.compare(13, 4, "padd", 4) == 0 || + Name.compare(13, 4, "psub", 4) == 0 || + Name.compare(13, 4, "pmul", 4) == 0 || + Name.compare(13, 5, "pmadd", 5) == 0 || + Name.compare(13, 4, "pand", 4) == 0 || + Name.compare(13, 3, "por", 3) == 0 || + Name.compare(13, 4, "pxor", 4) == 0 || + Name.compare(13, 4, "pavg", 4) == 0 || + Name.compare(13, 4, "pmax", 4) == 0 || + Name.compare(13, 4, "pmin", 4) == 0 || + Name.compare(13, 4, "psad", 4) == 0 || + Name.compare(13, 4, "psll", 4) == 0 || + Name.compare(13, 4, "psrl", 4) == 0 || + Name.compare(13, 4, "psra", 4) == 0 || + Name.compare(13, 4, "pack", 4) == 0 || + Name.compare(13, 6, "punpck", 6) == 0 || + Name.compare(13, 4, "pcmp", 4) == 0) { + assert(FTy->getNumParams() == 2 && "MMX intrinsic takes 2 args!"); + const Type *SecondParamTy = X86_MMXTy; + + if (Name.compare(13, 5, "pslli", 5) == 0 || + Name.compare(13, 5, "psrli", 5) == 0 || + Name.compare(13, 5, "psrai", 5) == 0) + SecondParamTy = FTy->getParamType(1); + + // Don't do anything if it has the correct types. + if (FTy->getReturnType() == X86_MMXTy && + FTy->getParamType(0) == X86_MMXTy && + FTy->getParamType(1) == SecondParamTy) + break; + + // We first need to change the name of the old (bad) intrinsic, because + // its type is incorrect, but we cannot overload that name. We + // arbitrarily unique it here allowing us to construct a correctly named + // and typed function below. + F->setName(""); + + // Now construct the new intrinsic with the correct name and type. We + // leave the old function around in order to query its type, whatever it + // may be, and correctly convert up to the new type. + NewFn = cast<Function>(M->getOrInsertFunction(Name, + X86_MMXTy, X86_MMXTy, + SecondParamTy, (Type*)0)); + return true; + } + + if (Name.compare(13, 8, "maskmovq", 8) == 0) { + // Don't do anything if it has the correct types. + if (FTy->getParamType(0) == X86_MMXTy && + FTy->getParamType(1) == X86_MMXTy) + break; + + F->setName(""); + NewFn = cast<Function>(M->getOrInsertFunction(Name, + FTy->getReturnType(), + X86_MMXTy, + X86_MMXTy, + FTy->getParamType(2), + (Type*)0)); + return true; + } + + if (Name.compare(13, 8, "pmovmskb", 8) == 0) { + if (FTy->getParamType(0) == X86_MMXTy) + break; + + F->setName(""); + NewFn = cast<Function>(M->getOrInsertFunction(Name, + FTy->getReturnType(), + X86_MMXTy, + (Type*)0)); + return true; + } + + if (Name.compare(13, 5, "movnt", 5) == 0) { + if (FTy->getParamType(1) == X86_MMXTy) + break; + + F->setName(""); + NewFn = cast<Function>(M->getOrInsertFunction(Name, + FTy->getReturnType(), + FTy->getParamType(0), + X86_MMXTy, + (Type*)0)); + return true; + } + + if (Name.compare(13, 7, "palignr", 7) == 0) { + if (FTy->getReturnType() == X86_MMXTy && + FTy->getParamType(0) == X86_MMXTy && + FTy->getParamType(1) == X86_MMXTy) + break; + + F->setName(""); + NewFn = cast<Function>(M->getOrInsertFunction(Name, + X86_MMXTy, + X86_MMXTy, + X86_MMXTy, + FTy->getParamType(2), + (Type*)0)); + return true; + } + + if (Name.compare(13, 5, "pextr", 5) == 0) { + if (FTy->getParamType(0) == X86_MMXTy) + break; + + F->setName(""); + NewFn = cast<Function>(M->getOrInsertFunction(Name, + FTy->getReturnType(), + X86_MMXTy, + FTy->getParamType(1), + (Type*)0)); + return true; + } + + if (Name.compare(13, 5, "pinsr", 5) == 0) { + if (FTy->getReturnType() == X86_MMXTy && + FTy->getParamType(0) == X86_MMXTy) + break; + + F->setName(""); + NewFn = cast<Function>(M->getOrInsertFunction(Name, + X86_MMXTy, + X86_MMXTy, + FTy->getParamType(1), + FTy->getParamType(2), + (Type*)0)); + return true; + } + + if (Name.compare(13, 12, "cvtsi32.si64", 12) == 0) { + if (FTy->getReturnType() == X86_MMXTy) + break; + + F->setName(""); + NewFn = cast<Function>(M->getOrInsertFunction(Name, + X86_MMXTy, + FTy->getParamType(0), + (Type*)0)); + return true; + } + + if (Name.compare(13, 12, "cvtsi64.si32", 12) == 0) { + if (FTy->getParamType(0) == X86_MMXTy) + break; + + F->setName(""); + NewFn = cast<Function>(M->getOrInsertFunction(Name, + FTy->getReturnType(), + X86_MMXTy, + (Type*)0)); + return true; + } + + if (Name.compare(13, 8, "vec.init", 8) == 0) { + if (FTy->getReturnType() == X86_MMXTy) + break; + + F->setName(""); + + if (Name.compare(21, 2, ".b", 2) == 0) + NewFn = cast<Function>(M->getOrInsertFunction(Name, + X86_MMXTy, + FTy->getParamType(0), + FTy->getParamType(1), + FTy->getParamType(2), + FTy->getParamType(3), + FTy->getParamType(4), + FTy->getParamType(5), + FTy->getParamType(6), + FTy->getParamType(7), + (Type*)0)); + else if (Name.compare(21, 2, ".w", 2) == 0) + NewFn = cast<Function>(M->getOrInsertFunction(Name, + X86_MMXTy, + FTy->getParamType(0), + FTy->getParamType(1), + FTy->getParamType(2), + FTy->getParamType(3), + (Type*)0)); + else if (Name.compare(21, 2, ".d", 2) == 0) + NewFn = cast<Function>(M->getOrInsertFunction(Name, + X86_MMXTy, + FTy->getParamType(0), + FTy->getParamType(1), + (Type*)0)); + return true; + } + + + if (Name.compare(13, 9, "vec.ext.d", 9) == 0) { + if (FTy->getReturnType() == X86_MMXTy && + FTy->getParamType(0) == X86_MMXTy) + break; + + F->setName(""); + NewFn = cast<Function>(M->getOrInsertFunction(Name, + X86_MMXTy, + X86_MMXTy, + FTy->getParamType(1), + (Type*)0)); + return true; + } + + if (Name.compare(13, 9, "emms", 4) == 0 || + Name.compare(13, 9, "femms", 5) == 0) { + NewFn = 0; break; - - // We first need to change the name of the old (bad) intrinsic, because - // its type is incorrect, but we cannot overload that name. We - // arbitrarily unique it here allowing us to construct a correctly named - // and typed function below. - F->setName(""); + } - assert(FTy->getNumParams() == 2 && "MMX shift intrinsics take 2 args!"); - - // Now construct the new intrinsic with the correct name and type. We - // leave the old function around in order to query its type, whatever it - // may be, and correctly convert up to the new type. - NewFn = cast<Function>(M->getOrInsertFunction(Name, - FTy->getReturnType(), - FTy->getParamType(0), - VT, - (Type *)0)); - return true; + // We really shouldn't get here ever. + assert(0 && "Invalid MMX intrinsic!"); + break; } else if (Name.compare(5,17,"x86.sse2.loadh.pd",17) == 0 || Name.compare(5,17,"x86.sse2.loadl.pd",17) == 0 || Name.compare(5,16,"x86.sse2.movl.dq",16) == 0 || @@ -341,6 +528,16 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) { // or 0. NewFn = 0; return true; + } else if (Name.compare(5, 17, "x86.ssse3.pshuf.w", 17) == 0) { + // This is an SSE/MMX instruction. + const Type *X86_MMXTy = VectorType::getX86_MMXTy(FTy->getContext()); + NewFn = + cast<Function>(M->getOrInsertFunction("llvm.x86.sse.pshuf.w", + X86_MMXTy, + X86_MMXTy, + Type::getInt8Ty(F->getContext()), + (Type*)0)); + return true; } break; @@ -432,6 +629,39 @@ static Instruction *CallVABD(CallInst *CI, Value *Arg0, Value *Arg1) { "upgraded."+CI->getName(), CI); } +/// ConstructNewCallInst - Construct a new CallInst with the signature of NewFn. +static void ConstructNewCallInst(Function *NewFn, CallInst *OldCI, + Value **Operands, unsigned NumOps, + bool AssignName = true) { + // Construct a new CallInst. + CallInst *NewCI = + CallInst::Create(NewFn, Operands, Operands + NumOps, + AssignName ? "upgraded." + OldCI->getName() : "", OldCI); + + NewCI->setTailCall(OldCI->isTailCall()); + NewCI->setCallingConv(OldCI->getCallingConv()); + + // Handle any uses of the old CallInst. If the type has changed, add a cast. + if (!OldCI->use_empty()) { + if (OldCI->getType() != NewCI->getType()) { + Function *OldFn = OldCI->getCalledFunction(); + CastInst *RetCast = + CastInst::Create(CastInst::getCastOpcode(NewCI, true, + OldFn->getReturnType(), true), + NewCI, OldFn->getReturnType(), NewCI->getName(),OldCI); + + // Replace all uses of the old call with the new cast which has the + // correct type. + OldCI->replaceAllUsesWith(RetCast); + } else { + OldCI->replaceAllUsesWith(NewCI); + } + } + + // Clean up the old call now that it has been completely upgraded. + OldCI->eraseFromParent(); +} + // UpgradeIntrinsicCall - Upgrade a call to an old intrinsic to be a call the // upgraded intrinsic. All argument and return casting must be provided in // order to seamlessly integrate with existing context. @@ -629,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()); } @@ -685,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()); } @@ -759,40 +989,265 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) { break; } + case Intrinsic::x86_mmx_padd_b: + case Intrinsic::x86_mmx_padd_w: + case Intrinsic::x86_mmx_padd_d: + case Intrinsic::x86_mmx_padd_q: + case Intrinsic::x86_mmx_padds_b: + case Intrinsic::x86_mmx_padds_w: + case Intrinsic::x86_mmx_paddus_b: + case Intrinsic::x86_mmx_paddus_w: + case Intrinsic::x86_mmx_psub_b: + case Intrinsic::x86_mmx_psub_w: + case Intrinsic::x86_mmx_psub_d: + case Intrinsic::x86_mmx_psub_q: + case Intrinsic::x86_mmx_psubs_b: + case Intrinsic::x86_mmx_psubs_w: + case Intrinsic::x86_mmx_psubus_b: + case Intrinsic::x86_mmx_psubus_w: + case Intrinsic::x86_mmx_pmulh_w: + case Intrinsic::x86_mmx_pmull_w: + case Intrinsic::x86_mmx_pmulhu_w: + case Intrinsic::x86_mmx_pmulu_dq: + case Intrinsic::x86_mmx_pmadd_wd: + case Intrinsic::x86_mmx_pand: + case Intrinsic::x86_mmx_pandn: + case Intrinsic::x86_mmx_por: + case Intrinsic::x86_mmx_pxor: + case Intrinsic::x86_mmx_pavg_b: + case Intrinsic::x86_mmx_pavg_w: + case Intrinsic::x86_mmx_pmaxu_b: + case Intrinsic::x86_mmx_pmaxs_w: + case Intrinsic::x86_mmx_pminu_b: + case Intrinsic::x86_mmx_pmins_w: + case Intrinsic::x86_mmx_psad_bw: + case Intrinsic::x86_mmx_psll_w: case Intrinsic::x86_mmx_psll_d: case Intrinsic::x86_mmx_psll_q: - case Intrinsic::x86_mmx_psll_w: - case Intrinsic::x86_mmx_psra_d: - case Intrinsic::x86_mmx_psra_w: + case Intrinsic::x86_mmx_pslli_w: + case Intrinsic::x86_mmx_pslli_d: + case Intrinsic::x86_mmx_pslli_q: + case Intrinsic::x86_mmx_psrl_w: case Intrinsic::x86_mmx_psrl_d: case Intrinsic::x86_mmx_psrl_q: - case Intrinsic::x86_mmx_psrl_w: { + case Intrinsic::x86_mmx_psrli_w: + case Intrinsic::x86_mmx_psrli_d: + case Intrinsic::x86_mmx_psrli_q: + case Intrinsic::x86_mmx_psra_w: + case Intrinsic::x86_mmx_psra_d: + case Intrinsic::x86_mmx_psrai_w: + case Intrinsic::x86_mmx_psrai_d: + case Intrinsic::x86_mmx_packsswb: + case Intrinsic::x86_mmx_packssdw: + case Intrinsic::x86_mmx_packuswb: + case Intrinsic::x86_mmx_punpckhbw: + case Intrinsic::x86_mmx_punpckhwd: + case Intrinsic::x86_mmx_punpckhdq: + case Intrinsic::x86_mmx_punpcklbw: + case Intrinsic::x86_mmx_punpcklwd: + case Intrinsic::x86_mmx_punpckldq: + case Intrinsic::x86_mmx_pcmpeq_b: + case Intrinsic::x86_mmx_pcmpeq_w: + case Intrinsic::x86_mmx_pcmpeq_d: + case Intrinsic::x86_mmx_pcmpgt_b: + case Intrinsic::x86_mmx_pcmpgt_w: + case Intrinsic::x86_mmx_pcmpgt_d: { Value *Operands[2]; + // Cast the operand to the X86 MMX type. + Operands[0] = new BitCastInst(CI->getArgOperand(0), + NewFn->getFunctionType()->getParamType(0), + "upgraded.", CI); + + switch (NewFn->getIntrinsicID()) { + default: + // Cast to the X86 MMX type. + Operands[1] = new BitCastInst(CI->getArgOperand(1), + NewFn->getFunctionType()->getParamType(1), + "upgraded.", CI); + break; + case Intrinsic::x86_mmx_pslli_w: + case Intrinsic::x86_mmx_pslli_d: + case Intrinsic::x86_mmx_pslli_q: + case Intrinsic::x86_mmx_psrli_w: + case Intrinsic::x86_mmx_psrli_d: + case Intrinsic::x86_mmx_psrli_q: + case Intrinsic::x86_mmx_psrai_w: + case Intrinsic::x86_mmx_psrai_d: + // These take an i32 as their second parameter. + Operands[1] = CI->getArgOperand(1); + break; + } + + ConstructNewCallInst(NewFn, CI, Operands, 2); + break; + } + case Intrinsic::x86_mmx_maskmovq: { + Value *Operands[3]; + + // Cast the operands to the X86 MMX type. + Operands[0] = new BitCastInst(CI->getArgOperand(0), + NewFn->getFunctionType()->getParamType(0), + "upgraded.", CI); + Operands[1] = new BitCastInst(CI->getArgOperand(1), + NewFn->getFunctionType()->getParamType(1), + "upgraded.", CI); + Operands[2] = CI->getArgOperand(2); + + ConstructNewCallInst(NewFn, CI, Operands, 3, false); + break; + } + case Intrinsic::x86_mmx_pmovmskb: { + Value *Operands[1]; + + // Cast the operand to the X86 MMX type. + Operands[0] = new BitCastInst(CI->getArgOperand(0), + NewFn->getFunctionType()->getParamType(0), + "upgraded.", CI); + + ConstructNewCallInst(NewFn, CI, Operands, 1); + break; + } + case Intrinsic::x86_mmx_movnt_dq: { + Value *Operands[2]; + Operands[0] = CI->getArgOperand(0); - - // Cast the second parameter to the correct type. - BitCastInst *BC = new BitCastInst(CI->getArgOperand(1), - NewFn->getFunctionType()->getParamType(1), - "upgraded.", CI); - Operands[1] = BC; - - // Construct a new CallInst - CallInst *NewCI = CallInst::Create(NewFn, Operands, Operands+2, - "upgraded."+CI->getName(), CI); - NewCI->setTailCall(CI->isTailCall()); - NewCI->setCallingConv(CI->getCallingConv()); - - // Handle any uses of the old CallInst. - if (!CI->use_empty()) - // Replace all uses of the old call with the new cast which has the - // correct type. - CI->replaceAllUsesWith(NewCI); - - // Clean up the old call now that it has been completely upgraded. - CI->eraseFromParent(); + + // Cast the operand to the X86 MMX type. + Operands[1] = new BitCastInst(CI->getArgOperand(1), + NewFn->getFunctionType()->getParamType(1), + "upgraded.", CI); + + ConstructNewCallInst(NewFn, CI, Operands, 2, false); break; - } + } + case Intrinsic::x86_mmx_palignr_b: { + Value *Operands[3]; + + // Cast the operands to the X86 MMX type. + Operands[0] = new BitCastInst(CI->getArgOperand(0), + NewFn->getFunctionType()->getParamType(0), + "upgraded.", CI); + Operands[1] = new BitCastInst(CI->getArgOperand(1), + NewFn->getFunctionType()->getParamType(1), + "upgraded.", CI); + Operands[2] = CI->getArgOperand(2); + + ConstructNewCallInst(NewFn, CI, Operands, 3); + break; + } + case Intrinsic::x86_mmx_pextr_w: { + Value *Operands[2]; + + // Cast the operands to the X86 MMX type. + Operands[0] = new BitCastInst(CI->getArgOperand(0), + NewFn->getFunctionType()->getParamType(0), + "upgraded.", CI); + Operands[1] = CI->getArgOperand(1); + + ConstructNewCallInst(NewFn, CI, Operands, 2); + break; + } + case Intrinsic::x86_mmx_pinsr_w: { + Value *Operands[3]; + + // Cast the operands to the X86 MMX type. + Operands[0] = new BitCastInst(CI->getArgOperand(0), + NewFn->getFunctionType()->getParamType(0), + "upgraded.", CI); + Operands[1] = CI->getArgOperand(1); + Operands[2] = CI->getArgOperand(2); + + ConstructNewCallInst(NewFn, CI, Operands, 3); + break; + } + case Intrinsic::x86_sse_pshuf_w: { + IRBuilder<> Builder(C); + Builder.SetInsertPoint(CI->getParent(), CI); + + // Cast the operand to the X86 MMX type. + Value *Operands[2]; + Operands[0] = + Builder.CreateBitCast(CI->getArgOperand(0), + NewFn->getFunctionType()->getParamType(0), + "upgraded."); + Operands[1] = + Builder.CreateTrunc(CI->getArgOperand(1), + Type::getInt8Ty(C), + "upgraded."); + + ConstructNewCallInst(NewFn, CI, Operands, 2); + break; + } + +#if 0 + case Intrinsic::x86_mmx_cvtsi32_si64: { + // The return type needs to be changed. + Value *Operands[1]; + Operands[0] = CI->getArgOperand(0); + ConstructNewCallInst(NewFn, CI, Operands, 1); + break; + } + case Intrinsic::x86_mmx_cvtsi64_si32: { + Value *Operands[1]; + + // Cast the operand to the X86 MMX type. + Operands[0] = new BitCastInst(CI->getArgOperand(0), + NewFn->getFunctionType()->getParamType(0), + "upgraded.", CI); + + ConstructNewCallInst(NewFn, CI, Operands, 1); + break; + } + case Intrinsic::x86_mmx_vec_init_b: + case Intrinsic::x86_mmx_vec_init_w: + case Intrinsic::x86_mmx_vec_init_d: { + // The return type needs to be changed. + Value *Operands[8]; + unsigned NumOps = 0; + + switch (NewFn->getIntrinsicID()) { + default: break; + case Intrinsic::x86_mmx_vec_init_b: NumOps = 8; break; + case Intrinsic::x86_mmx_vec_init_w: NumOps = 4; break; + case Intrinsic::x86_mmx_vec_init_d: NumOps = 2; break; + } + + switch (NewFn->getIntrinsicID()) { + default: break; + case Intrinsic::x86_mmx_vec_init_b: + Operands[7] = CI->getArgOperand(7); + Operands[6] = CI->getArgOperand(6); + Operands[5] = CI->getArgOperand(5); + Operands[4] = CI->getArgOperand(4); + // FALLTHRU + case Intrinsic::x86_mmx_vec_init_w: + Operands[3] = CI->getArgOperand(3); + Operands[2] = CI->getArgOperand(2); + // FALLTHRU + case Intrinsic::x86_mmx_vec_init_d: + Operands[1] = CI->getArgOperand(1); + Operands[0] = CI->getArgOperand(0); + break; + } + + ConstructNewCallInst(NewFn, CI, Operands, NumOps); + break; + } + case Intrinsic::x86_mmx_vec_ext_d: { + Value *Operands[2]; + + // Cast the operand to the X86 MMX type. + Operands[0] = new BitCastInst(CI->getArgOperand(0), + NewFn->getFunctionType()->getParamType(0), + "upgraded.", CI); + Operands[1] = CI->getArgOperand(1); + + ConstructNewCallInst(NewFn, CI, Operands, 2); + break; + } +#endif + case Intrinsic::ctlz: case Intrinsic::ctpop: case Intrinsic::cttz: { diff --git a/lib/VMCore/BasicBlock.cpp b/lib/VMCore/BasicBlock.cpp index 8ad53736c993..955a0285b260 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 1388c93cce39..1abd031dae4e 100644 --- a/lib/VMCore/CMakeLists.txt +++ b/lib/VMCore/CMakeLists.txt @@ -1,3 +1,5 @@ +set(LLVM_REQUIRES_RTTI 1) + add_llvm_library(LLVMCore AsmWriter.cpp Attributes.cpp @@ -28,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 9a91dafab2ff..573efb7e5731 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 d2dbbdd74c24..0ecd7b49a48e 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 16eaca81048b..246fde1569ae 100644 --- a/lib/VMCore/Constants.cpp +++ b/lib/VMCore/Constants.cpp @@ -40,22 +40,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 +72,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 +89,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 +262,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 @@ -265,20 +327,16 @@ ConstantInt::ConstantInt(const IntegerType *Ty, const APInt& V) 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) { 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; } @@ -297,14 +355,14 @@ ConstantInt *ConstantInt::get(LLVMContext &Context, const APInt& V) { return Slot; } -Constant* ConstantInt::get(const Type* Ty, uint64_t V, bool 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 +380,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 +388,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 +419,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 +431,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 +446,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 +460,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 +568,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 +580,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)); @@ -558,7 +616,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 +628,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,8 +637,8 @@ 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); @@ -592,23 +650,22 @@ ConstantVector::ConstantVector(const VectorType *T, 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 +687,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 +818,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 +1040,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 +1247,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 +1488,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 +1498,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 +1512,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 +1553,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 +1574,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) { +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 getGetElementPtrTy(PointerType::get(Ty, As), C, Idxs, NumIdx); + return getGetElementPtrTy(PointerType::get(Ty, As), C, Idxs, NumIdx,InBounds); } -Constant *ConstantExpr::getInBoundsGetElementPtr(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 getInBoundsGetElementPtrTy(PointerType::get(Ty, As), C, Idxs, NumIdx); -} - -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 +1772,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 +2108,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 1c04c3e1987e..ffc673fac0da 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 5aad19dd2a4a..35c3a2e92587 100644 --- a/lib/VMCore/Core.cpp +++ b/lib/VMCore/Core.cpp @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// // -// This file implements the C bindings for libLLVMCore.a, which implements -// the LLVM intermediate representation. +// This file implements the common infrastructure (including the C bindings) +// for libLLVMCore.a, which implements the LLVM intermediate representation. // //===----------------------------------------------------------------------===// @@ -28,12 +28,24 @@ #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> using namespace llvm; +void llvm::initializeCore(PassRegistry &Registry) { + initializeDominatorTreePass(Registry); + initializePrintModulePassPass(Registry); + initializePrintFunctionPassPass(Registry); + initializeVerifierPass(Registry); + initializePreVerifierPass(Registry); +} + +void LLVMInitializeCore(LLVMPassRegistryRef R) { + initializeCore(*unwrap(R)); +} /*===-- Error handling ----------------------------------------------------===*/ @@ -116,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(); } @@ -126,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) ....................................--*/ @@ -164,6 +186,8 @@ LLVMTypeKind LLVMGetTypeKind(LLVMTypeRef Ty) { return LLVMOpaqueTypeKind; case Type::VectorTyID: return LLVMVectorTypeKind; + case Type::X86_MMXTyID: + return LLVMX86_MMXTypeKind; } } @@ -232,6 +256,9 @@ LLVMTypeRef LLVMFP128TypeInContext(LLVMContextRef C) { LLVMTypeRef LLVMPPCFP128TypeInContext(LLVMContextRef C) { return (LLVMTypeRef) Type::getPPC_FP128Ty(*unwrap(C)); } +LLVMTypeRef LLVMX86MMXTypeInContext(LLVMContextRef C) { + return (LLVMTypeRef) Type::getX86_MMXTy(*unwrap(C)); +} LLVMTypeRef LLVMFloatType(void) { return LLVMFloatTypeInContext(LLVMGetGlobalContext()); @@ -248,6 +275,9 @@ LLVMTypeRef LLVMFP128Type(void) { LLVMTypeRef LLVMPPCFP128Type(void) { return LLVMPPCFP128TypeInContext(LLVMGetGlobalContext()); } +LLVMTypeRef LLVMX86MMXType(void) { + return LLVMX86MMXTypeInContext(LLVMGetGlobalContext()); +} /*--.. Operations on function types ........................................--*/ @@ -527,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), @@ -567,7 +605,7 @@ LLVMValueRef LLVMConstStringInContext(LLVMContextRef C, const char *Str, LLVMBool DontNullTerminate) { /* Inverted the sense of AddNull because ', 0)' is a better mnemonic for null termination than ', 1)'. */ - return wrap(ConstantArray::get(*unwrap(C), std::string(Str, Length), + return wrap(ConstantArray::get(*unwrap(C), StringRef(Str, Length), DontNullTerminate == 0)); } LLVMValueRef LLVMConstStructInContext(LLVMContextRef C, @@ -595,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 ................................................--*/ @@ -613,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))); } @@ -690,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))); } @@ -791,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)); @@ -826,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))); } @@ -872,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))); } @@ -965,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)); } @@ -2186,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; } @@ -2212,6 +2199,11 @@ void LLVMDisposeMemoryBuffer(LLVMMemoryBufferRef MemBuf) { delete unwrap(MemBuf); } +/*===-- Pass Registry -----------------------------------------------------===*/ + +LLVMPassRegistryRef LLVMGetGlobalPassRegistry(void) { + return wrap(PassRegistry::getPassRegistry()); +} /*===-- Pass Manager ------------------------------------------------------===*/ diff --git a/lib/VMCore/Dominators.cpp b/lib/VMCore/Dominators.cpp index f3dad824461d..c374b067d72c 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. // //===----------------------------------------------------------------------===// @@ -53,7 +53,7 @@ TEMPLATE_INSTANTIATION(class llvm::DominatorTreeBase<BasicBlock>); char DominatorTree::ID = 0; INITIALIZE_PASS(DominatorTree, "domtree", - "Dominator Tree Construction", true, true); + "Dominator Tree Construction", true, true) bool DominatorTree::runOnFunction(Function &F) { DT->recalculate(F); @@ -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,263 +105,3 @@ bool DominatorTree::dominates(const Instruction *A, const Instruction *B) const{ return &*I == A; } - - - -//===----------------------------------------------------------------------===// -// DominanceFrontier Implementation -//===----------------------------------------------------------------------===// - -char DominanceFrontier::ID = 0; -INITIALIZE_PASS(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 8f94efc6673a..00d1d7873247 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 96716eeb349b..60000ad1b50e 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 c1b783c75210..595dea470bc3 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/InlineAsm.cpp b/lib/VMCore/InlineAsm.cpp index 69f713b2c42c..e4f99f09a5c2 100644 --- a/lib/VMCore/InlineAsm.cpp +++ b/lib/VMCore/InlineAsm.cpp @@ -47,26 +47,54 @@ InlineAsm::InlineAsm(const PointerType *Ty, const std::string &asmString, } void InlineAsm::destroyConstant() { + getRawType()->getContext().pImpl->InlineAsms.remove(this); delete this; } const FunctionType *InlineAsm::getFunctionType() const { return cast<FunctionType>(getType()->getElementType()); } + +///Default constructor. +InlineAsm::ConstraintInfo::ConstraintInfo() : + Type(isInput), isEarlyClobber(false), + MatchingInput(-1), isCommutative(false), + isIndirect(false), isMultipleAlternative(false), + currentAlternativeIndex(0) { +} + +/// Copy constructor. +InlineAsm::ConstraintInfo::ConstraintInfo(const ConstraintInfo &other) : + Type(other.Type), isEarlyClobber(other.isEarlyClobber), + MatchingInput(other.MatchingInput), isCommutative(other.isCommutative), + isIndirect(other.isIndirect), Codes(other.Codes), + isMultipleAlternative(other.isMultipleAlternative), + multipleAlternatives(other.multipleAlternatives), + currentAlternativeIndex(other.currentAlternativeIndex) { +} /// Parse - Analyze the specified string (e.g. "==&{eax}") and fill in the /// fields in this structure. If the constraint string is not understood, /// return true, otherwise return false. bool InlineAsm::ConstraintInfo::Parse(StringRef Str, - std::vector<InlineAsm::ConstraintInfo> &ConstraintsSoFar) { + InlineAsm::ConstraintInfoVector &ConstraintsSoFar) { StringRef::iterator I = Str.begin(), E = Str.end(); + unsigned multipleAlternativeCount = Str.count('|') + 1; + unsigned multipleAlternativeIndex = 0; + ConstraintCodeVector *pCodes = &Codes; // Initialize + isMultipleAlternative = (multipleAlternativeCount > 1 ? true : false); + if (isMultipleAlternative) { + multipleAlternatives.resize(multipleAlternativeCount); + pCodes = &multipleAlternatives[0].Codes; + } Type = isInput; isEarlyClobber = false; MatchingInput = -1; isCommutative = false; isIndirect = false; + currentAlternativeIndex = 0; // Parse prefixes. if (*I == '~') { @@ -120,15 +148,15 @@ bool InlineAsm::ConstraintInfo::Parse(StringRef Str, // Find the end of the register name. StringRef::iterator ConstraintEnd = std::find(I+1, E, '}'); if (ConstraintEnd == E) return true; // "{foo" - Codes.push_back(std::string(I, ConstraintEnd+1)); + pCodes->push_back(std::string(I, ConstraintEnd+1)); I = ConstraintEnd+1; } else if (isdigit(*I)) { // Matching Constraint // Maximal munch numbers. StringRef::iterator NumStart = I; while (I != E && isdigit(*I)) ++I; - Codes.push_back(std::string(NumStart, I)); - unsigned N = atoi(Codes.back().c_str()); + pCodes->push_back(std::string(NumStart, I)); + unsigned N = atoi(pCodes->back().c_str()); // Check that this is a valid matching constraint! if (N >= ConstraintsSoFar.size() || ConstraintsSoFar[N].Type != isOutput|| Type != isInput) @@ -136,14 +164,26 @@ bool InlineAsm::ConstraintInfo::Parse(StringRef Str, // If Operand N already has a matching input, reject this. An output // can't be constrained to the same value as multiple inputs. - if (ConstraintsSoFar[N].hasMatchingInput()) - return true; - - // Note that operand #n has a matching input. - ConstraintsSoFar[N].MatchingInput = ConstraintsSoFar.size(); + if (isMultipleAlternative) { + InlineAsm::SubConstraintInfo &scInfo = + ConstraintsSoFar[N].multipleAlternatives[multipleAlternativeIndex]; + if (scInfo.MatchingInput != -1) + return true; + // Note that operand #n has a matching input. + scInfo.MatchingInput = ConstraintsSoFar.size(); + } else { + if (ConstraintsSoFar[N].hasMatchingInput()) + return true; + // Note that operand #n has a matching input. + ConstraintsSoFar[N].MatchingInput = ConstraintsSoFar.size(); + } + } else if (*I == '|') { + multipleAlternativeIndex++; + pCodes = &multipleAlternatives[multipleAlternativeIndex].Codes; + ++I; } else { // Single letter constraint. - Codes.push_back(std::string(I, I+1)); + pCodes->push_back(std::string(I, I+1)); ++I; } } @@ -151,9 +191,21 @@ bool InlineAsm::ConstraintInfo::Parse(StringRef Str, return false; } -std::vector<InlineAsm::ConstraintInfo> +/// selectAlternative - Point this constraint to the alternative constraint +/// indicated by the index. +void InlineAsm::ConstraintInfo::selectAlternative(unsigned index) { + if (index < multipleAlternatives.size()) { + currentAlternativeIndex = index; + InlineAsm::SubConstraintInfo &scInfo = + multipleAlternatives[currentAlternativeIndex]; + MatchingInput = scInfo.MatchingInput; + Codes = scInfo.Codes; + } +} + +InlineAsm::ConstraintInfoVector InlineAsm::ParseConstraints(StringRef Constraints) { - std::vector<ConstraintInfo> Result; + ConstraintInfoVector Result; // Scan the constraints string. for (StringRef::iterator I = Constraints.begin(), @@ -183,13 +235,12 @@ InlineAsm::ParseConstraints(StringRef Constraints) { return Result; } - /// Verify - Verify that the specified constraint string is reasonable for the /// specified function type, and otherwise validate the constraint string. bool InlineAsm::Verify(const FunctionType *Ty, StringRef ConstStr) { if (Ty->isVarArg()) return false; - std::vector<ConstraintInfo> Constraints = ParseConstraints(ConstStr); + ConstraintInfoVector Constraints = ParseConstraints(ConstStr); // Error parsing constraints. if (Constraints.empty() && !ConstStr.empty()) return false; diff --git a/lib/VMCore/Instruction.cpp b/lib/VMCore/Instruction.cpp index 05bed4c64316..2c8b8b23b18e 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; } @@ -398,25 +395,10 @@ bool Instruction::isSafeToSpeculativelyExecute() const { return Op && !Op->isNullValue() && !Op->isAllOnesValue(); } case Load: { - if (cast<LoadInst>(this)->isVolatile()) + const LoadInst *LI = cast<LoadInst>(this); + if (LI->isVolatile()) return false; - // Note that it is not safe to speculate into a malloc'd region because - // malloc may return null. - // It's also not safe to follow a bitcast, for example: - // bitcast i8* (alloca i8) to i32* - // would result in a 4-byte load from a 1-byte alloca. - Value *Op0 = getOperand(0); - if (GEPOperator *GEP = dyn_cast<GEPOperator>(Op0)) { - // TODO: it's safe to do this for any GEP with constant indices that - // compute inside the allocated type, but not for any inbounds gep. - if (GEP->hasAllZeroIndices()) - Op0 = GEP->getPointerOperand(); - } - if (isa<AllocaInst>(Op0)) - return true; - if (GlobalVariable *GV = dyn_cast<GlobalVariable>(getOperand(0))) - return !GV->hasExternalWeakLinkage(); - return false; + return LI->getPointerOperand()->isDereferenceablePointer(); } case Call: return false; // The called function could have undefined behavior or diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp index 401802ed13d5..d1290281cb1a 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(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); } @@ -899,7 +824,7 @@ void AllocaInst::setAlignment(unsigned Align) { bool AllocaInst::isArrayAllocation() const { if (ConstantInt *CI = dyn_cast<ConstantInt>(getOperand(0))) - return CI->getZExtValue() != 1; + return !CI->isOne(); return true; } @@ -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(); } //===----------------------------------------------------------------------===// @@ -2360,6 +2308,8 @@ bool CastInst::isCastable(const Type *SrcTy, const Type *DestTy) { } else { // Casting from something else return false; } + } else if (DestTy->isX86_MMXTy()) { + return SrcBits == 64; } else { // Casting to something else return false; } @@ -2441,6 +2391,10 @@ CastInst::getCastOpcode( return BitCast; // vector -> vector } else if (DestPTy->getBitWidth() == SrcBits) { return BitCast; // float/int -> vector + } else if (SrcTy->isX86_MMXTy()) { + assert(DestPTy->getBitWidth()==64 && + "Casting X86_MMX to vector of wrong width"); + return BitCast; // MMX to 64-bit vector } else { assert(!"Illegal cast to vector (wrong type or size)"); } @@ -2452,6 +2406,14 @@ CastInst::getCastOpcode( } else { assert(!"Casting pointer to other than pointer or int"); } + } else if (DestTy->isX86_MMXTy()) { + if (isa<VectorType>(SrcTy)) { + assert(cast<VectorType>(SrcTy)->getBitWidth() == 64 && + "Casting vector of wrong width to X86_MMX"); + return BitCast; // 64-bit vector to MMX + } else { + assert(!"Illegal cast to X86_MMX"); + } } else { assert(!"Casting to type that is not first-class"); } @@ -2754,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(); } @@ -2974,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); @@ -2992,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 @@ -3003,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]; } @@ -3018,7 +2981,7 @@ SwitchInst::SwitchInst(const SwitchInst &SI) } SwitchInst::~SwitchInst() { - dropHungoffUses(OperandList); + dropHungoffUses(); } @@ -3046,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. @@ -3089,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); } @@ -3104,7 +3063,7 @@ void SwitchInst::setSuccessorV(unsigned idx, BasicBlock *B) { } //===----------------------------------------------------------------------===// -// SwitchInst Implementation +// IndirectBrInst Implementation //===----------------------------------------------------------------------===// void IndirectBrInst::init(Value *Address, unsigned NumDests) { @@ -3144,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, @@ -3172,7 +3131,7 @@ IndirectBrInst::IndirectBrInst(const IndirectBrInst &IBI) } IndirectBrInst::~IndirectBrInst() { - dropHungoffUses(OperandList); + dropHungoffUses(); } /// addDestination - Add a destination. @@ -3346,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 563c651315a3..1bd497d05d4e 100644 --- a/lib/VMCore/LLVMContext.cpp +++ b/lib/VMCore/LLVMContext.cpp @@ -19,6 +19,7 @@ #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/SourceMgr.h" #include "LLVMContextImpl.h" +#include <cctype> using namespace llvm; static ManagedStatic<LLVMContext> GlobalContext; @@ -28,25 +29,42 @@ LLVMContext& llvm::getGlobalContext() { } LLVMContext::LLVMContext() : pImpl(new LLVMContextImpl(*this)) { - // Create the first metadata kind, which is always 'dbg'. + // 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. unsigned DbgID = getMDKindID("dbg"); assert(DbgID == MD_dbg && "dbg kind id drifted"); (void)DbgID; + + // Create the 'tbaa' metadata kind. + unsigned TBAAID = getMDKindID("tbaa"); + assert(TBAAID == MD_tbaa && "tbaa kind id drifted"); (void)TBAAID; } LLVMContext::~LLVMContext() { delete pImpl; } +void LLVMContext::addModule(Module *M) { + pImpl->OwnedModules.insert(M); +} + +void LLVMContext::removeModule(Module *M) { + pImpl->OwnedModules.erase(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; } @@ -76,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); } //===----------------------------------------------------------------------===// @@ -94,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.cpp b/lib/VMCore/LLVMContextImpl.cpp index 93a075f0fccb..ccb8dc500fcd 100644 --- a/lib/VMCore/LLVMContextImpl.cpp +++ b/lib/VMCore/LLVMContextImpl.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "LLVMContextImpl.h" +#include "llvm/Module.h" #include <algorithm> using namespace llvm; @@ -25,6 +26,7 @@ LLVMContextImpl::LLVMContextImpl(LLVMContext &C) X86_FP80Ty(C, Type::X86_FP80TyID), FP128Ty(C, Type::FP128TyID), PPC_FP128Ty(C, Type::PPC_FP128TyID), + X86_MMXTy(C, Type::X86_MMXTyID), Int1Ty(C, 1), Int8Ty(C, 8), Int16Ty(C, 16), @@ -51,6 +53,15 @@ struct DropReferences { } LLVMContextImpl::~LLVMContextImpl() { + // NOTE: We need to delete the contents of OwnedModules, but we have to + // duplicate it into a temporary vector, because the destructor of Module + // will try to remove itself from OwnedModules set. This would cause + // iterator invalidation if we iterated on the set directly. + std::vector<Module*> Modules(OwnedModules.begin(), OwnedModules.end()); + for (std::vector<Module*>::iterator I = Modules.begin(), E = Modules.end(); + I != E; ++I) + delete *I; + std::for_each(ExprConstants.map_begin(), ExprConstants.map_end(), DropReferences()); std::for_each(ArrayConstants.map_begin(), ArrayConstants.map_end(), @@ -90,7 +101,7 @@ LLVMContextImpl::~LLVMContextImpl() { MDNodes.push_back(&*I); } MDNodes.append(NonUniquedMDNodes.begin(), NonUniquedMDNodes.end()); - for (SmallVector<MDNode*, 8>::iterator I = MDNodes.begin(), + for (SmallVectorImpl<MDNode *>::iterator I = MDNodes.begin(), E = MDNodes.end(); I != E; ++I) { (*I)->destroy(); } diff --git a/lib/VMCore/LLVMContextImpl.h b/lib/VMCore/LLVMContextImpl.h index 51b2992898c0..23971aafa74d 100644 --- a/lib/VMCore/LLVMContextImpl.h +++ b/lib/VMCore/LLVMContextImpl.h @@ -115,7 +115,12 @@ public: class LLVMContextImpl { public: - void *InlineAsmDiagHandler, *InlineAsmDiagContext; + /// OwnedModules - The set of modules instantiated in this context, and which + /// will be automatically deleted if this context is deleted. + SmallPtrSet<Module*, 4> OwnedModules; + + LLVMContext::InlineAsmDiagHandlerTy InlineAsmDiagHandler; + void *InlineAsmDiagContext; typedef DenseMap<DenseMapAPIntKeyInfo::KeyTy, ConstantInt*, DenseMapAPIntKeyInfo> IntMapTy; @@ -170,6 +175,7 @@ public: const Type X86_FP80Ty; const Type FP128Ty; const Type PPC_FP128Ty; + const Type X86_MMXTy; const IntegerType Int1Ty; const IntegerType Int8Ty; const IntegerType Int16Ty; diff --git a/lib/VMCore/LeakDetector.cpp b/lib/VMCore/LeakDetector.cpp index a44f61d822ee..f6651e93e273 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 da69c43ff735..0b8e8dfa8b36 100644 --- a/lib/VMCore/Metadata.cpp +++ b/lib/VMCore/Metadata.cpp @@ -339,17 +339,14 @@ void MDNode::replaceOperand(MDNodeOperand *Op, Value *To) { // Now that the node is out of the folding set, get ready to reinsert it. // First, check to see if another node with the same operands already exists - // in the set. If it doesn't exist, this returns the position to insert it. + // in the set. If so, then this node is redundant. FoldingSetNodeID ID; Profile(ID); void *InsertPoint; - MDNode *N = pImpl->MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint); - - if (N) { - N->replaceAllUsesWith(this); - N->destroy(); - N = pImpl->MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint); - assert(N == 0 && "shouldn't be in the map now!"); (void)N; + if (MDNode *N = pImpl->MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint)) { + replaceAllUsesWith(N); + destroy(); + return; } // InsertPoint will have been set by the FindNodeOrInsertPos call. diff --git a/lib/VMCore/Module.cpp b/lib/VMCore/Module.cpp index d7ddf96cb070..341e527acb5b 100644 --- a/lib/VMCore/Module.cpp +++ b/lib/VMCore/Module.cpp @@ -62,9 +62,11 @@ Module::Module(StringRef MID, LLVMContext& C) ValSymTab = new ValueSymbolTable(); TypeSymTab = new TypeSymbolTable(); NamedMDSymTab = new StringMap<NamedMDNode *>(); + Context.addModule(this); } Module::~Module() { + Context.removeModule(this); dropAllReferences(); GlobalList.clear(); FunctionList.clear(); diff --git a/lib/VMCore/Pass.cpp b/lib/VMCore/Pass.cpp index a7d7f61dd762..9afc54063321 100644 --- a/lib/VMCore/Pass.cpp +++ b/lib/VMCore/Pass.cpp @@ -213,7 +213,6 @@ RegisterAGBase::RegisterAGBase(const char *Name, const void *InterfaceID, *this, isDefault); } - //===----------------------------------------------------------------------===// // PassRegistrationListener implementation // diff --git a/lib/VMCore/PassManager.cpp b/lib/VMCore/PassManager.cpp index ab4d4e55c750..8bfef9855ca2 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> @@ -497,9 +497,14 @@ PMTopLevelManager::PMTopLevelManager(PMDataManager *PMDM) { } /// Set pass P as the last user of the given analysis passes. -void PMTopLevelManager::setLastUser(SmallVector<Pass *, 12> &AnalysisPasses, - Pass *P) { - for (SmallVector<Pass *, 12>::iterator I = AnalysisPasses.begin(), +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; LastUser[AP] = P; @@ -507,20 +512,47 @@ void PMTopLevelManager::setLastUser(SmallVector<Pass *, 12> &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; } } } /// Collect passes whose last user is P -void PMTopLevelManager::collectLastUses(SmallVector<Pass *, 12> &LastUses, +void PMTopLevelManager::collectLastUses(SmallVectorImpl<Pass *> &LastUses, Pass *P) { DenseMap<Pass *, SmallPtrSet<Pass *, 8> >::iterator DMI = InversedLastUser.find(P); @@ -612,41 +644,40 @@ void PMTopLevelManager::schedulePass(Pass *P) { /// then return NULL. Pass *PMTopLevelManager::findAnalysisPass(AnalysisID AID) { - Pass *P = NULL; // Check pass managers - for (SmallVector<PMDataManager *, 8>::iterator I = PassManagers.begin(), - E = PassManagers.end(); P == NULL && I != E; ++I) { - PMDataManager *PMD = *I; - P = PMD->findAnalysisPass(AID, false); - } + for (SmallVectorImpl<PMDataManager *>::iterator I = PassManagers.begin(), + E = PassManagers.end(); I != E; ++I) + if (Pass *P = (*I)->findAnalysisPass(AID, false)) + return P; // Check other pass managers - for (SmallVector<PMDataManager *, 8>::iterator + for (SmallVectorImpl<PMDataManager *>::iterator I = IndirectPassManagers.begin(), - E = IndirectPassManagers.end(); P == NULL && I != E; ++I) - P = (*I)->findAnalysisPass(AID, false); - - for (SmallVector<ImmutablePass *, 8>::iterator I = ImmutablePasses.begin(), - E = ImmutablePasses.end(); P == NULL && I != E; ++I) { + E = IndirectPassManagers.end(); I != E; ++I) + if (Pass *P = (*I)->findAnalysisPass(AID, false)) + return P; + + // Check the immutable passes. Iterate in reverse order so that we find + // the most recently registered passes first. + for (SmallVector<ImmutablePass *, 8>::reverse_iterator I = + ImmutablePasses.rbegin(), E = ImmutablePasses.rend(); I != E; ++I) { AnalysisID PI = (*I)->getPassID(); if (PI == AID) - P = *I; + return *I; // If Pass not found then check the interfaces implemented by Immutable Pass - if (!P) { - const PassInfo *PassInf = - PassRegistry::getPassRegistry()->getPassInfo(PI); - const std::vector<const PassInfo*> &ImmPI = - PassInf->getInterfacesImplemented(); - for (std::vector<const PassInfo*>::const_iterator II = ImmPI.begin(), - EE = ImmPI.end(); II != EE; ++II) { - if ((*II)->getTypeInfo() == AID) - P = *I; - } + const PassInfo *PassInf = + PassRegistry::getPassRegistry()->getPassInfo(PI); + const std::vector<const PassInfo*> &ImmPI = + PassInf->getInterfacesImplemented(); + for (std::vector<const PassInfo*>::const_iterator II = ImmPI.begin(), + EE = ImmPI.end(); II != EE; ++II) { + if ((*II)->getTypeInfo() == AID) + return *I; } } - return P; + return 0; } // Print passes managed by this top level manager. @@ -675,6 +706,12 @@ void PMTopLevelManager::dumpArguments() const { return; dbgs() << "Pass Arguments: "; + for (SmallVector<ImmutablePass *, 8>::const_iterator I = + ImmutablePasses.begin(), E = ImmutablePasses.end(); I != E; ++I) + if (const PassInfo *PI = + PassRegistry::getPassRegistry()->getPassInfo((*I)->getPassID())) + if (!PI->isAnalysisGroup()) + dbgs() << " -" << PI->getPassArgument(); for (SmallVector<PMDataManager *, 8>::const_iterator I = PassManagers.begin(), E = PassManagers.end(); I != E; ++I) (*I)->dumpPassArguments(); @@ -682,12 +719,12 @@ void PMTopLevelManager::dumpArguments() const { } void PMTopLevelManager::initializeAllAnalysisInfo() { - for (SmallVector<PMDataManager *, 8>::iterator I = PassManagers.begin(), + for (SmallVectorImpl<PMDataManager *>::iterator I = PassManagers.begin(), E = PassManagers.end(); I != E; ++I) (*I)->initializeAnalysisInfo(); // Initailize other pass managers - for (SmallVector<PMDataManager *, 8>::iterator + for (SmallVectorImpl<PMDataManager *>::iterator I = IndirectPassManagers.begin(), E = IndirectPassManagers.end(); I != E; ++I) (*I)->initializeAnalysisInfo(); @@ -708,11 +745,11 @@ void PMTopLevelManager::initializeAllAnalysisInfo() { /// Destructor PMTopLevelManager::~PMTopLevelManager() { - for (SmallVector<PMDataManager *, 8>::iterator I = PassManagers.begin(), + for (SmallVectorImpl<PMDataManager *>::iterator I = PassManagers.begin(), E = PassManagers.end(); I != E; ++I) delete *I; - for (SmallVector<ImmutablePass *, 8>::iterator + for (SmallVectorImpl<ImmutablePass *>::iterator I = ImmutablePasses.begin(), E = ImmutablePasses.end(); I != E; ++I) delete *I; @@ -749,7 +786,7 @@ bool PMDataManager::preserveHigherLevelAnalysis(Pass *P) { return true; const AnalysisUsage::VectorType &PreservedSet = AnUsage->getPreservedSet(); - for (SmallVector<Pass *, 8>::iterator I = HigherLevelAnalysis.begin(), + for (SmallVectorImpl<Pass *>::iterator I = HigherLevelAnalysis.begin(), E = HigherLevelAnalysis.end(); I != E; ++I) { Pass *P1 = *I; if (P1->getAsImmutablePass() == 0 && @@ -849,7 +886,7 @@ void PMDataManager::removeDeadPasses(Pass *P, StringRef Msg, dbgs() << " Free these instances\n"; } - for (SmallVector<Pass *, 12>::iterator I = DeadPasses.begin(), + for (SmallVectorImpl<Pass *>::iterator I = DeadPasses.begin(), E = DeadPasses.end(); I != E; ++I) freePass(*I, Msg, DBG_STR); } @@ -910,7 +947,7 @@ void PMDataManager::add(Pass *P, bool ProcessAnalysis) { collectRequiredAnalysis(RequiredPasses, ReqAnalysisNotAvailable, P); - for (SmallVector<Pass *, 8>::iterator I = RequiredPasses.begin(), + for (SmallVectorImpl<Pass *>::iterator I = RequiredPasses.begin(), E = RequiredPasses.end(); I != E; ++I) { Pass *PRequired = *I; unsigned RDepth = 0; @@ -944,7 +981,7 @@ void PMDataManager::add(Pass *P, bool ProcessAnalysis) { } // Now, take care of required analyses that are not available. - for (SmallVector<AnalysisID, 8>::iterator + for (SmallVectorImpl<AnalysisID>::iterator I = ReqAnalysisNotAvailable.begin(), E = ReqAnalysisNotAvailable.end() ;I != E; ++I) { const PassInfo *PI = PassRegistry::getPassRegistry()->getPassInfo(*I); @@ -965,8 +1002,8 @@ void PMDataManager::add(Pass *P, bool ProcessAnalysis) { /// Populate RP with analysis pass that are required by /// pass P and are available. Populate RP_NotAvail with analysis /// pass that are required by pass P but are not available. -void PMDataManager::collectRequiredAnalysis(SmallVector<Pass *, 8>&RP, - SmallVector<AnalysisID, 8> &RP_NotAvail, +void PMDataManager::collectRequiredAnalysis(SmallVectorImpl<Pass *> &RP, + SmallVectorImpl<AnalysisID> &RP_NotAvail, Pass *P) { AnalysisUsage *AnUsage = TPM->findAnalysisUsage(P); const AnalysisUsage::VectorType &RequiredSet = AnUsage->getRequiredSet(); @@ -1038,7 +1075,7 @@ void PMDataManager::dumpLastUses(Pass *P, unsigned Offset) const{ TPM->collectLastUses(LUses, P); - for (SmallVector<Pass *, 12>::iterator I = LUses.begin(), + for (SmallVectorImpl<Pass *>::iterator I = LUses.begin(), E = LUses.end(); I != E; ++I) { llvm::dbgs() << "--" << std::string(Offset*2, ' '); (*I)->dumpPassStructure(0); @@ -1046,7 +1083,7 @@ void PMDataManager::dumpLastUses(Pass *P, unsigned Offset) const{ } void PMDataManager::dumpPassArguments() const { - for (SmallVector<Pass *, 8>::const_iterator I = PassVector.begin(), + for (SmallVectorImpl<Pass *>::const_iterator I = PassVector.begin(), E = PassVector.end(); I != E; ++I) { if (PMDataManager *PMD = (*I)->getAsPMDataManager()) PMD->dumpPassArguments(); @@ -1087,6 +1124,9 @@ void PMDataManager::dumpPassInfo(Pass *P, enum PassDebuggingString S1, case ON_MODULE_MSG: dbgs() << "' on Module '" << Msg << "'...\n"; break; + case ON_REGION_MSG: + dbgs() << "' on Region '" << Msg << "'...\n"; + break; case ON_LOOP_MSG: dbgs() << "' on Loop '" << Msg << "'...\n"; break; @@ -1163,7 +1203,7 @@ Pass *PMDataManager::getOnTheFlyPass(Pass *P, AnalysisID PI, Function &F) { // Destructor PMDataManager::~PMDataManager() { - for (SmallVector<Pass *, 8>::iterator I = PassVector.begin(), + for (SmallVectorImpl<Pass *>::iterator I = PassVector.begin(), E = PassVector.end(); I != E; ++I) delete *I; } @@ -1563,7 +1603,7 @@ void MPPassManager::addLowerLevelRequiredPass(Pass *P, Pass *RequiredPass) { FPP->add(RequiredPass); // Register P as the last user of RequiredPass. - SmallVector<Pass *, 12> LU; + SmallVector<Pass *, 1> LU; LU.push_back(RequiredPass); FPP->setLastUser(LU, P); } diff --git a/lib/VMCore/PassRegistry.cpp b/lib/VMCore/PassRegistry.cpp index 21dba56aad72..c97a170f501f 100644 --- a/lib/VMCore/PassRegistry.cpp +++ b/lib/VMCore/PassRegistry.cpp @@ -16,93 +16,125 @@ #include "llvm/PassSupport.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/ManagedStatic.h" +#include "llvm/Support/Mutex.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/StringMap.h" +#include <vector> using namespace llvm; -static PassRegistry *PassRegistryObj = 0; -PassRegistry *PassRegistry::getPassRegistry() { - // Use double-checked locking to safely initialize the registrar when - // we're running in multithreaded mode. - PassRegistry* tmp = PassRegistryObj; - if (llvm_is_multithreaded()) { - sys::MemoryFence(); - if (!tmp) { - llvm_acquire_global_lock(); - tmp = PassRegistryObj; - if (!tmp) { - tmp = new PassRegistry(); - sys::MemoryFence(); - PassRegistryObj = tmp; - } - llvm_release_global_lock(); - } - } else if (!tmp) { - PassRegistryObj = new PassRegistry(); - } - - return PassRegistryObj; -} - -namespace { - -// FIXME: We use ManagedCleanup to erase the pass registrar on shutdown. +// FIXME: We use ManagedStatic to erase the pass registrar on shutdown. // Unfortunately, passes are registered with static ctors, and having // llvm_shutdown clear this map prevents successful ressurection after // llvm_shutdown is run. Ideally we should find a solution so that we don't // leak the map, AND can still resurrect after shutdown. -void cleanupPassRegistry(void*) { - if (PassRegistryObj) { - delete PassRegistryObj; - PassRegistryObj = 0; - } +static ManagedStatic<PassRegistry> PassRegistryObj; +PassRegistry *PassRegistry::getPassRegistry() { + return &*PassRegistryObj; } -ManagedCleanup<&cleanupPassRegistry> registryCleanup ATTRIBUTE_USED; +static ManagedStatic<sys::SmartMutex<true> > Lock; + +//===----------------------------------------------------------------------===// +// PassRegistryImpl +// + +namespace { +struct PassRegistryImpl { + /// PassInfoMap - Keep track of the PassInfo object for each registered pass. + typedef DenseMap<const void*, const PassInfo*> MapType; + MapType PassInfoMap; + + typedef StringMap<const PassInfo*> StringMapType; + StringMapType PassInfoStringMap; + + /// AnalysisGroupInfo - Keep track of information for each analysis group. + struct AnalysisGroupInfo { + SmallPtrSet<const PassInfo *, 8> Implementations; + }; + DenseMap<const PassInfo*, AnalysisGroupInfo> AnalysisGroupInfoMap; + + std::vector<const PassInfo*> ToFree; + std::vector<PassRegistrationListener*> Listeners; +}; +} // end anonymous namespace + +void *PassRegistry::getImpl() const { + if (!pImpl) + pImpl = new PassRegistryImpl(); + return pImpl; +} + +//===----------------------------------------------------------------------===// +// Accessors +// + +PassRegistry::~PassRegistry() { + sys::SmartScopedLock<true> Guard(*Lock); + PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(pImpl); + + for (std::vector<const PassInfo*>::iterator I = Impl->ToFree.begin(), + E = Impl->ToFree.end(); I != E; ++I) + delete *I; + + delete Impl; + pImpl = 0; } const PassInfo *PassRegistry::getPassInfo(const void *TI) const { - sys::SmartScopedLock<true> Guard(Lock); - MapType::const_iterator I = PassInfoMap.find(TI); - return I != PassInfoMap.end() ? I->second : 0; + sys::SmartScopedLock<true> Guard(*Lock); + PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl()); + PassRegistryImpl::MapType::const_iterator I = Impl->PassInfoMap.find(TI); + return I != Impl->PassInfoMap.end() ? I->second : 0; } const PassInfo *PassRegistry::getPassInfo(StringRef Arg) const { - sys::SmartScopedLock<true> Guard(Lock); - StringMapType::const_iterator I = PassInfoStringMap.find(Arg); - return I != PassInfoStringMap.end() ? I->second : 0; + sys::SmartScopedLock<true> Guard(*Lock); + PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl()); + PassRegistryImpl::StringMapType::const_iterator + I = Impl->PassInfoStringMap.find(Arg); + return I != Impl->PassInfoStringMap.end() ? I->second : 0; } //===----------------------------------------------------------------------===// // Pass Registration mechanism // -void PassRegistry::registerPass(const PassInfo &PI) { - sys::SmartScopedLock<true> Guard(Lock); +void PassRegistry::registerPass(const PassInfo &PI, bool ShouldFree) { + sys::SmartScopedLock<true> Guard(*Lock); + PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl()); bool Inserted = - PassInfoMap.insert(std::make_pair(PI.getTypeInfo(),&PI)).second; - assert(Inserted && "Pass registered multiple times!"); Inserted=Inserted; - PassInfoStringMap[PI.getPassArgument()] = &PI; + Impl->PassInfoMap.insert(std::make_pair(PI.getTypeInfo(),&PI)).second; + assert(Inserted && "Pass registered multiple times!"); + (void)Inserted; + Impl->PassInfoStringMap[PI.getPassArgument()] = &PI; // Notify any listeners. for (std::vector<PassRegistrationListener*>::iterator - I = Listeners.begin(), E = Listeners.end(); I != E; ++I) + I = Impl->Listeners.begin(), E = Impl->Listeners.end(); I != E; ++I) (*I)->passRegistered(&PI); + + if (ShouldFree) Impl->ToFree.push_back(&PI); } void PassRegistry::unregisterPass(const PassInfo &PI) { - sys::SmartScopedLock<true> Guard(Lock); - MapType::iterator I = PassInfoMap.find(PI.getTypeInfo()); - assert(I != PassInfoMap.end() && "Pass registered but not in map!"); + sys::SmartScopedLock<true> Guard(*Lock); + PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl()); + PassRegistryImpl::MapType::iterator I = + Impl->PassInfoMap.find(PI.getTypeInfo()); + assert(I != Impl->PassInfoMap.end() && "Pass registered but not in map!"); // Remove pass from the map. - PassInfoMap.erase(I); - PassInfoStringMap.erase(PI.getPassArgument()); + Impl->PassInfoMap.erase(I); + Impl->PassInfoStringMap.erase(PI.getPassArgument()); } void PassRegistry::enumerateWith(PassRegistrationListener *L) { - sys::SmartScopedLock<true> Guard(Lock); - for (MapType::const_iterator I = PassInfoMap.begin(), - E = PassInfoMap.end(); I != E; ++I) + sys::SmartScopedLock<true> Guard(*Lock); + PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl()); + for (PassRegistryImpl::MapType::const_iterator I = Impl->PassInfoMap.begin(), + E = Impl->PassInfoMap.end(); I != E; ++I) L->passEnumerate(I->second); } @@ -111,7 +143,8 @@ void PassRegistry::enumerateWith(PassRegistrationListener *L) { void PassRegistry::registerAnalysisGroup(const void *InterfaceID, const void *PassID, PassInfo& Registeree, - bool isDefault) { + bool isDefault, + bool ShouldFree) { PassInfo *InterfaceInfo = const_cast<PassInfo*>(getPassInfo(InterfaceID)); if (InterfaceInfo == 0) { // First reference to Interface, register it now. @@ -126,12 +159,15 @@ void PassRegistry::registerAnalysisGroup(const void *InterfaceID, assert(ImplementationInfo && "Must register pass before adding to AnalysisGroup!"); + sys::SmartScopedLock<true> Guard(*Lock); + // Make sure we keep track of the fact that the implementation implements // the interface. ImplementationInfo->addInterfaceImplemented(InterfaceInfo); - sys::SmartScopedLock<true> Guard(Lock); - AnalysisGroupInfo &AGI = AnalysisGroupInfoMap[InterfaceInfo]; + PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl()); + PassRegistryImpl::AnalysisGroupInfo &AGI = + Impl->AnalysisGroupInfoMap[InterfaceInfo]; assert(AGI.Implementations.count(ImplementationInfo) == 0 && "Cannot add a pass to the same analysis group more than once!"); AGI.Implementations.insert(ImplementationInfo); @@ -143,17 +179,30 @@ void PassRegistry::registerAnalysisGroup(const void *InterfaceID, InterfaceInfo->setNormalCtor(ImplementationInfo->getNormalCtor()); } } + + PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl()); + if (ShouldFree) Impl->ToFree.push_back(&Registeree); } void PassRegistry::addRegistrationListener(PassRegistrationListener *L) { - sys::SmartScopedLock<true> Guard(Lock); - Listeners.push_back(L); + sys::SmartScopedLock<true> Guard(*Lock); + PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl()); + Impl->Listeners.push_back(L); } void PassRegistry::removeRegistrationListener(PassRegistrationListener *L) { - sys::SmartScopedLock<true> Guard(Lock); + sys::SmartScopedLock<true> Guard(*Lock); + + // NOTE: This is necessary, because removeRegistrationListener() can be called + // as part of the llvm_shutdown sequence. Since we have no control over the + // order of that sequence, we need to gracefully handle the case where the + // PassRegistry is destructed before the object that triggers this call. + if (!pImpl) return; + + PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl()); std::vector<PassRegistrationListener*>::iterator I = - std::find(Listeners.begin(), Listeners.end(), L); - assert(I != Listeners.end() && "PassRegistrationListener not registered!"); - Listeners.erase(I); + std::find(Impl->Listeners.begin(), Impl->Listeners.end(), L); + assert(I != Impl->Listeners.end() && + "PassRegistrationListener not registered!"); + Impl->Listeners.erase(I); } diff --git a/lib/VMCore/PrintModulePass.cpp b/lib/VMCore/PrintModulePass.cpp index 2ee49d235963..1f1fbc91bc31 100644 --- a/lib/VMCore/PrintModulePass.cpp +++ b/lib/VMCore/PrintModulePass.cpp @@ -78,10 +78,10 @@ namespace { char PrintModulePass::ID = 0; INITIALIZE_PASS(PrintModulePass, "print-module", - "Print module to stderr", false, false); + "Print module to stderr", false, false) char PrintFunctionPass::ID = 0; INITIALIZE_PASS(PrintFunctionPass, "print-function", - "Print function to stderr", false, false); + "Print function to stderr", false, false) /// createPrintModulePass - Create and return a pass that writes the /// module to the specified raw_ostream. diff --git a/lib/VMCore/Type.cpp b/lib/VMCore/Type.cpp index c55e6267836a..be28ad1f7122 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; @@ -109,6 +109,7 @@ const Type *Type::getPrimitiveType(LLVMContext &C, TypeID IDNumber) { case PPC_FP128TyID : return getPPC_FP128Ty(C); case LabelTyID : return getLabelTy(C); case MetadataTyID : return getMetadataTy(C); + case X86_MMXTyID : return getX86_MMXTy(C); default: return 0; } @@ -172,10 +173,20 @@ bool Type::canLosslesslyBitCastTo(const Type *Ty) const { return false; // Vector -> Vector conversions are always lossless if the two vector types - // have the same size, otherwise not. - if (const VectorType *thisPTy = dyn_cast<VectorType>(this)) + // have the same size, otherwise not. Also, 64-bit vector types can be + // converted to x86mmx. + if (const VectorType *thisPTy = dyn_cast<VectorType>(this)) { if (const VectorType *thatPTy = dyn_cast<VectorType>(Ty)) return thisPTy->getBitWidth() == thatPTy->getBitWidth(); + if (Ty->getTypeID() == Type::X86_MMXTyID && + thisPTy->getBitWidth() == 64) + return true; + } + + if (this->getTypeID() == Type::X86_MMXTyID) + if (const VectorType *thatPTy = dyn_cast<VectorType>(Ty)) + if (thatPTy->getBitWidth() == 64) + return true; // At this point we have only various mismatches of the first class types // remaining and ptr->ptr. Just select the lossless conversions. Everything @@ -192,6 +203,7 @@ unsigned Type::getPrimitiveSizeInBits() const { case Type::X86_FP80TyID: return 80; case Type::FP128TyID: return 128; case Type::PPC_FP128TyID: return 128; + case Type::X86_MMXTyID: return 64; case Type::IntegerTyID: return cast<IntegerType>(this)->getBitWidth(); case Type::VectorTyID: return cast<VectorType>(this)->getBitWidth(); default: return 0; @@ -354,6 +366,10 @@ const Type *Type::getPPC_FP128Ty(LLVMContext &C) { return &C.pImpl->PPC_FP128Ty; } +const Type *Type::getX86_MMXTy(LLVMContext &C) { + return &C.pImpl->X86_MMXTy; +} + const IntegerType *Type::getIntNTy(LLVMContext &C, unsigned N) { return IntegerType::get(C, N); } @@ -398,6 +414,10 @@ const PointerType *Type::getPPC_FP128PtrTy(LLVMContext &C, unsigned AS) { return getPPC_FP128Ty(C)->getPointerTo(AS); } +const PointerType *Type::getX86_MMXPtrTy(LLVMContext &C, unsigned AS) { + return getX86_MMXTy(C)->getPointerTo(AS); +} + const PointerType *Type::getIntNPtrTy(LLVMContext &C, unsigned N, unsigned AS) { return getIntNTy(C, N)->getPointerTo(AS); } @@ -1083,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 << " " @@ -1110,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 5a90917977b0..4694486c41b6 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 fec710b39459..2258b8d985ae 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 000000000000..2f4587debb66 --- /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 b8c677565467..29f6a8094f0b 100644 --- a/lib/VMCore/Value.cpp +++ b/lib/VMCore/Value.cpp @@ -22,6 +22,7 @@ #include "llvm/ValueSymbolTable.h" #include "llvm/ADT/SmallString.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/GetElementPtrTypeIterator.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/LeakDetector.h" #include "llvm/Support/ManagedStatic.h" @@ -254,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. @@ -345,25 +346,62 @@ 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; +/// 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 { + // Note that it is not safe to speculate into a malloc'd region because + // malloc may return null. + // It's also not always safe to follow a bitcast, for example: + // bitcast i8* (alloca i8) to i32* + // would result in a 4-byte load from a 1-byte alloca. Some cases could + // be handled using TargetData to check sizes and alignments though. + + // These are obviously ok. + if (isa<AllocaInst>(this)) return true; + + // Global variables which can't collapse to null are ok. + 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. + if (!GEP->getOperand(0)->isDereferenceablePointer()) + return false; + // Check the indices. + gep_type_iterator GTI = gep_type_begin(GEP); + for (User::const_op_iterator I = GEP->op_begin()+1, + E = GEP->op_end(); I != E; ++I) { + Value *Index = *I; + const Type *Ty = *GTI++; + // Struct indices can't be out of bounds. + if (isa<StructType>(Ty)) + continue; + ConstantInt *CI = dyn_cast<ConstantInt>(Index); + if (!CI) + return false; + // Zero is always ok. + if (CI->isZero()) + continue; + // Check to see that it's within the bounds of an array. + const ArrayType *ATy = dyn_cast<ArrayType>(Ty); + if (!ATy) + return false; + if (CI->getValue().getActiveBits() > 64) + return false; + if (CI->getZExtValue() >= ATy->getNumElements()) + return false; } - assert(V->getType()->isPointerTy() && "Unexpected operand type!"); + // Indices check out; this is dereferenceable. + return true; } - return V; + + // If we don't know, assume the worst. + return false; } /// DoPHITranslation - If this value is a PHI node with CurBB as its parent, @@ -600,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 d2a8ce34ae47..c054ae46f23b 100644 --- a/lib/VMCore/ValueTypes.cpp +++ b/lib/VMCore/ValueTypes.cpp @@ -109,7 +109,8 @@ 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"; case MVT::v8i8: return "v8i8"; @@ -155,6 +156,7 @@ const Type *EVT::getTypeForEVT(LLVMContext &Context) const { case MVT::f80: return Type::getX86_FP80Ty(Context); case MVT::f128: return Type::getFP128Ty(Context); case MVT::ppcf128: return Type::getPPC_FP128Ty(Context); + case MVT::x86mmx: return Type::getX86_MMXTy(Context); case MVT::v2i8: return VectorType::get(Type::getInt8Ty(Context), 2); case MVT::v4i8: return VectorType::get(Type::getInt8Ty(Context), 4); case MVT::v8i8: return VectorType::get(Type::getInt8Ty(Context), 8); @@ -196,6 +198,7 @@ EVT EVT::getEVT(const Type *Ty, bool HandleUnknown){ case Type::FloatTyID: return MVT(MVT::f32); case Type::DoubleTyID: return MVT(MVT::f64); case Type::X86_FP80TyID: return MVT(MVT::f80); + case Type::X86_MMXTyID: return MVT(MVT::x86mmx); case Type::FP128TyID: return MVT(MVT::f128); case Type::PPC_FP128TyID: return MVT(MVT::ppcf128); case Type::PointerTyID: return MVT(MVT::iPTR); diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp index e3ecc979bf12..58ec6fe88d35 100644 --- a/lib/VMCore/Verifier.cpp +++ b/lib/VMCore/Verifier.cpp @@ -72,7 +72,9 @@ namespace { // Anonymous namespace for class struct PreVerifier : public FunctionPass { static char ID; // Pass ID, replacement for typeid - PreVerifier() : FunctionPass(ID) { } + PreVerifier() : FunctionPass(ID) { + initializePreVerifierPass(*PassRegistry::getPassRegistry()); + } virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); @@ -103,8 +105,8 @@ namespace { // Anonymous namespace for class char PreVerifier::ID = 0; INITIALIZE_PASS(PreVerifier, "preverify", "Preliminary module verification", - false, false); -char &PreVerifyID = PreVerifier::ID; + false, false) +static char &PreVerifyID = PreVerifier::ID; namespace { class TypeSet : public AbstractTypeUser { @@ -184,11 +186,15 @@ namespace { Verifier() : FunctionPass(ID), Broken(false), RealPass(true), action(AbortProcessAction), - Mod(0), Context(0), DT(0), MessagesStr(Messages) {} + Mod(0), Context(0), DT(0), MessagesStr(Messages) { + initializeVerifierPass(*PassRegistry::getPassRegistry()); + } explicit Verifier(VerifierFailureAction ctn) : FunctionPass(ID), Broken(false), RealPass(true), action(ctn), Mod(0), Context(0), DT(0), - MessagesStr(Messages) {} + MessagesStr(Messages) { + initializeVerifierPass(*PassRegistry::getPassRegistry()); + } bool doInitialization(Module &M) { Mod = &M; @@ -393,7 +399,10 @@ namespace { } // End anonymous namespace char Verifier::ID = 0; -INITIALIZE_PASS(Verifier, "verify", "Module Verifier", false, false); +INITIALIZE_PASS_BEGIN(Verifier, "verify", "Module Verifier", false, false) +INITIALIZE_PASS_DEPENDENCY(PreVerifier) +INITIALIZE_PASS_DEPENDENCY(DominatorTree) +INITIALIZE_PASS_END(Verifier, "verify", "Module Verifier", false, false) // Assert - We know that cond should be true, if not print an error message. #define Assert(C, M) \ @@ -475,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()); @@ -685,6 +695,8 @@ void Verifier::visitFunction(Function &F) { case CallingConv::Cold: case CallingConv::X86_FastCall: case CallingConv::X86_ThisCall: + case CallingConv::PTX_Kernel: + case CallingConv::PTX_Device: Assert1(!F.isVarArg(), "Varargs functions must have C calling conventions!", &F); break; @@ -1643,10 +1655,14 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) { if (ID == Intrinsic::gcroot) { AllocaInst *AI = dyn_cast<AllocaInst>(CI.getArgOperand(0)->stripPointerCasts()); - Assert1(AI && AI->getType()->getElementType()->isPointerTy(), - "llvm.gcroot parameter #1 must be a pointer alloca.", &CI); + Assert1(AI, "llvm.gcroot parameter #1 must be an alloca.", &CI); Assert1(isa<Constant>(CI.getArgOperand(1)), "llvm.gcroot parameter #2 must be a constant.", &CI); + if (!AI->getType()->getElementType()->isPointerTy()) { + Assert1(!isa<ConstantPointerNull>(CI.getArgOperand(1)), + "llvm.gcroot parameter #1 must either be a pointer alloca, " + "or argument #2 must be a non-null constant.", &CI); + } } Assert1(CI.getParent()->getParent()->hasGC(), |