diff options
author | dim <dim@FreeBSD.org> | 2011-06-12 15:42:51 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2011-06-12 15:42:51 +0000 |
commit | ece02cd5829cea836e9365b0845a8ef042d17b0a (patch) | |
tree | b3032e51d630e8070e9e08d6641648f195316a80 /lib/VMCore | |
parent | 2b066988909948dc3d53d01760bc2d71d32f3feb (diff) | |
download | FreeBSD-src-ece02cd5829cea836e9365b0845a8ef042d17b0a.zip FreeBSD-src-ece02cd5829cea836e9365b0845a8ef042d17b0a.tar.gz |
Vendor import of llvm trunk r132879:
http://llvm.org/svn/llvm-project/llvm/trunk@132879
Diffstat (limited to 'lib/VMCore')
-rw-r--r-- | lib/VMCore/Attributes.cpp | 2 | ||||
-rw-r--r-- | lib/VMCore/AutoUpgrade.cpp | 60 | ||||
-rw-r--r-- | lib/VMCore/DebugInfoProbe.cpp | 43 | ||||
-rw-r--r-- | lib/VMCore/Function.cpp | 39 | ||||
-rw-r--r-- | lib/VMCore/IRBuilder.cpp | 31 | ||||
-rw-r--r-- | lib/VMCore/InlineAsm.cpp | 5 | ||||
-rw-r--r-- | lib/VMCore/Instructions.cpp | 167 | ||||
-rw-r--r-- | lib/VMCore/PassManager.cpp | 18 | ||||
-rw-r--r-- | lib/VMCore/Type.cpp | 19 | ||||
-rw-r--r-- | lib/VMCore/Verifier.cpp | 3 |
10 files changed, 255 insertions, 132 deletions
diff --git a/lib/VMCore/Attributes.cpp b/lib/VMCore/Attributes.cpp index 92152a3..ee257db 100644 --- a/lib/VMCore/Attributes.cpp +++ b/lib/VMCore/Attributes.cpp @@ -36,6 +36,8 @@ std::string Attribute::getAsString(Attributes Attrs) { Result += "noreturn "; if (Attrs & Attribute::NoUnwind) Result += "nounwind "; + if (Attrs & Attribute::UWTable) + Result += "uwtable "; if (Attrs & Attribute::InReg) Result += "inreg "; if (Attrs & Attribute::NoAlias) diff --git a/lib/VMCore/AutoUpgrade.cpp b/lib/VMCore/AutoUpgrade.cpp index 4541f38..f8f15ca 100644 --- a/lib/VMCore/AutoUpgrade.cpp +++ b/lib/VMCore/AutoUpgrade.cpp @@ -285,7 +285,33 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) { } break; - case 'x': + case 'x': + // This fixes the poorly named crc32 intrinsics + if (Name.compare(5, 13, "x86.sse42.crc", 13) == 0) { + const char* NewFnName = NULL; + if (Name.compare(18, 2, "32", 2) == 0) { + if (Name.compare(20, 2, ".8") == 0 && Name.length() == 22) { + NewFnName = "llvm.x86.sse42.crc32.32.8"; + } else if (Name.compare(20, 3, ".16") == 0 && Name.length() == 23) { + NewFnName = "llvm.x86.sse42.crc32.32.16"; + } else if (Name.compare(20, 3, ".32") == 0 && Name.length() == 23) { + NewFnName = "llvm.x86.sse42.crc32.32.32"; + } + } + else if (Name.compare(18, 2, "64", 2) == 0) { + if (Name.compare(20, 2, ".8") == 0 && Name.length() == 22) { + NewFnName = "llvm.x86.sse42.crc32.64.8"; + } else if (Name.compare(20, 3, ".64") == 0 && Name.length() == 23) { + NewFnName = "llvm.x86.sse42.crc32.64.64"; + } + } + if (NewFnName) { + F->setName(NewFnName); + NewFn = F; + return true; + } + } + // This fixes all MMX shift intrinsic instructions to take a // x86_mmx instead of a v1i64, v2i32, v4i16, or v8i8. if (Name.compare(5, 8, "x86.mmx.", 8) == 0) { @@ -533,6 +559,13 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) { // Calls to these instructions are transformed into unaligned loads. NewFn = 0; return true; + } else if (Name.compare(5, 16, "x86.sse.movnt.ps", 16) == 0 || + Name.compare(5, 17, "x86.sse2.movnt.dq", 17) == 0 || + Name.compare(5, 17, "x86.sse2.movnt.pd", 17) == 0 || + Name.compare(5, 17, "x86.sse2.movnt.i", 16) == 0) { + // Calls to these instructions are transformed into nontemporal stores. + 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()); @@ -975,6 +1008,31 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) { // Remove intrinsic. CI->eraseFromParent(); + } else if (F->getName() == "llvm.x86.sse.movnt.ps" || + F->getName() == "llvm.x86.sse2.movnt.dq" || + F->getName() == "llvm.x86.sse2.movnt.pd" || + F->getName() == "llvm.x86.sse2.movnt.i") { + IRBuilder<> Builder(C); + Builder.SetInsertPoint(CI->getParent(), CI); + + Module *M = F->getParent(); + SmallVector<Value *, 1> Elts; + Elts.push_back(ConstantInt::get(Type::getInt32Ty(C), 1)); + MDNode *Node = MDNode::get(C, Elts); + + Value *Arg0 = CI->getArgOperand(0); + Value *Arg1 = CI->getArgOperand(1); + + // Convert the type of the pointer to a pointer to the stored type. + Value *BC = Builder.CreateBitCast(Arg0, + PointerType::getUnqual(Arg1->getType()), + "cast"); + StoreInst *SI = Builder.CreateStore(Arg1, BC); + SI->setMetadata(M->getMDKindID("nontemporal"), Node); + SI->setAlignment(16); + + // Remove intrinsic. + CI->eraseFromParent(); } else { llvm_unreachable("Unknown function for CallInst upgrade."); } diff --git a/lib/VMCore/DebugInfoProbe.cpp b/lib/VMCore/DebugInfoProbe.cpp index 334c3d8..d1275ff 100644 --- a/lib/VMCore/DebugInfoProbe.cpp +++ b/lib/VMCore/DebugInfoProbe.cpp @@ -51,7 +51,6 @@ namespace llvm { unsigned NumDbgLineLost, NumDbgValueLost; std::string PassName; Function *TheFn; - std::set<unsigned> LineNos; std::set<MDNode *> DbgVariables; std::set<Instruction *> MissingDebugLoc; }; @@ -60,37 +59,19 @@ namespace llvm { //===----------------------------------------------------------------------===// // DebugInfoProbeImpl -static void collect(Function &F, std::set<unsigned> &Lines) { - for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI) - for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); - BI != BE; ++BI) { - const DebugLoc &DL = BI->getDebugLoc(); - unsigned LineNo = 0; - if (!DL.isUnknown()) { - if (MDNode *N = DL.getInlinedAt(F.getContext())) - LineNo = DebugLoc::getFromDILocation(N).getLine(); - else - LineNo = DL.getLine(); - - Lines.insert(LineNo); - } - } -} - /// initialize - Collect information before running an optimization pass. void DebugInfoProbeImpl::initialize(StringRef PName, Function &F) { if (!EnableDebugInfoProbe) return; PassName = PName; - LineNos.clear(); DbgVariables.clear(); + MissingDebugLoc.clear(); TheFn = &F; - collect(F, LineNos); for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI) for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); BI != BE; ++BI) { - if (BI->getDebugLoc().isUnknown()) + if (!isa<PHINode>(BI) && BI->getDebugLoc().isUnknown()) MissingDebugLoc.insert(BI); if (!isa<DbgInfoIntrinsic>(BI)) continue; Value *Addr = NULL; @@ -130,30 +111,16 @@ void DebugInfoProbeImpl::report() { /// must be used after initialization. void DebugInfoProbeImpl::finalize(Function &F) { if (!EnableDebugInfoProbe) return; - std::set<unsigned> LineNos2; - collect(F, LineNos2); assert (TheFn == &F && "Invalid function to measure!"); - for (std::set<unsigned>::iterator I = LineNos.begin(), - E = LineNos.end(); I != E; ++I) { - unsigned LineNo = *I; - if (LineNos2.count(LineNo) == 0) { - DEBUG(dbgs() - << "DebugInfoProbe(" - << PassName - << "): Losing dbg info for source line " - << LineNo << "\n"); - ++NumDbgLineLost; - } - } - std::set<MDNode *>DbgVariables2; for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI) for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); BI != BE; ++BI) { - if (BI->getDebugLoc().isUnknown() && + if (!isa<PHINode>(BI) && BI->getDebugLoc().isUnknown() && MissingDebugLoc.count(BI) == 0) { - DEBUG(dbgs() << "DebugInfoProbe(" << PassName << "): --- "); + ++NumDbgLineLost; + DEBUG(dbgs() << "DebugInfoProbe (" << PassName << "): --- "); DEBUG(BI->print(dbgs())); DEBUG(dbgs() << "\n"); } diff --git a/lib/VMCore/Function.cpp b/lib/VMCore/Function.cpp index 013c458..0ae0bdb 100644 --- a/lib/VMCore/Function.cpp +++ b/lib/VMCore/Function.cpp @@ -24,6 +24,7 @@ #include "llvm/Support/Threading.h" #include "SymbolTableListTraitsImpl.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringExtras.h" using namespace llvm; @@ -78,6 +79,12 @@ bool Argument::hasByValAttr() const { return getParent()->paramHasAttr(getArgNo()+1, Attribute::ByVal); } +unsigned Argument::getParamAlignment() const { + assert(getType()->isPointerTy() && "Only pointers have alignments"); + return getParent()->getParamAlignment(getArgNo()+1); + +} + /// hasNestAttr - Return true if this argument has the nest attribute on /// it in its containing function. bool Argument::hasNestAttr() const { @@ -406,4 +413,36 @@ bool Function::hasAddressTaken(const User* *PutOffender) const { return false; } +/// callsFunctionThatReturnsTwice - Return true if the function has a call to +/// setjmp or other function that gcc recognizes as "returning twice". +/// +/// FIXME: Remove after <rdar://problem/8031714> is fixed. +/// FIXME: Is the obove FIXME valid? +bool Function::callsFunctionThatReturnsTwice() const { + const Module *M = this->getParent(); + static const char *ReturnsTwiceFns[] = { + "_setjmp", + "setjmp", + "sigsetjmp", + "setjmp_syscall", + "savectx", + "qsetjmp", + "vfork", + "getcontext" + }; + + for (unsigned I = 0; I < array_lengthof(ReturnsTwiceFns); ++I) + if (const Function *Callee = M->getFunction(ReturnsTwiceFns[I])) { + if (!Callee->use_empty()) + for (Value::const_use_iterator + I = Callee->use_begin(), E = Callee->use_end(); + I != E; ++I) + if (const CallInst *CI = dyn_cast<CallInst>(*I)) + if (CI->getParent()->getParent() == this) + return true; + } + + return false; +} + // vim: sw=2 ai diff --git a/lib/VMCore/IRBuilder.cpp b/lib/VMCore/IRBuilder.cpp index 2149155..f2d469a 100644 --- a/lib/VMCore/IRBuilder.cpp +++ b/lib/VMCore/IRBuilder.cpp @@ -60,7 +60,6 @@ static CallInst *createCallHelper(Value *Callee, Value *const* Ops, return CI; } - CallInst *IRBuilderBase:: CreateMemSet(Value *Ptr, Value *Val, Value *Size, unsigned Align, bool isVolatile, MDNode *TBAATag) { @@ -118,3 +117,33 @@ CreateMemMove(Value *Dst, Value *Src, Value *Size, unsigned Align, return CI; } + +CallInst *IRBuilderBase::CreateLifetimeStart(Value *Ptr, ConstantInt *Size) { + assert(isa<PointerType>(Ptr->getType()) && + "lifetime.start only applies to pointers."); + Ptr = getCastedInt8PtrValue(Ptr); + if (!Size) + Size = getInt64(-1); + else + assert(Size->getType() == getInt64Ty() && + "lifetime.start requires the size to be an i64"); + Value *Ops[] = { Size, Ptr }; + Module *M = BB->getParent()->getParent(); + Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::lifetime_start); + return createCallHelper(TheFn, Ops, 2, this); +} + +CallInst *IRBuilderBase::CreateLifetimeEnd(Value *Ptr, ConstantInt *Size) { + assert(isa<PointerType>(Ptr->getType()) && + "lifetime.end only applies to pointers."); + Ptr = getCastedInt8PtrValue(Ptr); + if (!Size) + Size = getInt64(-1); + else + assert(Size->getType() == getInt64Ty() && + "lifetime.end requires the size to be an i64"); + Value *Ops[] = { Size, Ptr }; + Module *M = BB->getParent()->getParent(); + Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::lifetime_end); + return createCallHelper(TheFn, Ops, 2, this); +} diff --git a/lib/VMCore/InlineAsm.cpp b/lib/VMCore/InlineAsm.cpp index e4f99f0..bd3667d 100644 --- a/lib/VMCore/InlineAsm.cpp +++ b/lib/VMCore/InlineAsm.cpp @@ -181,6 +181,11 @@ bool InlineAsm::ConstraintInfo::Parse(StringRef Str, multipleAlternativeIndex++; pCodes = &multipleAlternatives[multipleAlternativeIndex].Codes; ++I; + } else if (*I == '^') { + // Multi-letter constraint + // FIXME: For now assuming these are 2-character constraints. + pCodes->push_back(std::string(I+1, I+3)); + I += 3; } else { // Single letter constraint. pCodes->push_back(std::string(I, I+1)); diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp index 61da9b6..8f4eabe 100644 --- a/lib/VMCore/Instructions.cpp +++ b/lib/VMCore/Instructions.cpp @@ -2076,6 +2076,7 @@ unsigned CastInst::isEliminableCastPair( CastInst *CastInst::Create(Instruction::CastOps op, Value *S, const Type *Ty, const Twine &Name, Instruction *InsertBefore) { + assert(castIsValid(op, S, Ty) && "Invalid cast!"); // Construct and return the appropriate CastInst subclass switch (op) { case Trunc: return new TruncInst (S, Ty, Name, InsertBefore); @@ -2098,6 +2099,7 @@ CastInst *CastInst::Create(Instruction::CastOps op, Value *S, const Type *Ty, CastInst *CastInst::Create(Instruction::CastOps op, Value *S, const Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd) { + assert(castIsValid(op, S, Ty) && "Invalid cast!"); // Construct and return the appropriate CastInst subclass switch (op) { case Trunc: return new TruncInst (S, Ty, Name, InsertAtEnd); @@ -2254,60 +2256,56 @@ bool CastInst::isCastable(const Type *SrcTy, const Type *DestTy) { if (SrcTy == DestTy) return true; + if (const VectorType *SrcVecTy = dyn_cast<VectorType>(SrcTy)) + if (const VectorType *DestVecTy = dyn_cast<VectorType>(DestTy)) + if (SrcVecTy->getNumElements() == DestVecTy->getNumElements()) { + // An element by element cast. Valid if casting the elements is valid. + SrcTy = SrcVecTy->getElementType(); + DestTy = DestVecTy->getElementType(); + } + // Get the bit sizes, we'll need these - unsigned SrcBits = SrcTy->getScalarSizeInBits(); // 0 for ptr - unsigned DestBits = DestTy->getScalarSizeInBits(); // 0 for ptr + unsigned SrcBits = SrcTy->getPrimitiveSizeInBits(); // 0 for ptr + unsigned DestBits = DestTy->getPrimitiveSizeInBits(); // 0 for ptr // Run through the possibilities ... - if (DestTy->isIntegerTy()) { // Casting to integral - if (SrcTy->isIntegerTy()) { // Casting from integral + if (DestTy->isIntegerTy()) { // Casting to integral + if (SrcTy->isIntegerTy()) { // Casting from integral return true; - } else if (SrcTy->isFloatingPointTy()) { // Casting from floating pt + } else if (SrcTy->isFloatingPointTy()) { // Casting from floating pt return true; - } else if (const VectorType *PTy = dyn_cast<VectorType>(SrcTy)) { - // Casting from vector - return DestBits == PTy->getBitWidth(); + } else if (SrcTy->isVectorTy()) { // Casting from vector + return DestBits == SrcBits; } else { // Casting from something else return SrcTy->isPointerTy(); } - } else if (DestTy->isFloatingPointTy()) { // Casting to floating pt - if (SrcTy->isIntegerTy()) { // Casting from integral + } else if (DestTy->isFloatingPointTy()) { // Casting to floating pt + if (SrcTy->isIntegerTy()) { // Casting from integral return true; - } else if (SrcTy->isFloatingPointTy()) { // Casting from floating pt + } else if (SrcTy->isFloatingPointTy()) { // Casting from floating pt return true; - } else if (const VectorType *PTy = dyn_cast<VectorType>(SrcTy)) { - // Casting from vector - return DestBits == PTy->getBitWidth(); + } else if (SrcTy->isVectorTy()) { // Casting from vector + return DestBits == SrcBits; } else { // Casting from something else return false; } - } else if (const VectorType *DestPTy = dyn_cast<VectorType>(DestTy)) { - // Casting to vector - if (const VectorType *SrcPTy = dyn_cast<VectorType>(SrcTy)) { - // Casting from vector - return DestPTy->getBitWidth() == SrcPTy->getBitWidth(); - } else if (DestPTy->getBitWidth() == SrcBits) { - return true; // float/int -> vector - } else if (SrcTy->isX86_MMXTy()) { - return DestPTy->getBitWidth() == 64; // MMX to 64-bit vector - } else { - return false; - } + } else if (DestTy->isVectorTy()) { // Casting to vector + return DestBits == SrcBits; } else if (DestTy->isPointerTy()) { // Casting to pointer - if (SrcTy->isPointerTy()) { // Casting from pointer + if (SrcTy->isPointerTy()) { // Casting from pointer return true; - } else if (SrcTy->isIntegerTy()) { // Casting from integral + } else if (SrcTy->isIntegerTy()) { // Casting from integral return true; - } else { // Casting from something else + } else { // Casting from something else return false; } } else if (DestTy->isX86_MMXTy()) { - if (const VectorType *SrcPTy = dyn_cast<VectorType>(SrcTy)) { - return SrcPTy->getBitWidth() == 64; // 64-bit vector to MMX + if (SrcTy->isVectorTy()) { + return DestBits == SrcBits; // 64-bit vector to MMX } else { return false; } - } else { // Casting to something else + } else { // Casting to something else return false; } } @@ -2322,14 +2320,27 @@ bool CastInst::isCastable(const Type *SrcTy, const Type *DestTy) { Instruction::CastOps CastInst::getCastOpcode( const Value *Src, bool SrcIsSigned, const Type *DestTy, bool DestIsSigned) { - // Get the bit sizes, we'll need these const Type *SrcTy = Src->getType(); - unsigned SrcBits = SrcTy->getScalarSizeInBits(); // 0 for ptr - unsigned DestBits = DestTy->getScalarSizeInBits(); // 0 for ptr assert(SrcTy->isFirstClassType() && DestTy->isFirstClassType() && "Only first class types are castable!"); + if (SrcTy == DestTy) + return BitCast; + + if (const VectorType *SrcVecTy = dyn_cast<VectorType>(SrcTy)) + if (const VectorType *DestVecTy = dyn_cast<VectorType>(DestTy)) + if (SrcVecTy->getNumElements() == DestVecTy->getNumElements()) { + // An element by element cast. Find the appropriate opcode based on the + // element types. + SrcTy = SrcVecTy->getElementType(); + DestTy = DestVecTy->getElementType(); + } + + // Get the bit sizes, we'll need these + unsigned SrcBits = SrcTy->getPrimitiveSizeInBits(); // 0 for ptr + unsigned DestBits = DestTy->getPrimitiveSizeInBits(); // 0 for ptr + // Run through the possibilities ... if (DestTy->isIntegerTy()) { // Casting to integral if (SrcTy->isIntegerTy()) { // Casting from integral @@ -2348,10 +2359,9 @@ CastInst::getCastOpcode( return FPToSI; // FP -> sint else return FPToUI; // FP -> uint - } else if (const VectorType *PTy = dyn_cast<VectorType>(SrcTy)) { - assert(DestBits == PTy->getBitWidth() && - "Casting vector to integer of different width"); - PTy = NULL; + } else if (SrcTy->isVectorTy()) { + assert(DestBits == SrcBits && + "Casting vector to integer of different width"); return BitCast; // Same size, no-op cast } else { assert(SrcTy->isPointerTy() && @@ -2372,29 +2382,17 @@ CastInst::getCastOpcode( } else { return BitCast; // same size, no-op cast } - } else if (const VectorType *PTy = dyn_cast<VectorType>(SrcTy)) { - assert(DestBits == PTy->getBitWidth() && + } else if (SrcTy->isVectorTy()) { + assert(DestBits == SrcBits && "Casting vector to floating point of different width"); - PTy = NULL; return BitCast; // same size, no-op cast } else { llvm_unreachable("Casting pointer or non-first class to float"); } - } else if (const VectorType *DestPTy = dyn_cast<VectorType>(DestTy)) { - if (const VectorType *SrcPTy = dyn_cast<VectorType>(SrcTy)) { - assert(DestPTy->getBitWidth() == SrcPTy->getBitWidth() && - "Casting vector to vector of different widths"); - SrcPTy = NULL; - 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)"); - } + } else if (DestTy->isVectorTy()) { + assert(DestBits == SrcBits && + "Illegal cast to vector (wrong type or size)"); + return BitCast; } else if (DestTy->isPointerTy()) { if (SrcTy->isPointerTy()) { return BitCast; // ptr -> ptr @@ -2404,9 +2402,8 @@ CastInst::getCastOpcode( 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"); + if (SrcTy->isVectorTy()) { + assert(DestBits == SrcBits && "Casting vector of wrong width to X86_MMX"); return BitCast; // 64-bit vector to MMX } else { assert(!"Illegal cast to X86_MMX"); @@ -2442,46 +2439,40 @@ CastInst::castIsValid(Instruction::CastOps op, Value *S, const Type *DstTy) { unsigned SrcBitSize = SrcTy->getScalarSizeInBits(); unsigned DstBitSize = DstTy->getScalarSizeInBits(); + // If these are vector types, get the lengths of the vectors (using zero for + // scalar types means that checking that vector lengths match also checks that + // scalars are not being converted to vectors or vectors to scalars). + unsigned SrcLength = SrcTy->isVectorTy() ? + cast<VectorType>(SrcTy)->getNumElements() : 0; + unsigned DstLength = DstTy->isVectorTy() ? + cast<VectorType>(DstTy)->getNumElements() : 0; + // Switch on the opcode provided switch (op) { default: return false; // This is an input error case Instruction::Trunc: - return SrcTy->isIntOrIntVectorTy() && - DstTy->isIntOrIntVectorTy()&& SrcBitSize > DstBitSize; + return SrcTy->isIntOrIntVectorTy() && DstTy->isIntOrIntVectorTy() && + SrcLength == DstLength && SrcBitSize > DstBitSize; case Instruction::ZExt: - return SrcTy->isIntOrIntVectorTy() && - DstTy->isIntOrIntVectorTy()&& SrcBitSize < DstBitSize; + return SrcTy->isIntOrIntVectorTy() && DstTy->isIntOrIntVectorTy() && + SrcLength == DstLength && SrcBitSize < DstBitSize; case Instruction::SExt: - return SrcTy->isIntOrIntVectorTy() && - DstTy->isIntOrIntVectorTy()&& SrcBitSize < DstBitSize; + return SrcTy->isIntOrIntVectorTy() && DstTy->isIntOrIntVectorTy() && + SrcLength == DstLength && SrcBitSize < DstBitSize; case Instruction::FPTrunc: - return SrcTy->isFPOrFPVectorTy() && - DstTy->isFPOrFPVectorTy() && - SrcBitSize > DstBitSize; + return SrcTy->isFPOrFPVectorTy() && DstTy->isFPOrFPVectorTy() && + SrcLength == DstLength && SrcBitSize > DstBitSize; case Instruction::FPExt: - return SrcTy->isFPOrFPVectorTy() && - DstTy->isFPOrFPVectorTy() && - SrcBitSize < DstBitSize; + return SrcTy->isFPOrFPVectorTy() && DstTy->isFPOrFPVectorTy() && + SrcLength == DstLength && SrcBitSize < DstBitSize; case Instruction::UIToFP: case Instruction::SIToFP: - if (const VectorType *SVTy = dyn_cast<VectorType>(SrcTy)) { - if (const VectorType *DVTy = dyn_cast<VectorType>(DstTy)) { - return SVTy->getElementType()->isIntOrIntVectorTy() && - DVTy->getElementType()->isFPOrFPVectorTy() && - SVTy->getNumElements() == DVTy->getNumElements(); - } - } - return SrcTy->isIntOrIntVectorTy() && DstTy->isFPOrFPVectorTy(); + return SrcTy->isIntOrIntVectorTy() && DstTy->isFPOrFPVectorTy() && + SrcLength == DstLength; case Instruction::FPToUI: case Instruction::FPToSI: - if (const VectorType *SVTy = dyn_cast<VectorType>(SrcTy)) { - if (const VectorType *DVTy = dyn_cast<VectorType>(DstTy)) { - return SVTy->getElementType()->isFPOrFPVectorTy() && - DVTy->getElementType()->isIntOrIntVectorTy() && - SVTy->getNumElements() == DVTy->getNumElements(); - } - } - return SrcTy->isFPOrFPVectorTy() && DstTy->isIntOrIntVectorTy(); + return SrcTy->isFPOrFPVectorTy() && DstTy->isIntOrIntVectorTy() && + SrcLength == DstLength; case Instruction::PtrToInt: return SrcTy->isPointerTy() && DstTy->isIntegerTy(); case Instruction::IntToPtr: diff --git a/lib/VMCore/PassManager.cpp b/lib/VMCore/PassManager.cpp index 637fa79..5cf2905 100644 --- a/lib/VMCore/PassManager.cpp +++ b/lib/VMCore/PassManager.cpp @@ -449,9 +449,9 @@ namespace { static DebugInfoProbeInfo *TheDebugProbe; static void createDebugInfoProbe() { if (TheDebugProbe) return; - - // Constructed the first time this is called. This guarantees that the - // object will be constructed, if -enable-debug-info-probe is set, + + // Constructed the first time this is called. This guarantees that the + // object will be constructed, if -enable-debug-info-probe is set, // before static globals, thus it will be destroyed before them. static ManagedStatic<DebugInfoProbeInfo> DIP; TheDebugProbe = &*DIP; @@ -632,6 +632,7 @@ void PMTopLevelManager::schedulePass(Pass *P) { Pass *AnalysisPass = findAnalysisPass(*I); if (!AnalysisPass) { const PassInfo *PI = PassRegistry::getPassRegistry()->getPassInfo(*I); + assert(PI && "Expected required passes to be initialized"); AnalysisPass = PI->createPass(); if (P->getPotentialPassManagerType () == AnalysisPass->getPotentialPassManagerType()) @@ -686,6 +687,7 @@ Pass *PMTopLevelManager::findAnalysisPass(AnalysisID AID) { // If Pass not found then check the interfaces implemented by Immutable Pass const PassInfo *PassInf = PassRegistry::getPassRegistry()->getPassInfo(PI); + assert(PassInf && "Expected all immutable passes to be initialized"); const std::vector<const PassInfo*> &ImmPI = PassInf->getInterfacesImplemented(); for (std::vector<const PassInfo*>::const_iterator II = ImmPI.begin(), @@ -727,9 +729,11 @@ void PMTopLevelManager::dumpArguments() const { for (SmallVector<ImmutablePass *, 8>::const_iterator I = ImmutablePasses.begin(), E = ImmutablePasses.end(); I != E; ++I) if (const PassInfo *PI = - PassRegistry::getPassRegistry()->getPassInfo((*I)->getPassID())) + PassRegistry::getPassRegistry()->getPassInfo((*I)->getPassID())) { + assert(PI && "Expected all immutable passes to be initialized"); if (!PI->isAnalysisGroup()) dbgs() << " -" << PI->getPassArgument(); + } for (SmallVector<PMDataManager *, 8>::const_iterator I = PassManagers.begin(), E = PassManagers.end(); I != E; ++I) (*I)->dumpPassArguments(); @@ -1183,6 +1187,12 @@ void PMDataManager::dumpAnalysisUsage(StringRef Msg, const Pass *P, for (unsigned i = 0; i != Set.size(); ++i) { if (i) dbgs() << ','; const PassInfo *PInf = PassRegistry::getPassRegistry()->getPassInfo(Set[i]); + if (!PInf) { + // Some preserved passes, such as AliasAnalysis, may not be initialized by + // all drivers. + dbgs() << " Uninitialized Pass"; + continue; + } dbgs() << ' ' << PInf->getPassName(); } dbgs() << '\n'; diff --git a/lib/VMCore/Type.cpp b/lib/VMCore/Type.cpp index b15304c..e4496db 100644 --- a/lib/VMCore/Type.cpp +++ b/lib/VMCore/Type.cpp @@ -197,6 +197,25 @@ bool Type::canLosslesslyBitCastTo(const Type *Ty) const { return false; // Other types have no identity values } +bool Type::isEmptyTy() const { + const ArrayType *ATy = dyn_cast<ArrayType>(this); + if (ATy) { + unsigned NumElements = ATy->getNumElements(); + return NumElements == 0 || ATy->getElementType()->isEmptyTy(); + } + + const StructType *STy = dyn_cast<StructType>(this); + if (STy) { + unsigned NumElements = STy->getNumElements(); + for (unsigned i = 0; i < NumElements; ++i) + if (!STy->getElementType(i)->isEmptyTy()) + return false; + return true; + } + + return false; +} + unsigned Type::getPrimitiveSizeInBits() const { switch (getTypeID()) { case Type::FloatTyID: return 32; diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp index 8b89110..139e035 100644 --- a/lib/VMCore/Verifier.cpp +++ b/lib/VMCore/Verifier.cpp @@ -1645,6 +1645,9 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) { Assert1(isa<ConstantInt>(CI.getArgOperand(3)), "alignment argument of memory intrinsics must be a constant int", &CI); + Assert1(isa<ConstantInt>(CI.getArgOperand(4)), + "isvolatile argument of memory intrinsics must be a constant int", + &CI); break; case Intrinsic::gcroot: case Intrinsic::gcwrite: |