diff options
author | Stephen Hines <srhines@google.com> | 2014-02-11 20:01:10 -0800 |
---|---|---|
committer | Stephen Hines <srhines@google.com> | 2014-02-11 20:01:10 -0800 |
commit | ce9904c6ea8fd669978a8eefb854b330eb9828ff (patch) | |
tree | 2418ee2e96ea220977c8fb74959192036ab5b133 /lib/IR | |
parent | c27b10b198c1d9e9b51f2303994313ec2778edd7 (diff) | |
parent | dbb832b83351cec97b025b61c26536ef50c3181c (diff) | |
download | external_llvm-ce9904c6ea8fd669978a8eefb854b330eb9828ff.zip external_llvm-ce9904c6ea8fd669978a8eefb854b330eb9828ff.tar.gz external_llvm-ce9904c6ea8fd669978a8eefb854b330eb9828ff.tar.bz2 |
Merge remote-tracking branch 'upstream/release_34' into merge-20140211
Conflicts:
lib/Linker/LinkModules.cpp
lib/Support/Unix/Signals.inc
Change-Id: Ia54f291fa5dc828052d2412736e8495c1282aa64
Diffstat (limited to 'lib/IR')
-rw-r--r-- | lib/IR/AsmWriter.cpp | 9 | ||||
-rw-r--r-- | lib/IR/AttributeImpl.h | 3 | ||||
-rw-r--r-- | lib/IR/Attributes.cpp | 7 | ||||
-rw-r--r-- | lib/IR/AutoUpgrade.cpp | 108 | ||||
-rw-r--r-- | lib/IR/CMakeLists.txt | 3 | ||||
-rw-r--r-- | lib/IR/ConstantFold.cpp | 80 | ||||
-rw-r--r-- | lib/IR/Constants.cpp | 27 | ||||
-rw-r--r-- | lib/IR/Core.cpp | 114 | ||||
-rw-r--r-- | lib/IR/DIBuilder.cpp | 358 | ||||
-rw-r--r-- | lib/IR/DataLayout.cpp | 7 | ||||
-rw-r--r-- | lib/IR/DebugInfo.cpp | 478 | ||||
-rw-r--r-- | lib/IR/Function.cpp | 48 | ||||
-rw-r--r-- | lib/IR/GCOV.cpp | 287 | ||||
-rw-r--r-- | lib/IR/Globals.cpp | 16 | ||||
-rw-r--r-- | lib/IR/Instruction.cpp | 25 | ||||
-rw-r--r-- | lib/IR/Instructions.cpp | 328 | ||||
-rw-r--r-- | lib/IR/LLVMContextImpl.h | 5 | ||||
-rw-r--r-- | lib/IR/LegacyPassManager.cpp | 1920 | ||||
-rw-r--r-- | lib/IR/Metadata.cpp | 4 | ||||
-rw-r--r-- | lib/IR/Module.cpp | 42 | ||||
-rw-r--r-- | lib/IR/PassManager.cpp | 1983 | ||||
-rw-r--r-- | lib/IR/Type.cpp | 6 | ||||
-rw-r--r-- | lib/IR/TypeFinder.cpp | 31 | ||||
-rw-r--r-- | lib/IR/Value.cpp | 47 | ||||
-rw-r--r-- | lib/IR/ValueTypes.cpp | 10 | ||||
-rw-r--r-- | lib/IR/Verifier.cpp | 174 |
26 files changed, 3530 insertions, 2590 deletions
diff --git a/lib/IR/AsmWriter.cpp b/lib/IR/AsmWriter.cpp index f275305..7decffd 100644 --- a/lib/IR/AsmWriter.cpp +++ b/lib/IR/AsmWriter.cpp @@ -74,6 +74,8 @@ static void PrintCallingConv(unsigned cc, raw_ostream &Out) { default: Out << "cc" << cc; break; case CallingConv::Fast: Out << "fastcc"; break; case CallingConv::Cold: Out << "coldcc"; break; + case CallingConv::WebKit_JS: Out << "webkit_jscc"; break; + case CallingConv::AnyReg: Out << "anyregcc"; break; case CallingConv::X86_StdCall: Out << "x86_stdcallcc"; break; case CallingConv::X86_FastCall: Out << "x86_fastcallcc"; break; case CallingConv::X86_ThisCall: Out << "x86_thiscallcc"; break; @@ -1394,9 +1396,6 @@ static void PrintLinkage(GlobalValue::LinkageTypes LT, case GlobalValue::InternalLinkage: Out << "internal "; break; case GlobalValue::LinkOnceAnyLinkage: Out << "linkonce "; break; case GlobalValue::LinkOnceODRLinkage: Out << "linkonce_odr "; break; - case GlobalValue::LinkOnceODRAutoHideLinkage: - Out << "linkonce_odr_auto_hide "; - break; case GlobalValue::WeakAnyLinkage: Out << "weak "; break; case GlobalValue::WeakODRLinkage: Out << "weak_odr "; break; case GlobalValue::CommonLinkage: Out << "common "; break; @@ -1647,6 +1646,10 @@ void AssemblyWriter::printFunction(const Function *F) { Out << " align " << F->getAlignment(); if (F->hasGC()) Out << " gc \"" << F->getGC() << '"'; + if (F->hasPrefixData()) { + Out << " prefix "; + writeOperand(F->getPrefixData(), true); + } if (F->isDeclaration()) { Out << '\n'; } else { diff --git a/lib/IR/AttributeImpl.h b/lib/IR/AttributeImpl.h index 9da3f96..ea954ac 100644 --- a/lib/IR/AttributeImpl.h +++ b/lib/IR/AttributeImpl.h @@ -94,6 +94,7 @@ public: /// attribute enties, which are for target-dependent attributes. class EnumAttributeImpl : public AttributeImpl { + virtual void anchor(); Attribute::AttrKind Kind; protected: @@ -108,6 +109,7 @@ public: }; class AlignAttributeImpl : public EnumAttributeImpl { + virtual void anchor(); unsigned Align; public: @@ -122,6 +124,7 @@ public: }; class StringAttributeImpl : public AttributeImpl { + virtual void anchor(); std::string Kind; std::string Val; diff --git a/lib/IR/Attributes.cpp b/lib/IR/Attributes.cpp index f466d16..0f2b7a0 100644 --- a/lib/IR/Attributes.cpp +++ b/lib/IR/Attributes.cpp @@ -196,6 +196,8 @@ std::string Attribute::getAsString(bool InAttrGrp) const { return "noreturn"; if (hasAttribute(Attribute::NoUnwind)) return "nounwind"; + if (hasAttribute(Attribute::OptimizeNone)) + return "optnone"; if (hasAttribute(Attribute::OptimizeForSize)) return "optsize"; if (hasAttribute(Attribute::ReadNone)) @@ -284,7 +286,11 @@ bool Attribute::operator<(Attribute A) const { // AttributeImpl Definition //===----------------------------------------------------------------------===// +// Pin the vtabels to this file. AttributeImpl::~AttributeImpl() {} +void EnumAttributeImpl::anchor() {} +void AlignAttributeImpl::anchor() {} +void StringAttributeImpl::anchor() {} bool AttributeImpl::hasAttribute(Attribute::AttrKind A) const { if (isStringAttribute()) return false; @@ -381,6 +387,7 @@ uint64_t AttributeImpl::getAttrMask(Attribute::AttrKind Val) { case Attribute::Returned: return 1ULL << 39; case Attribute::Cold: return 1ULL << 40; case Attribute::Builtin: return 1ULL << 41; + case Attribute::OptimizeNone: return 1ULL << 42; } llvm_unreachable("Unsupported attribute type"); } diff --git a/lib/IR/AutoUpgrade.cpp b/lib/IR/AutoUpgrade.cpp index a4f5289..d12bf7b 100644 --- a/lib/IR/AutoUpgrade.cpp +++ b/lib/IR/AutoUpgrade.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "llvm/AutoUpgrade.h" +#include "llvm/DebugInfo.h" #include "llvm/IR/Constants.h" #include "llvm/IR/Function.h" #include "llvm/IR/IRBuilder.h" @@ -88,6 +89,20 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) { } break; } + case 'o': + // We only need to change the name to match the mangling including the + // address space. + if (F->arg_size() == 2 && Name.startswith("objectsize.")) { + Type *Tys[2] = { F->getReturnType(), F->arg_begin()->getType() }; + if (F->getName() != Intrinsic::getName(Intrinsic::objectsize, Tys)) { + F->setName(Name + ".old"); + NewFn = Intrinsic::getDeclaration(F->getParent(), + Intrinsic::objectsize, Tys); + return true; + } + } + break; + case 'x': { if (Name.startswith("x86.sse2.pcmpeq.") || Name.startswith("x86.sse2.pcmpgt.") || @@ -97,6 +112,7 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) { Name == "x86.avx.movnt.dq.256" || Name == "x86.avx.movnt.pd.256" || Name == "x86.avx.movnt.ps.256" || + Name == "x86.sse42.crc32.64.8" || (Name.startswith("x86.xop.vpcom") && F->arg_size() == 2)) { NewFn = 0; return true; @@ -257,6 +273,12 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) { Function *VPCOM = Intrinsic::getDeclaration(F->getParent(), intID); Rep = Builder.CreateCall3(VPCOM, CI->getArgOperand(0), CI->getArgOperand(1), Builder.getInt8(Imm)); + } else if (Name == "llvm.x86.sse42.crc32.64.8") { + Function *CRC32 = Intrinsic::getDeclaration(F->getParent(), + Intrinsic::x86_sse42_crc32_32_8); + Value *Trunc0 = Builder.CreateTrunc(CI->getArgOperand(0), Type::getInt32Ty(C)); + Rep = Builder.CreateCall2(CRC32, Trunc0, CI->getArgOperand(1)); + Rep = Builder.CreateZExt(Rep, CI->getType(), ""); } else { bool PD128 = false, PD256 = false, PS128 = false, PS256 = false; if (Name == "llvm.x86.avx.vpermil.pd.256") @@ -317,6 +339,14 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) { CI->eraseFromParent(); return; + case Intrinsic::objectsize: + CI->replaceAllUsesWith(Builder.CreateCall2(NewFn, + CI->getArgOperand(0), + CI->getArgOperand(1), + Name)); + CI->eraseFromParent(); + return; + case Intrinsic::arm_neon_vclz: { // Change name from llvm.arm.neon.vclz.* to llvm.ctlz.* CI->replaceAllUsesWith(Builder.CreateCall2(NewFn, CI->getArgOperand(0), @@ -391,3 +421,81 @@ void llvm::UpgradeCallsToIntrinsic(Function* F) { } } +void llvm::UpgradeInstWithTBAATag(Instruction *I) { + MDNode *MD = I->getMetadata(LLVMContext::MD_tbaa); + assert(MD && "UpgradeInstWithTBAATag should have a TBAA tag"); + // Check if the tag uses struct-path aware TBAA format. + if (isa<MDNode>(MD->getOperand(0)) && MD->getNumOperands() >= 3) + return; + + if (MD->getNumOperands() == 3) { + Value *Elts[] = { + MD->getOperand(0), + MD->getOperand(1) + }; + MDNode *ScalarType = MDNode::get(I->getContext(), Elts); + // Create a MDNode <ScalarType, ScalarType, offset 0, const> + Value *Elts2[] = { + ScalarType, ScalarType, + Constant::getNullValue(Type::getInt64Ty(I->getContext())), + MD->getOperand(2) + }; + I->setMetadata(LLVMContext::MD_tbaa, MDNode::get(I->getContext(), Elts2)); + } else { + // Create a MDNode <MD, MD, offset 0> + Value *Elts[] = {MD, MD, + Constant::getNullValue(Type::getInt64Ty(I->getContext()))}; + I->setMetadata(LLVMContext::MD_tbaa, MDNode::get(I->getContext(), Elts)); + } +} + +Instruction *llvm::UpgradeBitCastInst(unsigned Opc, Value *V, Type *DestTy, + Instruction *&Temp) { + if (Opc != Instruction::BitCast) + return 0; + + Temp = 0; + Type *SrcTy = V->getType(); + if (SrcTy->isPtrOrPtrVectorTy() && DestTy->isPtrOrPtrVectorTy() && + SrcTy->getPointerAddressSpace() != DestTy->getPointerAddressSpace()) { + LLVMContext &Context = V->getContext(); + + // We have no information about target data layout, so we assume that + // the maximum pointer size is 64bit. + Type *MidTy = Type::getInt64Ty(Context); + Temp = CastInst::Create(Instruction::PtrToInt, V, MidTy); + + return CastInst::Create(Instruction::IntToPtr, Temp, DestTy); + } + + return 0; +} + +Value *llvm::UpgradeBitCastExpr(unsigned Opc, Constant *C, Type *DestTy) { + if (Opc != Instruction::BitCast) + return 0; + + Type *SrcTy = C->getType(); + if (SrcTy->isPtrOrPtrVectorTy() && DestTy->isPtrOrPtrVectorTy() && + SrcTy->getPointerAddressSpace() != DestTy->getPointerAddressSpace()) { + LLVMContext &Context = C->getContext(); + + // We have no information about target data layout, so we assume that + // the maximum pointer size is 64bit. + Type *MidTy = Type::getInt64Ty(Context); + + return ConstantExpr::getIntToPtr(ConstantExpr::getPtrToInt(C, MidTy), + DestTy); + } + + return 0; +} + +/// Check the debug info version number, if it is out-dated, drop the debug +/// info. Return true if module is modified. +bool llvm::UpgradeDebugInfo(Module &M) { + if (getDebugMetadataVersionFromModule(M) == DEBUG_METADATA_VERSION) + return false; + + return StripDebugInfo(M); +} diff --git a/lib/IR/CMakeLists.txt b/lib/IR/CMakeLists.txt index c2a4ee3..581946c 100644 --- a/lib/IR/CMakeLists.txt +++ b/lib/IR/CMakeLists.txt @@ -6,10 +6,10 @@ add_llvm_library(LLVMCore ConstantFold.cpp Constants.cpp Core.cpp + DIBuilder.cpp DataLayout.cpp DebugInfo.cpp DebugLoc.cpp - DIBuilder.cpp Dominators.cpp Function.cpp GCOV.cpp @@ -23,6 +23,7 @@ add_llvm_library(LLVMCore LLVMContext.cpp LLVMContextImpl.cpp LeakDetector.cpp + LegacyPassManager.cpp Metadata.cpp Module.cpp Pass.cpp diff --git a/lib/IR/ConstantFold.cpp b/lib/IR/ConstantFold.cpp index 8c5a983..f5e225c 100644 --- a/lib/IR/ConstantFold.cpp +++ b/lib/IR/ConstantFold.cpp @@ -689,6 +689,8 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, Constant *V, } case Instruction::BitCast: return FoldBitCast(V, DestTy); + case Instruction::AddrSpaceCast: + return 0; } } @@ -1897,6 +1899,37 @@ static bool isInBoundsIndices(ArrayRef<IndexTy> Idxs) { return true; } +/// \brief Test whether a given ConstantInt is in-range for a SequentialType. +static bool isIndexInRangeOfSequentialType(const SequentialType *STy, + const ConstantInt *CI) { + if (const PointerType *PTy = dyn_cast<PointerType>(STy)) + // Only handle pointers to sized types, not pointers to functions. + return PTy->getElementType()->isSized(); + + uint64_t NumElements = 0; + // Determine the number of elements in our sequential type. + if (const ArrayType *ATy = dyn_cast<ArrayType>(STy)) + NumElements = ATy->getNumElements(); + else if (const VectorType *VTy = dyn_cast<VectorType>(STy)) + NumElements = VTy->getNumElements(); + + assert((isa<ArrayType>(STy) || NumElements > 0) && + "didn't expect non-array type to have zero elements!"); + + // We cannot bounds check the index if it doesn't fit in an int64_t. + if (CI->getValue().getActiveBits() > 64) + return false; + + // A negative index or an index past the end of our sequential type is + // considered out-of-range. + int64_t IndexVal = CI->getSExtValue(); + if (IndexVal < 0 || (NumElements > 0 && (uint64_t)IndexVal >= NumElements)) + return false; + + // Otherwise, it is in-range. + return true; +} + template<typename IndexTy> static Constant *ConstantFoldGetElementPtrImpl(Constant *C, bool inBounds, @@ -1940,7 +1973,32 @@ static Constant *ConstantFoldGetElementPtrImpl(Constant *C, I != E; ++I) LastTy = *I; - if ((LastTy && isa<SequentialType>(LastTy)) || Idx0->isNullValue()) { + // We cannot combine indices if doing so would take us outside of an + // array or vector. Doing otherwise could trick us if we evaluated such a + // GEP as part of a load. + // + // e.g. Consider if the original GEP was: + // i8* getelementptr ({ [2 x i8], i32, i8, [3 x i8] }* @main.c, + // i32 0, i32 0, i64 0) + // + // If we then tried to offset it by '8' to get to the third element, + // an i8, we should *not* get: + // i8* getelementptr ({ [2 x i8], i32, i8, [3 x i8] }* @main.c, + // i32 0, i32 0, i64 8) + // + // This GEP tries to index array element '8 which runs out-of-bounds. + // Subsequent evaluation would get confused and produce erroneous results. + // + // The following prohibits such a GEP from being formed by checking to see + // if the index is in-range with respect to an array or vector. + bool PerformFold = false; + if (Idx0->isNullValue()) + PerformFold = true; + else if (SequentialType *STy = dyn_cast_or_null<SequentialType>(LastTy)) + if (ConstantInt *CI = dyn_cast<ConstantInt>(Idx0)) + PerformFold = isIndexInRangeOfSequentialType(STy, CI); + + if (PerformFold) { SmallVector<Value*, 16> NewIndices; NewIndices.reserve(Idxs.size() + CE->getNumOperands()); for (unsigned i = 1, e = CE->getNumOperands()-1; i != e; ++i) @@ -2000,8 +2058,8 @@ static Constant *ConstantFoldGetElementPtrImpl(Constant *C, } // Check to see if any array indices are not within the corresponding - // notional array bounds. If so, try to determine if they can be factored - // out into preceding dimensions. + // notional array or vector bounds. If so, try to determine if they can be + // factored out into preceding dimensions. bool Unknown = false; SmallVector<Constant *, 8> NewIdxs; Type *Ty = C->getType(); @@ -2009,16 +2067,20 @@ static Constant *ConstantFoldGetElementPtrImpl(Constant *C, for (unsigned i = 0, e = Idxs.size(); i != e; Prev = Ty, Ty = cast<CompositeType>(Ty)->getTypeAtIndex(Idxs[i]), ++i) { if (ConstantInt *CI = dyn_cast<ConstantInt>(Idxs[i])) { - if (ArrayType *ATy = dyn_cast<ArrayType>(Ty)) - if (ATy->getNumElements() <= INT64_MAX && - ATy->getNumElements() != 0 && - CI->getSExtValue() >= (int64_t)ATy->getNumElements()) { + if (isa<ArrayType>(Ty) || isa<VectorType>(Ty)) + if (CI->getSExtValue() > 0 && + !isIndexInRangeOfSequentialType(cast<SequentialType>(Ty), CI)) { if (isa<SequentialType>(Prev)) { // It's out of range, but we can factor it into the prior // dimension. NewIdxs.resize(Idxs.size()); - ConstantInt *Factor = ConstantInt::get(CI->getType(), - ATy->getNumElements()); + uint64_t NumElements = 0; + if (const ArrayType *ATy = dyn_cast<ArrayType>(Ty)) + NumElements = ATy->getNumElements(); + else + NumElements = cast<VectorType>(Ty)->getNumElements(); + + ConstantInt *Factor = ConstantInt::get(CI->getType(), NumElements); NewIdxs[i] = ConstantExpr::getSRem(CI, Factor); Constant *PrevIdx = cast<Constant>(Idxs[i-1]); diff --git a/lib/IR/Constants.cpp b/lib/IR/Constants.cpp index 9067b34..690ac59 100644 --- a/lib/IR/Constants.cpp +++ b/lib/IR/Constants.cpp @@ -1126,6 +1126,7 @@ getWithOperands(ArrayRef<Constant*> Ops, Type *Ty) const { case Instruction::PtrToInt: case Instruction::IntToPtr: case Instruction::BitCast: + case Instruction::AddrSpaceCast: return ConstantExpr::getCast(getOpcode(), Ops[0], Ty); case Instruction::Select: return ConstantExpr::getSelect(Ops[0], Ops[1], Ops[2]); @@ -1461,6 +1462,7 @@ Constant *ConstantExpr::getCast(unsigned oc, Constant *C, Type *Ty) { case Instruction::PtrToInt: return getPtrToInt(C, Ty); case Instruction::IntToPtr: return getIntToPtr(C, Ty); case Instruction::BitCast: return getBitCast(C, Ty); + case Instruction::AddrSpaceCast: return getAddrSpaceCast(C, Ty); } } @@ -1489,10 +1491,26 @@ Constant *ConstantExpr::getPointerCast(Constant *S, Type *Ty) { if (Ty->isIntOrIntVectorTy()) return getPtrToInt(S, Ty); + + unsigned SrcAS = S->getType()->getPointerAddressSpace(); + if (Ty->isPtrOrPtrVectorTy() && SrcAS != Ty->getPointerAddressSpace()) + return getAddrSpaceCast(S, Ty); + return getBitCast(S, Ty); } -Constant *ConstantExpr::getIntegerCast(Constant *C, Type *Ty, +Constant *ConstantExpr::getPointerBitCastOrAddrSpaceCast(Constant *S, + Type *Ty) { + assert(S->getType()->isPtrOrPtrVectorTy() && "Invalid cast"); + assert(Ty->isPtrOrPtrVectorTy() && "Invalid cast"); + + if (S->getType()->getPointerAddressSpace() != Ty->getPointerAddressSpace()) + return getAddrSpaceCast(S, Ty); + + return getBitCast(S, Ty); +} + +Constant *ConstantExpr::getIntegerCast(Constant *C, Type *Ty, bool isSigned) { assert(C->getType()->isIntOrIntVectorTy() && Ty->isIntOrIntVectorTy() && "Invalid cast"); @@ -1662,6 +1680,13 @@ Constant *ConstantExpr::getBitCast(Constant *C, Type *DstTy) { return getFoldedCast(Instruction::BitCast, C, DstTy); } +Constant *ConstantExpr::getAddrSpaceCast(Constant *C, Type *DstTy) { + assert(CastInst::castIsValid(Instruction::AddrSpaceCast, C, DstTy) && + "Invalid constantexpr addrspacecast!"); + + return getFoldedCast(Instruction::AddrSpaceCast, C, DstTy); +} + Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2, unsigned Flags) { // Check the operands for consistency first. diff --git a/lib/IR/Core.cpp b/lib/IR/Core.cpp index 66610bd..c70f459 100644 --- a/lib/IR/Core.cpp +++ b/lib/IR/Core.cpp @@ -97,7 +97,7 @@ LLVMModuleRef LLVMModuleCreateWithName(const char *ModuleID) { return wrap(new Module(ModuleID, getGlobalContext())); } -LLVMModuleRef LLVMModuleCreateWithNameInContext(const char *ModuleID, +LLVMModuleRef LLVMModuleCreateWithNameInContext(const char *ModuleID, LLVMContextRef C) { return wrap(new Module(ModuleID, *unwrap(C))); } @@ -147,6 +147,16 @@ LLVMBool LLVMPrintModuleToFile(LLVMModuleRef M, const char *Filename, return false; } +char *LLVMPrintModuleToString(LLVMModuleRef M) { + std::string buf; + raw_string_ostream os(buf); + + unwrap(M)->print(os, NULL); + os.flush(); + + return strdup(buf.c_str()); +} + /*--.. Operations on inline assembler ......................................--*/ void LLVMSetModuleInlineAsm(LLVMModuleRef M, const char *Asm) { unwrap(M)->setModuleInlineAsm(StringRef(Asm)); @@ -210,6 +220,20 @@ LLVMContextRef LLVMGetTypeContext(LLVMTypeRef Ty) { return wrap(&unwrap(Ty)->getContext()); } +void LLVMDumpType(LLVMTypeRef Ty) { + return unwrap(Ty)->dump(); +} + +char *LLVMPrintTypeToString(LLVMTypeRef Ty) { + std::string buf; + raw_string_ostream os(buf); + + unwrap(Ty)->print(os); + os.flush(); + + return strdup(buf.c_str()); +} + /*--.. Operations on integer types .........................................--*/ LLVMTypeRef LLVMInt1TypeInContext(LLVMContextRef C) { @@ -450,6 +474,16 @@ void LLVMDumpValue(LLVMValueRef Val) { unwrap(Val)->dump(); } +char* LLVMPrintValueToString(LLVMValueRef Val) { + std::string buf; + raw_string_ostream os(buf); + + unwrap(Val)->print(os); + os.flush(); + + return strdup(buf.c_str()); +} + void LLVMReplaceAllUsesWith(LLVMValueRef OldVal, LLVMValueRef NewVal) { unwrap(OldVal)->replaceAllUsesWith(unwrap(NewVal)); } @@ -681,7 +715,7 @@ LLVMValueRef LLVMConstStringInContext(LLVMContextRef C, const char *Str, return wrap(ConstantDataArray::getString(*unwrap(C), StringRef(Str, Length), DontNullTerminate == 0)); } -LLVMValueRef LLVMConstStructInContext(LLVMContextRef C, +LLVMValueRef LLVMConstStructInContext(LLVMContextRef C, LLVMValueRef *ConstantVals, unsigned Count, LLVMBool Packed) { Constant **Elements = unwrap<Constant>(ConstantVals, Count); @@ -999,6 +1033,12 @@ LLVMValueRef LLVMConstBitCast(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { unwrap(ToType))); } +LLVMValueRef LLVMConstAddrSpaceCast(LLVMValueRef ConstantVal, + LLVMTypeRef ToType) { + return wrap(ConstantExpr::getAddrSpaceCast(unwrap<Constant>(ConstantVal), + unwrap(ToType))); +} + LLVMValueRef LLVMConstZExtOrBitCast(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { return wrap(ConstantExpr::getZExtOrBitCast(unwrap<Constant>(ConstantVal), @@ -1110,8 +1150,6 @@ LLVMLinkage LLVMGetLinkage(LLVMValueRef Global) { return LLVMLinkOnceAnyLinkage; case GlobalValue::LinkOnceODRLinkage: return LLVMLinkOnceODRLinkage; - case GlobalValue::LinkOnceODRAutoHideLinkage: - return LLVMLinkOnceODRAutoHideLinkage; case GlobalValue::WeakAnyLinkage: return LLVMWeakAnyLinkage; case GlobalValue::WeakODRLinkage: @@ -1156,7 +1194,8 @@ void LLVMSetLinkage(LLVMValueRef Global, LLVMLinkage Linkage) { GV->setLinkage(GlobalValue::LinkOnceODRLinkage); break; case LLVMLinkOnceODRAutoHideLinkage: - GV->setLinkage(GlobalValue::LinkOnceODRAutoHideLinkage); + DEBUG(errs() << "LLVMSetLinkage(): LLVMLinkOnceODRAutoHideLinkage is no " + "longer supported."); break; case LLVMWeakAnyLinkage: GV->setLinkage(GlobalValue::WeakAnyLinkage); @@ -1216,12 +1255,30 @@ void LLVMSetVisibility(LLVMValueRef Global, LLVMVisibility Viz) { ->setVisibility(static_cast<GlobalValue::VisibilityTypes>(Viz)); } -unsigned LLVMGetAlignment(LLVMValueRef Global) { - return unwrap<GlobalValue>(Global)->getAlignment(); +/*--.. Operations on global variables, load and store instructions .........--*/ + +unsigned LLVMGetAlignment(LLVMValueRef V) { + Value *P = unwrap<Value>(V); + if (GlobalValue *GV = dyn_cast<GlobalValue>(P)) + return GV->getAlignment(); + if (LoadInst *LI = dyn_cast<LoadInst>(P)) + return LI->getAlignment(); + if (StoreInst *SI = dyn_cast<StoreInst>(P)) + return SI->getAlignment(); + + llvm_unreachable("only GlobalValue, LoadInst and StoreInst have alignment"); } -void LLVMSetAlignment(LLVMValueRef Global, unsigned Bytes) { - unwrap<GlobalValue>(Global)->setAlignment(Bytes); +void LLVMSetAlignment(LLVMValueRef V, unsigned Bytes) { + Value *P = unwrap<Value>(V); + if (GlobalValue *GV = dyn_cast<GlobalValue>(P)) + GV->setAlignment(Bytes); + else if (LoadInst *LI = dyn_cast<LoadInst>(P)) + LI->setAlignment(Bytes); + else if (StoreInst *SI = dyn_cast<StoreInst>(P)) + SI->setAlignment(Bytes); + else + llvm_unreachable("only GlobalValue, LoadInst and StoreInst have alignment"); } /*--.. Operations on global variables ......................................--*/ @@ -1553,7 +1610,7 @@ LLVMAttribute LLVMGetAttribute(LLVMValueRef Arg) { return (LLVMAttribute)A->getParent()->getAttributes(). Raw(A->getArgNo()+1); } - + void LLVMSetParamAlignment(LLVMValueRef Arg, unsigned align) { Argument *A = unwrap<Argument>(Arg); @@ -1745,7 +1802,7 @@ void LLVMSetInstructionCallConv(LLVMValueRef Instr, unsigned CC) { llvm_unreachable("LLVMSetInstructionCallConv applies only to call and invoke!"); } -void LLVMAddInstrAttribute(LLVMValueRef Instr, unsigned index, +void LLVMAddInstrAttribute(LLVMValueRef Instr, unsigned index, LLVMAttribute PA) { CallSite Call = CallSite(unwrap<Instruction>(Instr)); AttrBuilder B(PA); @@ -1755,7 +1812,7 @@ void LLVMAddInstrAttribute(LLVMValueRef Instr, unsigned index, index, B))); } -void LLVMRemoveInstrAttribute(LLVMValueRef Instr, unsigned index, +void LLVMRemoveInstrAttribute(LLVMValueRef Instr, unsigned index, LLVMAttribute PA) { CallSite Call = CallSite(unwrap<Instruction>(Instr)); AttrBuilder B(PA); @@ -1765,7 +1822,7 @@ void LLVMRemoveInstrAttribute(LLVMValueRef Instr, unsigned index, index, B))); } -void LLVMSetInstrParamAlignment(LLVMValueRef Instr, unsigned index, +void LLVMSetInstrParamAlignment(LLVMValueRef Instr, unsigned index, unsigned align) { CallSite Call = CallSite(unwrap<Instruction>(Instr)); AttrBuilder B; @@ -2119,8 +2176,8 @@ LLVMValueRef LLVMBuildMalloc(LLVMBuilderRef B, LLVMTypeRef Ty, Type* ITy = Type::getInt32Ty(unwrap(B)->GetInsertBlock()->getContext()); Constant* AllocSize = ConstantExpr::getSizeOf(unwrap(Ty)); AllocSize = ConstantExpr::getTruncOrBitCast(AllocSize, ITy); - Instruction* Malloc = CallInst::CreateMalloc(unwrap(B)->GetInsertBlock(), - ITy, unwrap(Ty), AllocSize, + Instruction* Malloc = CallInst::CreateMalloc(unwrap(B)->GetInsertBlock(), + ITy, unwrap(Ty), AllocSize, 0, 0, ""); return wrap(unwrap(B)->Insert(Malloc, Twine(Name))); } @@ -2130,8 +2187,8 @@ LLVMValueRef LLVMBuildArrayMalloc(LLVMBuilderRef B, LLVMTypeRef Ty, Type* ITy = Type::getInt32Ty(unwrap(B)->GetInsertBlock()->getContext()); Constant* AllocSize = ConstantExpr::getSizeOf(unwrap(Ty)); AllocSize = ConstantExpr::getTruncOrBitCast(AllocSize, ITy); - Instruction* Malloc = CallInst::CreateMalloc(unwrap(B)->GetInsertBlock(), - ITy, unwrap(Ty), AllocSize, + Instruction* Malloc = CallInst::CreateMalloc(unwrap(B)->GetInsertBlock(), + ITy, unwrap(Ty), AllocSize, unwrap(Val), 0, ""); return wrap(unwrap(B)->Insert(Malloc, Twine(Name))); } @@ -2157,7 +2214,7 @@ LLVMValueRef LLVMBuildLoad(LLVMBuilderRef B, LLVMValueRef PointerVal, return wrap(unwrap(B)->CreateLoad(unwrap(PointerVal), Name)); } -LLVMValueRef LLVMBuildStore(LLVMBuilderRef B, LLVMValueRef Val, +LLVMValueRef LLVMBuildStore(LLVMBuilderRef B, LLVMValueRef Val, LLVMValueRef PointerVal) { return wrap(unwrap(B)->CreateStore(unwrap(Val), unwrap(PointerVal))); } @@ -2267,6 +2324,11 @@ LLVMValueRef LLVMBuildBitCast(LLVMBuilderRef B, LLVMValueRef Val, return wrap(unwrap(B)->CreateBitCast(unwrap(Val), unwrap(DestTy), Name)); } +LLVMValueRef LLVMBuildAddrSpaceCast(LLVMBuilderRef B, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name) { + return wrap(unwrap(B)->CreateAddrSpaceCast(unwrap(Val), unwrap(DestTy), Name)); +} + LLVMValueRef LLVMBuildZExtOrBitCast(LLVMBuilderRef B, LLVMValueRef Val, LLVMTypeRef DestTy, const char *Name) { return wrap(unwrap(B)->CreateZExtOrBitCast(unwrap(Val), unwrap(DestTy), @@ -2396,9 +2458,9 @@ LLVMValueRef LLVMBuildPtrDiff(LLVMBuilderRef B, LLVMValueRef LHS, return wrap(unwrap(B)->CreatePtrDiff(unwrap(LHS), unwrap(RHS), Name)); } -LLVMValueRef LLVMBuildAtomicRMW(LLVMBuilderRef B,LLVMAtomicRMWBinOp op, - LLVMValueRef PTR, LLVMValueRef Val, - LLVMAtomicOrdering ordering, +LLVMValueRef LLVMBuildAtomicRMW(LLVMBuilderRef B,LLVMAtomicRMWBinOp op, + LLVMValueRef PTR, LLVMValueRef Val, + LLVMAtomicOrdering ordering, LLVMBool singleThread) { AtomicRMWInst::BinOp intop; switch (op) { @@ -2421,14 +2483,14 @@ LLVMValueRef LLVMBuildAtomicRMW(LLVMBuilderRef B,LLVMAtomicRMWBinOp op, case LLVMAtomicOrderingMonotonic: intordering = Monotonic; break; case LLVMAtomicOrderingAcquire: intordering = Acquire; break; case LLVMAtomicOrderingRelease: intordering = Release; break; - case LLVMAtomicOrderingAcquireRelease: - intordering = AcquireRelease; + case LLVMAtomicOrderingAcquireRelease: + intordering = AcquireRelease; break; - case LLVMAtomicOrderingSequentiallyConsistent: - intordering = SequentiallyConsistent; + case LLVMAtomicOrderingSequentiallyConsistent: + intordering = SequentiallyConsistent; break; } - return wrap(unwrap(B)->CreateAtomicRMW(intop, unwrap(PTR), unwrap(Val), + return wrap(unwrap(B)->CreateAtomicRMW(intop, unwrap(PTR), unwrap(Val), intordering, singleThread ? SingleThread : CrossThread)); } diff --git a/lib/IR/DIBuilder.cpp b/lib/IR/DIBuilder.cpp index 3005f77..c4a9f41 100644 --- a/lib/IR/DIBuilder.cpp +++ b/lib/IR/DIBuilder.cpp @@ -30,17 +30,24 @@ static Constant *GetTagConstant(LLVMContext &VMContext, unsigned Tag) { } DIBuilder::DIBuilder(Module &m) - : M(m), VMContext(M.getContext()), TempEnumTypes(0), - TempRetainTypes(0), TempSubprograms(0), TempGVs(0), DeclareFn(0), - ValueFn(0) -{} + : M(m), VMContext(M.getContext()), TempEnumTypes(0), TempRetainTypes(0), + TempSubprograms(0), TempGVs(0), DeclareFn(0), ValueFn(0) {} /// finalize - Construct any deferred debug info descriptors. void DIBuilder::finalize() { DIArray Enums = getOrCreateArray(AllEnumTypes); DIType(TempEnumTypes).replaceAllUsesWith(Enums); - DIArray RetainTypes = getOrCreateArray(AllRetainTypes); + SmallVector<Value *, 16> RetainValues; + // Declarations and definitions of the same type may be retained. Some + // clients RAUW these pairs, leaving duplicates in the retained types + // list. Use a set to remove the duplicates while we transform the + // TrackingVHs back into Values. + SmallPtrSet<Value *, 16> RetainSet; + for (unsigned I = 0, E = AllRetainTypes.size(); I < E; I++) + if (RetainSet.insert(AllRetainTypes[I])) + RetainValues.push_back(AllRetainTypes[I]); + DIArray RetainTypes = getOrCreateArray(RetainValues); DIType(TempRetainTypes).replaceAllUsesWith(RetainTypes); DIArray SPs = getOrCreateArray(AllSubprograms); @@ -79,7 +86,7 @@ static MDNode *createFilePathPair(LLVMContext &VMContext, StringRef Filename, assert(!Filename.empty() && "Unable to create file without name"); Value *Pair[] = { MDString::get(VMContext, Filename), - MDString::get(VMContext, Directory), + MDString::get(VMContext, Directory) }; return MDNode::get(VMContext, Pair); } @@ -274,7 +281,7 @@ DIDerivedType DIBuilder::createQualifiedType(unsigned Tag, DIType FromTy) { ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Align ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Offset ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Flags - FromTy + FromTy.getRef() }; return DIDerivedType(MDNode::get(VMContext, Elts)); } @@ -294,7 +301,7 @@ DIBuilder::createPointerType(DIType PointeeTy, uint64_t SizeInBits, ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits), ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Offset ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Flags - PointeeTy + PointeeTy.getRef() }; return DIDerivedType(MDNode::get(VMContext, Elts)); } @@ -308,12 +315,12 @@ DIDerivedType DIBuilder::createMemberPointerType(DIType PointeeTy, NULL, // Unused NULL, ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Line - ConstantInt::get(Type::getInt64Ty(VMContext), 0), - ConstantInt::get(Type::getInt64Ty(VMContext), 0), + ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Size + ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Align ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Offset ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Flags - PointeeTy, - Base + PointeeTy.getRef(), + Base.getRef() }; return DIDerivedType(MDNode::get(VMContext, Elts)); } @@ -333,7 +340,7 @@ DIDerivedType DIBuilder::createReferenceType(unsigned Tag, DIType RTy) { ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Align ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Offset ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Flags - RTy + RTy.getRef() }; return DIDerivedType(MDNode::get(VMContext, Elts)); } @@ -346,14 +353,14 @@ DIDerivedType DIBuilder::createTypedef(DIType Ty, StringRef Name, DIFile File, Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_typedef), File.getFileNode(), - getNonCompileUnitScope(Context), + DIScope(getNonCompileUnitScope(Context)).getRef(), MDString::get(VMContext, Name), ConstantInt::get(Type::getInt32Ty(VMContext), LineNo), ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Size ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Align ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Offset ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Flags - Ty + Ty.getRef() }; return DIDerivedType(MDNode::get(VMContext, Elts)); } @@ -366,56 +373,59 @@ DIDerivedType DIBuilder::createFriend(DIType Ty, DIType FriendTy) { Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_friend), NULL, - Ty, + Ty.getRef(), NULL, // Name ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Line ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Size ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Align ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Offset ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Flags - FriendTy + FriendTy.getRef() }; return DIDerivedType(MDNode::get(VMContext, Elts)); } /// createInheritance - Create debugging information entry to establish /// inheritance relationship between two types. -DIDerivedType DIBuilder::createInheritance( - DIType Ty, DIType BaseTy, uint64_t BaseOffset, unsigned Flags) { +DIDerivedType DIBuilder::createInheritance(DIType Ty, DIType BaseTy, + uint64_t BaseOffset, + unsigned Flags) { assert(Ty.isType() && "Unable to create inheritance"); // TAG_inheritance is encoded in DIDerivedType format. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_inheritance), NULL, - Ty, + Ty.getRef(), NULL, // Name ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Line ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Size ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Align ConstantInt::get(Type::getInt64Ty(VMContext), BaseOffset), ConstantInt::get(Type::getInt32Ty(VMContext), Flags), - BaseTy + BaseTy.getRef() }; return DIDerivedType(MDNode::get(VMContext, Elts)); } /// createMemberType - Create debugging information entry for a member. -DIDerivedType DIBuilder::createMemberType( - DIDescriptor Scope, StringRef Name, DIFile File, unsigned LineNumber, - uint64_t SizeInBits, uint64_t AlignInBits, uint64_t OffsetInBits, - unsigned Flags, DIType Ty) { +DIDerivedType DIBuilder::createMemberType(DIDescriptor Scope, StringRef Name, + DIFile File, unsigned LineNumber, + uint64_t SizeInBits, + uint64_t AlignInBits, + uint64_t OffsetInBits, unsigned Flags, + DIType Ty) { // TAG_member is encoded in DIDerivedType format. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_member), File.getFileNode(), - getNonCompileUnitScope(Scope), + DIScope(getNonCompileUnitScope(Scope)).getRef(), MDString::get(VMContext, Name), ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber), ConstantInt::get(Type::getInt64Ty(VMContext), SizeInBits), ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits), ConstantInt::get(Type::getInt64Ty(VMContext), OffsetInBits), ConstantInt::get(Type::getInt32Ty(VMContext), Flags), - Ty + Ty.getRef() }; return DIDerivedType(MDNode::get(VMContext, Elts)); } @@ -432,14 +442,14 @@ DIBuilder::createStaticMemberType(DIDescriptor Scope, StringRef Name, Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_member), File.getFileNode(), - getNonCompileUnitScope(Scope), + DIScope(getNonCompileUnitScope(Scope)).getRef(), MDString::get(VMContext, Name), ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber), - ConstantInt::get(Type::getInt64Ty(VMContext), 0/*SizeInBits*/), - ConstantInt::get(Type::getInt64Ty(VMContext), 0/*AlignInBits*/), - ConstantInt::get(Type::getInt64Ty(VMContext), 0/*OffsetInBits*/), + ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Size + ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Align + ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Offset ConstantInt::get(Type::getInt32Ty(VMContext), Flags), - Ty, + Ty.getRef(), Val }; return DIDerivedType(MDNode::get(VMContext, Elts)); @@ -448,13 +458,11 @@ DIBuilder::createStaticMemberType(DIDescriptor Scope, StringRef Name, /// createObjCIVar - Create debugging information entry for Objective-C /// instance variable. DIDerivedType -DIBuilder::createObjCIVar(StringRef Name, - DIFile File, unsigned LineNumber, +DIBuilder::createObjCIVar(StringRef Name, DIFile File, unsigned LineNumber, uint64_t SizeInBits, uint64_t AlignInBits, - uint64_t OffsetInBits, unsigned Flags, - DIType Ty, StringRef PropertyName, - StringRef GetterName, StringRef SetterName, - unsigned PropertyAttributes) { + uint64_t OffsetInBits, unsigned Flags, DIType Ty, + StringRef PropertyName, StringRef GetterName, + StringRef SetterName, unsigned PropertyAttributes) { // TAG_member is encoded in DIDerivedType format. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_member), @@ -477,12 +485,12 @@ DIBuilder::createObjCIVar(StringRef Name, /// createObjCIVar - Create debugging information entry for Objective-C /// instance variable. -DIDerivedType -DIBuilder::createObjCIVar(StringRef Name, - DIFile File, unsigned LineNumber, - uint64_t SizeInBits, uint64_t AlignInBits, - uint64_t OffsetInBits, unsigned Flags, - DIType Ty, MDNode *PropertyNode) { +DIDerivedType DIBuilder::createObjCIVar(StringRef Name, DIFile File, + unsigned LineNumber, + uint64_t SizeInBits, + uint64_t AlignInBits, + uint64_t OffsetInBits, unsigned Flags, + DIType Ty, MDNode *PropertyNode) { // TAG_member is encoded in DIDerivedType format. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_member), @@ -502,12 +510,10 @@ DIBuilder::createObjCIVar(StringRef Name, /// createObjCProperty - Create debugging information entry for Objective-C /// property. -DIObjCProperty DIBuilder::createObjCProperty(StringRef Name, - DIFile File, unsigned LineNumber, - StringRef GetterName, - StringRef SetterName, - unsigned PropertyAttributes, - DIType Ty) { +DIObjCProperty +DIBuilder::createObjCProperty(StringRef Name, DIFile File, unsigned LineNumber, + StringRef GetterName, StringRef SetterName, + unsigned PropertyAttributes, DIType Ty) { Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_APPLE_property), MDString::get(VMContext, Name), @@ -529,9 +535,9 @@ DIBuilder::createTemplateTypeParameter(DIDescriptor Context, StringRef Name, unsigned ColumnNo) { Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_template_type_parameter), - getNonCompileUnitScope(Context), + DIScope(getNonCompileUnitScope(Context)).getRef(), MDString::get(VMContext, Name), - Ty, + Ty.getRef(), File, ConstantInt::get(Type::getInt32Ty(VMContext), LineNo), ConstantInt::get(Type::getInt32Ty(VMContext), ColumnNo) @@ -547,9 +553,9 @@ DIBuilder::createTemplateValueParameter(unsigned Tag, DIDescriptor Context, unsigned ColumnNo) { Value *Elts[] = { GetTagConstant(VMContext, Tag), - getNonCompileUnitScope(Context), + DIScope(getNonCompileUnitScope(Context)).getRef(), MDString::get(VMContext, Name), - Ty, + Ty.getRef(), Val, File, ConstantInt::get(Type::getInt32Ty(VMContext), LineNo), @@ -598,30 +604,34 @@ DICompositeType DIBuilder::createClassType(DIDescriptor Context, StringRef Name, uint64_t OffsetInBits, unsigned Flags, DIType DerivedFrom, DIArray Elements, - MDNode *VTableHolder, - MDNode *TemplateParams) { + DIType VTableHolder, + MDNode *TemplateParams, + StringRef UniqueIdentifier) { assert((!Context || Context.isScope() || Context.isType()) && "createClassType should be called with a valid Context"); // TAG_class_type is encoded in DICompositeType format. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_class_type), File.getFileNode(), - getNonCompileUnitScope(Context), + DIScope(getNonCompileUnitScope(Context)).getRef(), MDString::get(VMContext, Name), ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber), ConstantInt::get(Type::getInt64Ty(VMContext), SizeInBits), ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits), ConstantInt::get(Type::getInt32Ty(VMContext), OffsetInBits), ConstantInt::get(Type::getInt32Ty(VMContext), Flags), - DerivedFrom, + DerivedFrom.getRef(), Elements, ConstantInt::get(Type::getInt32Ty(VMContext), 0), - VTableHolder, - TemplateParams + VTableHolder.getRef(), + TemplateParams, + UniqueIdentifier.empty() ? NULL : MDString::get(VMContext, UniqueIdentifier) }; DICompositeType R(MDNode::get(VMContext, Elts)); assert(R.isCompositeType() && "createClassType should return a DICompositeType"); + if (!UniqueIdentifier.empty()) + retainType(R); return R; } @@ -634,27 +644,31 @@ DICompositeType DIBuilder::createStructType(DIDescriptor Context, unsigned Flags, DIType DerivedFrom, DIArray Elements, unsigned RunTimeLang, - MDNode *VTableHolder) { + DIType VTableHolder, + StringRef UniqueIdentifier) { // TAG_structure_type is encoded in DICompositeType format. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_structure_type), File.getFileNode(), - getNonCompileUnitScope(Context), + DIScope(getNonCompileUnitScope(Context)).getRef(), MDString::get(VMContext, Name), ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber), ConstantInt::get(Type::getInt64Ty(VMContext), SizeInBits), ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits), ConstantInt::get(Type::getInt32Ty(VMContext), 0), ConstantInt::get(Type::getInt32Ty(VMContext), Flags), - DerivedFrom, + DerivedFrom.getRef(), Elements, ConstantInt::get(Type::getInt32Ty(VMContext), RunTimeLang), - VTableHolder, + VTableHolder.getRef(), NULL, + UniqueIdentifier.empty() ? NULL : MDString::get(VMContext, UniqueIdentifier) }; DICompositeType R(MDNode::get(VMContext, Elts)); assert(R.isCompositeType() && "createStructType should return a DICompositeType"); + if (!UniqueIdentifier.empty()) + retainType(R); return R; } @@ -664,45 +678,52 @@ DICompositeType DIBuilder::createUnionType(DIDescriptor Scope, StringRef Name, uint64_t SizeInBits, uint64_t AlignInBits, unsigned Flags, DIArray Elements, - unsigned RunTimeLang) { + unsigned RunTimeLang, + StringRef UniqueIdentifier) { // TAG_union_type is encoded in DICompositeType format. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_union_type), File.getFileNode(), - getNonCompileUnitScope(Scope), + DIScope(getNonCompileUnitScope(Scope)).getRef(), MDString::get(VMContext, Name), ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber), ConstantInt::get(Type::getInt64Ty(VMContext), SizeInBits), ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits), - ConstantInt::get(Type::getInt64Ty(VMContext), 0), + ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Offset ConstantInt::get(Type::getInt32Ty(VMContext), Flags), NULL, Elements, ConstantInt::get(Type::getInt32Ty(VMContext), RunTimeLang), - Constant::getNullValue(Type::getInt32Ty(VMContext)), - NULL + NULL, + NULL, + UniqueIdentifier.empty() ? NULL : MDString::get(VMContext, UniqueIdentifier) }; - return DICompositeType(MDNode::get(VMContext, Elts)); + DICompositeType R(MDNode::get(VMContext, Elts)); + if (!UniqueIdentifier.empty()) + retainType(R); + return R; } /// createSubroutineType - Create subroutine type. -DICompositeType -DIBuilder::createSubroutineType(DIFile File, DIArray ParameterTypes) { +DICompositeType DIBuilder::createSubroutineType(DIFile File, + DIArray ParameterTypes) { // TAG_subroutine_type is encoded in DICompositeType format. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_subroutine_type), Constant::getNullValue(Type::getInt32Ty(VMContext)), - Constant::getNullValue(Type::getInt32Ty(VMContext)), + NULL, MDString::get(VMContext, ""), - ConstantInt::get(Type::getInt32Ty(VMContext), 0), - ConstantInt::get(Type::getInt64Ty(VMContext), 0), - ConstantInt::get(Type::getInt64Ty(VMContext), 0), - ConstantInt::get(Type::getInt64Ty(VMContext), 0), - ConstantInt::get(Type::getInt32Ty(VMContext), 0), + ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Line + ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Size + ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Align + ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Offset + ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Flags NULL, ParameterTypes, ConstantInt::get(Type::getInt32Ty(VMContext), 0), - Constant::getNullValue(Type::getInt32Ty(VMContext)) + NULL, + NULL, + NULL // Type Identifer }; return DICompositeType(MDNode::get(VMContext, Elts)); } @@ -712,26 +733,30 @@ DIBuilder::createSubroutineType(DIFile File, DIArray ParameterTypes) { DICompositeType DIBuilder::createEnumerationType( DIDescriptor Scope, StringRef Name, DIFile File, unsigned LineNumber, uint64_t SizeInBits, uint64_t AlignInBits, DIArray Elements, - DIType UnderlyingType) { + DIType UnderlyingType, StringRef UniqueIdentifier) { // TAG_enumeration_type is encoded in DICompositeType format. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_enumeration_type), File.getFileNode(), - getNonCompileUnitScope(Scope), + DIScope(getNonCompileUnitScope(Scope)).getRef(), MDString::get(VMContext, Name), ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber), ConstantInt::get(Type::getInt64Ty(VMContext), SizeInBits), ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits), - ConstantInt::get(Type::getInt32Ty(VMContext), 0), - ConstantInt::get(Type::getInt32Ty(VMContext), 0), - UnderlyingType, + ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Offset + ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Flags + UnderlyingType.getRef(), Elements, ConstantInt::get(Type::getInt32Ty(VMContext), 0), - Constant::getNullValue(Type::getInt32Ty(VMContext)) + NULL, + NULL, + UniqueIdentifier.empty() ? NULL : MDString::get(VMContext, UniqueIdentifier) }; - MDNode *Node = MDNode::get(VMContext, Elts); - AllEnumTypes.push_back(Node); - return DICompositeType(Node); + DICompositeType CTy(MDNode::get(VMContext, Elts)); + AllEnumTypes.push_back(CTy); + if (!UniqueIdentifier.empty()) + retainType(CTy); + return CTy; } /// createArrayType - Create debugging information entry for an array. @@ -743,15 +768,17 @@ DICompositeType DIBuilder::createArrayType(uint64_t Size, uint64_t AlignInBits, NULL, // Filename/Directory, NULL, // Unused MDString::get(VMContext, ""), - ConstantInt::get(Type::getInt32Ty(VMContext), 0), + ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Line ConstantInt::get(Type::getInt64Ty(VMContext), Size), ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits), - ConstantInt::get(Type::getInt32Ty(VMContext), 0), - ConstantInt::get(Type::getInt32Ty(VMContext), 0), - Ty, + ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Offset + ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Flags + Ty.getRef(), Subscripts, ConstantInt::get(Type::getInt32Ty(VMContext), 0), - Constant::getNullValue(Type::getInt32Ty(VMContext)) + NULL, + NULL, + NULL // Type Identifer }; return DICompositeType(MDNode::get(VMContext, Elts)); } @@ -759,22 +786,23 @@ DICompositeType DIBuilder::createArrayType(uint64_t Size, uint64_t AlignInBits, /// createVectorType - Create debugging information entry for a vector. DICompositeType DIBuilder::createVectorType(uint64_t Size, uint64_t AlignInBits, DIType Ty, DIArray Subscripts) { - // A vector is an array type with the FlagVector flag applied. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_array_type), NULL, // Filename/Directory, NULL, // Unused MDString::get(VMContext, ""), - ConstantInt::get(Type::getInt32Ty(VMContext), 0), + ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Line ConstantInt::get(Type::getInt64Ty(VMContext), Size), ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits), - ConstantInt::get(Type::getInt32Ty(VMContext), 0), + ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Offset ConstantInt::get(Type::getInt32Ty(VMContext), DIType::FlagVector), - Ty, + Ty.getRef(), Subscripts, ConstantInt::get(Type::getInt32Ty(VMContext), 0), - Constant::getNullValue(Type::getInt32Ty(VMContext)) + NULL, + NULL, + NULL // Type Identifer }; return DICompositeType(MDNode::get(VMContext, Elts)); } @@ -787,17 +815,14 @@ DIType DIBuilder::createArtificialType(DIType Ty) { SmallVector<Value *, 9> Elts; MDNode *N = Ty; assert (N && "Unexpected input DIType!"); - for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { - if (Value *V = N->getOperand(i)) - Elts.push_back(V); - else - Elts.push_back(Constant::getNullValue(Type::getInt32Ty(VMContext))); - } + for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) + Elts.push_back(N->getOperand(i)); unsigned CurFlags = Ty.getFlags(); CurFlags = CurFlags | DIType::FlagArtificial; // Flags are stored at this slot. + // FIXME: Add an enum for this magic value. Elts[8] = ConstantInt::get(Type::getInt32Ty(VMContext), CurFlags); return DIType(MDNode::get(VMContext, Elts)); @@ -812,17 +837,14 @@ DIType DIBuilder::createObjectPointerType(DIType Ty) { SmallVector<Value *, 9> Elts; MDNode *N = Ty; assert (N && "Unexpected input DIType!"); - for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { - if (Value *V = N->getOperand(i)) - Elts.push_back(V); - else - Elts.push_back(Constant::getNullValue(Type::getInt32Ty(VMContext))); - } + for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) + Elts.push_back(N->getOperand(i)); unsigned CurFlags = Ty.getFlags(); CurFlags = CurFlags | (DIType::FlagObjectPointer | DIType::FlagArtificial); // Flags are stored at this slot. + // FIXME: Add an enum for this magic value. Elts[8] = ConstantInt::get(Type::getInt32Ty(VMContext), CurFlags); return DIType(MDNode::get(VMContext, Elts)); @@ -831,7 +853,7 @@ DIType DIBuilder::createObjectPointerType(DIType Ty) { /// retainType - Retain DIType in a module even if it is not referenced /// through debug info anchors. void DIBuilder::retainType(DIType T) { - AllRetainTypes.push_back(T); + AllRetainTypes.push_back(TrackingVH<MDNode>(T)); } /// createUnspecifiedParameter - Create unspeicified type descriptor @@ -845,31 +867,35 @@ DIDescriptor DIBuilder::createUnspecifiedParameter() { /// createForwardDecl - Create a temporary forward-declared type that /// can be RAUW'd if the full type is seen. -DIType DIBuilder::createForwardDecl(unsigned Tag, StringRef Name, - DIDescriptor Scope, DIFile F, - unsigned Line, unsigned RuntimeLang, - uint64_t SizeInBits, - uint64_t AlignInBits) { +DICompositeType +DIBuilder::createForwardDecl(unsigned Tag, StringRef Name, DIDescriptor Scope, + DIFile F, unsigned Line, unsigned RuntimeLang, + uint64_t SizeInBits, uint64_t AlignInBits, + StringRef UniqueIdentifier) { // Create a temporary MDNode. Value *Elts[] = { GetTagConstant(VMContext, Tag), F.getFileNode(), - getNonCompileUnitScope(Scope), + DIScope(getNonCompileUnitScope(Scope)).getRef(), MDString::get(VMContext, Name), ConstantInt::get(Type::getInt32Ty(VMContext), Line), ConstantInt::get(Type::getInt64Ty(VMContext), SizeInBits), ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits), - ConstantInt::get(Type::getInt32Ty(VMContext), 0), - ConstantInt::get(Type::getInt32Ty(VMContext), - DIDescriptor::FlagFwdDecl), + ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Offset + ConstantInt::get(Type::getInt32Ty(VMContext), DIDescriptor::FlagFwdDecl), NULL, DIArray(), - ConstantInt::get(Type::getInt32Ty(VMContext), RuntimeLang) + ConstantInt::get(Type::getInt32Ty(VMContext), RuntimeLang), + NULL, + NULL, //TemplateParams + UniqueIdentifier.empty() ? NULL : MDString::get(VMContext, UniqueIdentifier) }; MDNode *Node = MDNode::getTemporary(VMContext, Elts); - DIType RetTy(Node); - assert(RetTy.isType() && + DICompositeType RetTy(Node); + assert(RetTy.isCompositeType() && "createForwardDecl result should be a DIType"); + if (!UniqueIdentifier.empty()) + retainType(RetTy); return RetTy; } @@ -895,10 +921,11 @@ DISubrange DIBuilder::getOrCreateSubrange(int64_t Lo, int64_t Count) { } /// \brief Create a new descriptor for the specified global. -DIGlobalVariable DIBuilder:: -createGlobalVariable(StringRef Name, StringRef LinkageName, DIFile F, - unsigned LineNumber, DIType Ty, bool isLocalToUnit, - Value *Val) { +DIGlobalVariable DIBuilder::createGlobalVariable(StringRef Name, + StringRef LinkageName, + DIFile F, unsigned LineNumber, + DIType Ty, bool isLocalToUnit, + Value *Val) { Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_variable), Constant::getNullValue(Type::getInt32Ty(VMContext)), @@ -920,19 +947,22 @@ createGlobalVariable(StringRef Name, StringRef LinkageName, DIFile F, } /// \brief Create a new descriptor for the specified global. -DIGlobalVariable DIBuilder:: -createGlobalVariable(StringRef Name, DIFile F, unsigned LineNumber, - DIType Ty, bool isLocalToUnit, Value *Val) { +DIGlobalVariable DIBuilder::createGlobalVariable(StringRef Name, DIFile F, + unsigned LineNumber, DIType Ty, + bool isLocalToUnit, + Value *Val) { return createGlobalVariable(Name, Name, F, LineNumber, Ty, isLocalToUnit, Val); } /// createStaticVariable - Create a new descriptor for the specified static /// variable. -DIGlobalVariable DIBuilder:: -createStaticVariable(DIDescriptor Context, StringRef Name, - StringRef LinkageName, DIFile F, unsigned LineNumber, - DIType Ty, bool isLocalToUnit, Value *Val, MDNode *Decl) { +DIGlobalVariable DIBuilder::createStaticVariable(DIDescriptor Context, + StringRef Name, + StringRef LinkageName, + DIFile F, unsigned LineNumber, + DIType Ty, bool isLocalToUnit, + Value *Val, MDNode *Decl) { Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_variable), Constant::getNullValue(Type::getInt32Ty(VMContext)), @@ -1012,24 +1042,38 @@ DIVariable DIBuilder::createComplexVariable(unsigned Tag, DIDescriptor Scope, } /// createFunction - Create a new descriptor for the specified function. -DISubprogram DIBuilder::createFunction(DIDescriptor Context, - StringRef Name, - StringRef LinkageName, - DIFile File, unsigned LineNo, - DICompositeType Ty, +/// FIXME: this is added for dragonegg. Once we update dragonegg +/// to call resolve function, this will be removed. +DISubprogram DIBuilder::createFunction(DIScopeRef Context, StringRef Name, + StringRef LinkageName, DIFile File, + unsigned LineNo, DICompositeType Ty, + bool isLocalToUnit, bool isDefinition, + unsigned ScopeLine, unsigned Flags, + bool isOptimized, Function *Fn, + MDNode *TParams, MDNode *Decl) { + // dragonegg does not generate identifier for types, so using an empty map + // to resolve the context should be fine. + DITypeIdentifierMap EmptyMap; + return createFunction(Context.resolve(EmptyMap), Name, LinkageName, File, + LineNo, Ty, isLocalToUnit, isDefinition, ScopeLine, + Flags, isOptimized, Fn, TParams, Decl); +} + +/// createFunction - Create a new descriptor for the specified function. +DISubprogram DIBuilder::createFunction(DIDescriptor Context, StringRef Name, + StringRef LinkageName, DIFile File, + unsigned LineNo, DICompositeType Ty, bool isLocalToUnit, bool isDefinition, - unsigned ScopeLine, - unsigned Flags, bool isOptimized, - Function *Fn, - MDNode *TParams, - MDNode *Decl) { + unsigned ScopeLine, unsigned Flags, + bool isOptimized, Function *Fn, + MDNode *TParams, MDNode *Decl) { assert(Ty.getTag() == dwarf::DW_TAG_subroutine_type && "function types should be subroutines"); Value *TElts[] = { GetTagConstant(VMContext, DW_TAG_base_type) }; Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_subprogram), File.getFileNode(), - getNonCompileUnitScope(Context), + DIScope(getNonCompileUnitScope(Context)).getRef(), MDString::get(VMContext, Name), MDString::get(VMContext, Name), MDString::get(VMContext, LinkageName), @@ -1059,26 +1103,24 @@ DISubprogram DIBuilder::createFunction(DIDescriptor Context, } /// createMethod - Create a new descriptor for the specified C++ method. -DISubprogram DIBuilder::createMethod(DIDescriptor Context, - StringRef Name, - StringRef LinkageName, - DIFile F, +DISubprogram DIBuilder::createMethod(DIDescriptor Context, StringRef Name, + StringRef LinkageName, DIFile F, unsigned LineNo, DICompositeType Ty, - bool isLocalToUnit, - bool isDefinition, + bool isLocalToUnit, bool isDefinition, unsigned VK, unsigned VIndex, - MDNode *VTableHolder, - unsigned Flags, - bool isOptimized, - Function *Fn, + DIType VTableHolder, unsigned Flags, + bool isOptimized, Function *Fn, MDNode *TParam) { assert(Ty.getTag() == dwarf::DW_TAG_subroutine_type && "function types should be subroutines"); + assert(getNonCompileUnitScope(Context) && + "Methods should have both a Context and a context that isn't " + "the compile unit."); Value *TElts[] = { GetTagConstant(VMContext, DW_TAG_base_type) }; Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_subprogram), F.getFileNode(), - getNonCompileUnitScope(Context), + DIScope(Context).getRef(), MDString::get(VMContext, Name), MDString::get(VMContext, Name), MDString::get(VMContext, LinkageName), @@ -1086,9 +1128,9 @@ DISubprogram DIBuilder::createMethod(DIDescriptor Context, Ty, ConstantInt::get(Type::getInt1Ty(VMContext), isLocalToUnit), ConstantInt::get(Type::getInt1Ty(VMContext), isDefinition), - ConstantInt::get(Type::getInt32Ty(VMContext), (unsigned)VK), + ConstantInt::get(Type::getInt32Ty(VMContext), VK), ConstantInt::get(Type::getInt32Ty(VMContext), VIndex), - VTableHolder, + VTableHolder.getRef(), ConstantInt::get(Type::getInt32Ty(VMContext), Flags), ConstantInt::get(Type::getInt1Ty(VMContext), isOptimized), Fn, diff --git a/lib/IR/DataLayout.cpp b/lib/IR/DataLayout.cpp index d786d33..6bdc09e 100644 --- a/lib/IR/DataLayout.cpp +++ b/lib/IR/DataLayout.cpp @@ -629,6 +629,13 @@ Type *DataLayout::getSmallestLegalIntType(LLVMContext &C, unsigned Width) const return 0; } +unsigned DataLayout::getLargestLegalIntTypeSize() const { + unsigned MaxWidth = 0; + for (unsigned i = 0, e = (unsigned)LegalIntWidths.size(); i != e; ++i) + MaxWidth = std::max<unsigned>(MaxWidth, LegalIntWidths[i]); + return MaxWidth; +} + uint64_t DataLayout::getIndexedOffset(Type *ptrTy, ArrayRef<Value *> Indices) const { Type *Ty = ptrTy; diff --git a/lib/IR/DebugInfo.cpp b/lib/IR/DebugInfo.cpp index ff37542..70a756f 100644 --- a/lib/IR/DebugInfo.cpp +++ b/lib/IR/DebugInfo.cpp @@ -75,8 +75,8 @@ uint64_t DIDescriptor::getUInt64Field(unsigned Elt) const { return 0; if (Elt < DbgNode->getNumOperands()) - if (ConstantInt *CI - = dyn_cast_or_null<ConstantInt>(DbgNode->getOperand(Elt))) + if (ConstantInt *CI = + dyn_cast_or_null<ConstantInt>(DbgNode->getOperand(Elt))) return CI->getZExtValue(); return 0; @@ -87,8 +87,8 @@ int64_t DIDescriptor::getInt64Field(unsigned Elt) const { return 0; if (Elt < DbgNode->getNumOperands()) - if (ConstantInt *CI - = dyn_cast_or_null<ConstantInt>(DbgNode->getOperand(Elt))) + if (ConstantInt *CI = + dyn_cast_or_null<ConstantInt>(DbgNode->getOperand(Elt))) return CI->getSExtValue(); return 0; @@ -104,7 +104,7 @@ GlobalVariable *DIDescriptor::getGlobalVariableField(unsigned Elt) const { return 0; if (Elt < DbgNode->getNumOperands()) - return dyn_cast_or_null<GlobalVariable>(DbgNode->getOperand(Elt)); + return dyn_cast_or_null<GlobalVariable>(DbgNode->getOperand(Elt)); return 0; } @@ -113,7 +113,7 @@ Constant *DIDescriptor::getConstantField(unsigned Elt) const { return 0; if (Elt < DbgNode->getNumOperands()) - return dyn_cast_or_null<Constant>(DbgNode->getOperand(Elt)); + return dyn_cast_or_null<Constant>(DbgNode->getOperand(Elt)); return 0; } @@ -122,7 +122,7 @@ Function *DIDescriptor::getFunctionField(unsigned Elt) const { return 0; if (Elt < DbgNode->getNumOperands()) - return dyn_cast_or_null<Function>(DbgNode->getOperand(Elt)); + return dyn_cast_or_null<Function>(DbgNode->getOperand(Elt)); return 0; } @@ -131,19 +131,17 @@ void DIDescriptor::replaceFunctionField(unsigned Elt, Function *F) { return; if (Elt < DbgNode->getNumOperands()) { - MDNode *Node = const_cast<MDNode*>(DbgNode); + MDNode *Node = const_cast<MDNode *>(DbgNode); Node->replaceOperandWith(Elt, F); } } unsigned DIVariable::getNumAddrElements() const { - return DbgNode->getNumOperands()-8; + return DbgNode->getNumOperands() - 8; } /// getInlinedAt - If this variable is inlined then return inline location. -MDNode *DIVariable::getInlinedAt() const { - return getNodeField(DbgNode, 7); -} +MDNode *DIVariable::getInlinedAt() const { return getNodeField(DbgNode, 7); } //===----------------------------------------------------------------------===// // Predicates @@ -152,7 +150,8 @@ MDNode *DIVariable::getInlinedAt() const { /// isBasicType - Return true if the specified tag is legal for /// DIBasicType. bool DIDescriptor::isBasicType() const { - if (!DbgNode) return false; + if (!DbgNode) + return false; switch (getTag()) { case dwarf::DW_TAG_base_type: case dwarf::DW_TAG_unspecified_type: @@ -164,7 +163,8 @@ bool DIDescriptor::isBasicType() const { /// isDerivedType - Return true if the specified tag is legal for DIDerivedType. bool DIDescriptor::isDerivedType() const { - if (!DbgNode) return false; + if (!DbgNode) + return false; switch (getTag()) { case dwarf::DW_TAG_typedef: case dwarf::DW_TAG_pointer_type: @@ -187,7 +187,8 @@ bool DIDescriptor::isDerivedType() const { /// isCompositeType - Return true if the specified tag is legal for /// DICompositeType. bool DIDescriptor::isCompositeType() const { - if (!DbgNode) return false; + if (!DbgNode) + return false; switch (getTag()) { case dwarf::DW_TAG_array_type: case dwarf::DW_TAG_structure_type: @@ -203,7 +204,8 @@ bool DIDescriptor::isCompositeType() const { /// isVariable - Return true if the specified tag is legal for DIVariable. bool DIDescriptor::isVariable() const { - if (!DbgNode) return false; + if (!DbgNode) + return false; switch (getTag()) { case dwarf::DW_TAG_auto_variable: case dwarf::DW_TAG_arg_variable: @@ -240,17 +242,19 @@ bool DIDescriptor::isUnspecifiedParameter() const { /// isScope - Return true if the specified tag is one of the scope /// related tag. bool DIDescriptor::isScope() const { - if (!DbgNode) return false; + if (!DbgNode) + return false; switch (getTag()) { case dwarf::DW_TAG_compile_unit: case dwarf::DW_TAG_lexical_block: case dwarf::DW_TAG_subprogram: case dwarf::DW_TAG_namespace: + case dwarf::DW_TAG_file_type: return true; default: break; } - return false; + return isType(); } /// isTemplateTypeParameter - Return true if the specified tag is @@ -286,13 +290,13 @@ bool DIDescriptor::isNameSpace() const { /// lexical block with an extra file. bool DIDescriptor::isLexicalBlockFile() const { return DbgNode && getTag() == dwarf::DW_TAG_lexical_block && - (DbgNode->getNumOperands() == 3); + (DbgNode->getNumOperands() == 3); } /// isLexicalBlock - Return true if the specified tag is DW_TAG_lexical_block. bool DIDescriptor::isLexicalBlock() const { return DbgNode && getTag() == dwarf::DW_TAG_lexical_block && - (DbgNode->getNumOperands() > 3); + (DbgNode->getNumOperands() > 3); } /// isSubrange - Return true if the specified tag is DW_TAG_subrange_type. @@ -339,10 +343,10 @@ void DIType::replaceAllUsesWith(DIDescriptor &D) { // this detail by allowing a value to be replaced with replaceAllUsesWith() // itself. if (DbgNode != D) { - MDNode *Node = const_cast<MDNode*>(DbgNode); + MDNode *Node = const_cast<MDNode *>(DbgNode); const MDNode *DN = D; const Value *V = cast_or_null<Value>(DN); - Node->replaceAllUsesWith(const_cast<Value*>(V)); + Node->replaceAllUsesWith(const_cast<Value *>(V)); MDNode::deleteTemporary(Node); } } @@ -359,31 +363,14 @@ void DIType::replaceAllUsesWith(MDNode *D) { // this detail by allowing a value to be replaced with replaceAllUsesWith() // itself. if (DbgNode != D) { - MDNode *Node = const_cast<MDNode*>(DbgNode); + MDNode *Node = const_cast<MDNode *>(DbgNode); const MDNode *DN = D; const Value *V = cast_or_null<Value>(DN); - Node->replaceAllUsesWith(const_cast<Value*>(V)); + Node->replaceAllUsesWith(const_cast<Value *>(V)); MDNode::deleteTemporary(Node); } } -/// isUnsignedDIType - Return true if type encoding is unsigned. -bool DIType::isUnsignedDIType() { - DIDerivedType DTy(DbgNode); - if (DTy.Verify()) - return DTy.getTypeDerivedFrom().isUnsignedDIType(); - - DIBasicType BTy(DbgNode); - if (BTy.Verify()) { - unsigned Encoding = BTy.getEncoding(); - if (Encoding == dwarf::DW_ATE_unsigned || - Encoding == dwarf::DW_ATE_unsigned_char || - Encoding == dwarf::DW_ATE_boolean) - return true; - } - return false; -} - /// Verify - Verify that a compile unit is well formed. bool DICompileUnit::Verify() const { if (!isCompileUnit()) @@ -413,22 +400,53 @@ static bool fieldIsMDNode(const MDNode *DbgNode, unsigned Elt) { // FIXME: This function should return true, if the field is null or the field // is indeed a MDNode: return !Fld || isa<MDNode>(Fld). Value *Fld = getField(DbgNode, Elt); - if (Fld && isa<MDString>(Fld) && - !cast<MDString>(Fld)->getString().empty()) + if (Fld && isa<MDString>(Fld) && !cast<MDString>(Fld)->getString().empty()) return false; return true; } +/// Check if a field at position Elt of a MDNode is a MDString. +static bool fieldIsMDString(const MDNode *DbgNode, unsigned Elt) { + Value *Fld = getField(DbgNode, Elt); + return !Fld || isa<MDString>(Fld); +} + +/// Check if a value can be a reference to a type. +static bool isTypeRef(const Value *Val) { + return !Val || + (isa<MDString>(Val) && !cast<MDString>(Val)->getString().empty()) || + (isa<MDNode>(Val) && DIType(cast<MDNode>(Val)).isType()); +} + +/// Check if a field at position Elt of a MDNode can be a reference to a type. +static bool fieldIsTypeRef(const MDNode *DbgNode, unsigned Elt) { + Value *Fld = getField(DbgNode, Elt); + return isTypeRef(Fld); +} + +/// Check if a value can be a ScopeRef. +static bool isScopeRef(const Value *Val) { + return !Val || + (isa<MDString>(Val) && !cast<MDString>(Val)->getString().empty()) || + (isa<MDNode>(Val) && DIScope(cast<MDNode>(Val)).isScope()); +} + +/// Check if a field at position Elt of a MDNode can be a ScopeRef. +static bool fieldIsScopeRef(const MDNode *DbgNode, unsigned Elt) { + Value *Fld = getField(DbgNode, Elt); + return isScopeRef(Fld); +} + /// Verify - Verify that a type descriptor is well formed. bool DIType::Verify() const { if (!isType()) return false; // Make sure Context @ field 2 is MDNode. - if (!fieldIsMDNode(DbgNode, 2)) + if (!fieldIsScopeRef(DbgNode, 2)) return false; // FIXME: Sink this into the various subclass verifies. - unsigned Tag = getTag(); + uint16_t Tag = getTag(); if (!isBasicType() && Tag != dwarf::DW_TAG_const_type && Tag != dwarf::DW_TAG_volatile_type && Tag != dwarf::DW_TAG_pointer_type && Tag != dwarf::DW_TAG_ptr_to_member_type && @@ -460,12 +478,12 @@ bool DIBasicType::Verify() const { /// Verify - Verify that a derived type descriptor is well formed. bool DIDerivedType::Verify() const { - // Make sure DerivedFrom @ field 9 is MDNode. - if (!fieldIsMDNode(DbgNode, 9)) + // Make sure DerivedFrom @ field 9 is TypeRef. + if (!fieldIsTypeRef(DbgNode, 9)) return false; if (getTag() == dwarf::DW_TAG_ptr_to_member_type) - // Make sure ClassType @ field 10 is MDNode. - if (!fieldIsMDNode(DbgNode, 10)) + // Make sure ClassType @ field 10 is a TypeRef. + if (!fieldIsTypeRef(DbgNode, 10)) return false; return isDerivedType() && DbgNode->getNumOperands() >= 10 && @@ -477,13 +495,17 @@ bool DICompositeType::Verify() const { if (!isCompositeType()) return false; - // Make sure DerivedFrom @ field 9 and ContainingType @ field 12 are MDNodes. - if (!fieldIsMDNode(DbgNode, 9)) + // Make sure DerivedFrom @ field 9 and ContainingType @ field 12 are TypeRef. + if (!fieldIsTypeRef(DbgNode, 9)) return false; - if (!fieldIsMDNode(DbgNode, 12)) + if (!fieldIsTypeRef(DbgNode, 12)) return false; - return DbgNode->getNumOperands() >= 10 && DbgNode->getNumOperands() <= 14; + // Make sure the type identifier at field 14 is MDString, it can be null. + if (!fieldIsMDString(DbgNode, 14)) + return false; + + return DbgNode->getNumOperands() == 15; } /// Verify - Verify that a subprogram descriptor is well formed. @@ -491,13 +513,13 @@ bool DISubprogram::Verify() const { if (!isSubprogram()) return false; - // Make sure context @ field 2 and type @ field 7 are MDNodes. - if (!fieldIsMDNode(DbgNode, 2)) + // Make sure context @ field 2 is a ScopeRef and type @ field 7 is a MDNode. + if (!fieldIsScopeRef(DbgNode, 2)) return false; if (!fieldIsMDNode(DbgNode, 7)) return false; // Containing type @ field 12. - if (!fieldIsMDNode(DbgNode, 12)) + if (!fieldIsTypeRef(DbgNode, 12)) return false; return DbgNode->getNumOperands() == 20; } @@ -550,9 +572,7 @@ bool DINameSpace::Verify() const { } /// \brief Retrieve the MDNode for the directory/file pair. -MDNode *DIFile::getFileNode() const { - return getNodeField(DbgNode, 1); -} +MDNode *DIFile::getFileNode() const { return getNodeField(DbgNode, 1); } /// \brief Verify that the file descriptor is well formed. bool DIFile::Verify() const { @@ -595,56 +615,77 @@ bool DIImportedEntity::Verify() const { (DbgNode->getNumOperands() == 4 || DbgNode->getNumOperands() == 5); } -/// getOriginalTypeSize - If this type is derived from a base type then -/// return base type size. -uint64_t DIDerivedType::getOriginalTypeSize() const { - unsigned Tag = getTag(); - - if (Tag != dwarf::DW_TAG_member && Tag != dwarf::DW_TAG_typedef && - Tag != dwarf::DW_TAG_const_type && Tag != dwarf::DW_TAG_volatile_type && - Tag != dwarf::DW_TAG_restrict_type) - return getSizeInBits(); - - DIType BaseType = getTypeDerivedFrom(); - - // If this type is not derived from any type then take conservative approach. - if (!BaseType.isValid()) - return getSizeInBits(); - - // If this is a derived type, go ahead and get the base type, unless it's a - // reference then it's just the size of the field. Pointer types have no need - // of this since they're a different type of qualification on the type. - if (BaseType.getTag() == dwarf::DW_TAG_reference_type || - BaseType.getTag() == dwarf::DW_TAG_rvalue_reference_type) - return getSizeInBits(); - - if (BaseType.isDerivedType()) - return DIDerivedType(BaseType).getOriginalTypeSize(); - - return BaseType.getSizeInBits(); -} - /// getObjCProperty - Return property node, if this ivar is associated with one. MDNode *DIDerivedType::getObjCProperty() const { return getNodeField(DbgNode, 10); } +MDString *DICompositeType::getIdentifier() const { + return cast_or_null<MDString>(getField(DbgNode, 14)); +} + +#ifndef NDEBUG +static void VerifySubsetOf(const MDNode *LHS, const MDNode *RHS) { + for (unsigned i = 0; i != LHS->getNumOperands(); ++i) { + // Skip the 'empty' list (that's a single i32 0, rather than truly empty). + if (i == 0 && isa<ConstantInt>(LHS->getOperand(i))) + continue; + const MDNode *E = cast<MDNode>(LHS->getOperand(i)); + bool found = false; + for (unsigned j = 0; !found && j != RHS->getNumOperands(); ++j) + found = E == RHS->getOperand(j); + assert(found && "Losing a member during member list replacement"); + } +} +#endif + /// \brief Set the array of member DITypes. void DICompositeType::setTypeArray(DIArray Elements, DIArray TParams) { - assert((!TParams || DbgNode->getNumOperands() == 14) && + assert((!TParams || DbgNode->getNumOperands() == 15) && "If you're setting the template parameters this should include a slot " "for that!"); TrackingVH<MDNode> N(*this); - N->replaceOperandWith(10, Elements); + if (Elements) { +#ifndef NDEBUG + // Check that the new list of members contains all the old members as well. + if (const MDNode *El = cast_or_null<MDNode>(N->getOperand(10))) + VerifySubsetOf(El, Elements); +#endif + N->replaceOperandWith(10, Elements); + } if (TParams) N->replaceOperandWith(13, TParams); DbgNode = N; } +void DICompositeType::addMember(DIDescriptor D) { + SmallVector<llvm::Value *, 16> M; + DIArray OrigM = getTypeArray(); + unsigned Elements = OrigM.getNumElements(); + if (Elements == 1 && !OrigM.getElement(0)) + Elements = 0; + M.reserve(Elements + 1); + for (unsigned i = 0; i != Elements; ++i) + M.push_back(OrigM.getElement(i)); + M.push_back(D); + setTypeArray(DIArray(MDNode::get(DbgNode->getContext(), M))); +} + +/// Generate a reference to this DIType. Uses the type identifier instead +/// of the actual MDNode if possible, to help type uniquing. +DIScopeRef DIScope::getRef() const { + if (!isCompositeType()) + return DIScopeRef(*this); + DICompositeType DTy(DbgNode); + if (!DTy.getIdentifier()) + return DIScopeRef(*this); + return DIScopeRef(DTy.getIdentifier()); +} + /// \brief Set the containing type. void DICompositeType::setContainingType(DICompositeType ContainingType) { TrackingVH<MDNode> N(*this); - N->replaceOperandWith(12, ContainingType); + N->replaceOperandWith(12, ContainingType.getRef()); DbgNode = N; } @@ -674,7 +715,7 @@ bool DISubprogram::describes(const Function *F) { } unsigned DISubprogram::isOptimized() const { - assert (DbgNode && "Invalid subprogram descriptor!"); + assert(DbgNode && "Invalid subprogram descriptor!"); if (DbgNode->getNumOperands() == 15) return getUnsignedField(14); return 0; @@ -694,25 +735,39 @@ Value *DITemplateValueParameter::getValue() const { // If the current node has a parent scope then return that, // else return an empty scope. -DIScope DIScope::getContext() const { +DIScopeRef DIScope::getContext() const { if (isType()) return DIType(DbgNode).getContext(); if (isSubprogram()) - return DISubprogram(DbgNode).getContext(); + return DIScopeRef(DISubprogram(DbgNode).getContext()); if (isLexicalBlock()) - return DILexicalBlock(DbgNode).getContext(); + return DIScopeRef(DILexicalBlock(DbgNode).getContext()); if (isLexicalBlockFile()) - return DILexicalBlockFile(DbgNode).getContext(); + return DIScopeRef(DILexicalBlockFile(DbgNode).getContext()); if (isNameSpace()) - return DINameSpace(DbgNode).getContext(); + return DIScopeRef(DINameSpace(DbgNode).getContext()); assert((isFile() || isCompileUnit()) && "Unhandled type of scope."); - return DIScope(); + return DIScopeRef(NULL); +} + +// If the scope node has a name, return that, else return an empty string. +StringRef DIScope::getName() const { + if (isType()) + return DIType(DbgNode).getName(); + if (isSubprogram()) + return DISubprogram(DbgNode).getName(); + if (isNameSpace()) + return DINameSpace(DbgNode).getName(); + assert((isLexicalBlock() || isLexicalBlockFile() || isFile() || + isCompileUnit()) && + "Unhandled type of scope."); + return StringRef(); } StringRef DIScope::getFilename() const { @@ -748,7 +803,6 @@ DIArray DICompileUnit::getSubprograms() const { return DIArray(getNodeField(DbgNode, 9)); } - DIArray DICompileUnit::getGlobalVariables() const { if (!DbgNode || DbgNode->getNumOperands() < 13) return DIArray(); @@ -813,8 +867,7 @@ DIVariable llvm::createInlinedVariable(MDNode *DV, MDNode *InlinedScope, SmallVector<Value *, 16> Elts; // Insert inlined scope as 7th element. for (unsigned i = 0, e = DV->getNumOperands(); i != e; ++i) - i == 7 ? Elts.push_back(InlinedScope) : - Elts.push_back(DV->getOperand(i)); + i == 7 ? Elts.push_back(InlinedScope) : Elts.push_back(DV->getOperand(i)); return DIVariable(MDNode::get(VMContext, Elts)); } @@ -823,9 +876,8 @@ DIVariable llvm::cleanseInlinedVariable(MDNode *DV, LLVMContext &VMContext) { SmallVector<Value *, 16> Elts; // Insert inlined scope as 7th element. for (unsigned i = 0, e = DV->getNumOperands(); i != e; ++i) - i == 7 ? - Elts.push_back(Constant::getNullValue(Type::getInt32Ty(VMContext))): - Elts.push_back(DV->getOperand(i)); + i == 7 ? Elts.push_back(Constant::getNullValue(Type::getInt32Ty(VMContext))) + : Elts.push_back(DV->getOperand(i)); return DIVariable(MDNode::get(VMContext, Elts)); } @@ -849,23 +901,42 @@ DICompositeType llvm::getDICompositeType(DIType T) { if (T.isCompositeType()) return DICompositeType(T); - if (T.isDerivedType()) - return getDICompositeType(DIDerivedType(T).getTypeDerivedFrom()); + if (T.isDerivedType()) { + // This function is currently used by dragonegg and dragonegg does + // not generate identifier for types, so using an empty map to resolve + // DerivedFrom should be fine. + DITypeIdentifierMap EmptyMap; + return getDICompositeType( + DIDerivedType(T).getTypeDerivedFrom().resolve(EmptyMap)); + } return DICompositeType(); } -/// isSubprogramContext - Return true if Context is either a subprogram -/// or another context nested inside a subprogram. -bool llvm::isSubprogramContext(const MDNode *Context) { - if (!Context) - return false; - DIDescriptor D(Context); - if (D.isSubprogram()) - return true; - if (D.isType()) - return isSubprogramContext(DIType(Context).getContext()); - return false; +/// Update DITypeIdentifierMap by going through retained types of each CU. +DITypeIdentifierMap +llvm::generateDITypeIdentifierMap(const NamedMDNode *CU_Nodes) { + DITypeIdentifierMap Map; + for (unsigned CUi = 0, CUe = CU_Nodes->getNumOperands(); CUi != CUe; ++CUi) { + DICompileUnit CU(CU_Nodes->getOperand(CUi)); + DIArray Retain = CU.getRetainedTypes(); + for (unsigned Ti = 0, Te = Retain.getNumElements(); Ti != Te; ++Ti) { + if (!Retain.getElement(Ti).isCompositeType()) + continue; + DICompositeType Ty(Retain.getElement(Ti)); + if (MDString *TypeId = Ty.getIdentifier()) { + // Definition has priority over declaration. + // Try to insert (TypeId, Ty) to Map. + std::pair<DITypeIdentifierMap::iterator, bool> P = + Map.insert(std::make_pair(TypeId, Ty)); + // If TypeId already exists in Map and this is a definition, replace + // whatever we had (declaration or definition) with the definition. + if (!P.second && !Ty.isForwardDecl()) + P.first->second = Ty; + } + } + } + return Map; } //===----------------------------------------------------------------------===// @@ -879,10 +950,21 @@ void DebugInfoFinder::reset() { TYs.clear(); Scopes.clear(); NodesSeen.clear(); + TypeIdentifierMap.clear(); + TypeMapInitialized = false; +} + +void DebugInfoFinder::InitializeTypeMap(const Module &M) { + if (!TypeMapInitialized) + if (NamedMDNode *CU_Nodes = M.getNamedMetadata("llvm.dbg.cu")) { + TypeIdentifierMap = generateDITypeIdentifierMap(CU_Nodes); + TypeMapInitialized = true; + } } /// processModule - Process entire module and collect debug info. void DebugInfoFinder::processModule(const Module &M) { + InitializeTypeMap(M); if (NamedMDNode *CU_Nodes = M.getNamedMetadata("llvm.dbg.cu")) { for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) { DICompileUnit CU(CU_Nodes->getOperand(i)); @@ -904,27 +986,38 @@ void DebugInfoFinder::processModule(const Module &M) { DIArray RetainedTypes = CU.getRetainedTypes(); for (unsigned i = 0, e = RetainedTypes.getNumElements(); i != e; ++i) processType(DIType(RetainedTypes.getElement(i))); - // FIXME: We really shouldn't be bailing out after visiting just one CU - return; + DIArray Imports = CU.getImportedEntities(); + for (unsigned i = 0, e = Imports.getNumElements(); i != e; ++i) { + DIImportedEntity Import = DIImportedEntity(Imports.getElement(i)); + DIDescriptor Entity = Import.getEntity(); + if (Entity.isType()) + processType(DIType(Entity)); + else if (Entity.isSubprogram()) + processSubprogram(DISubprogram(Entity)); + else if (Entity.isNameSpace()) + processScope(DINameSpace(Entity).getContext()); + } } } } /// processLocation - Process DILocation. -void DebugInfoFinder::processLocation(DILocation Loc) { - if (!Loc) return; +void DebugInfoFinder::processLocation(const Module &M, DILocation Loc) { + if (!Loc) + return; + InitializeTypeMap(M); processScope(Loc.getScope()); - processLocation(Loc.getOrigLocation()); + processLocation(M, Loc.getOrigLocation()); } /// processType - Process DIType. void DebugInfoFinder::processType(DIType DT) { if (!addType(DT)) return; - processScope(DT.getContext()); + processScope(DT.getContext().resolve(TypeIdentifierMap)); if (DT.isCompositeType()) { DICompositeType DCT(DT); - processType(DCT.getTypeDerivedFrom()); + processType(DCT.getTypeDerivedFrom().resolve(TypeIdentifierMap)); DIArray DA = DCT.getTypeArray(); for (unsigned i = 0, e = DA.getNumElements(); i != e; ++i) { DIDescriptor D = DA.getElement(i); @@ -935,7 +1028,7 @@ void DebugInfoFinder::processType(DIType DT) { } } else if (DT.isDerivedType()) { DIDerivedType DDT(DT); - processType(DDT.getTypeDerivedFrom()); + processType(DDT.getTypeDerivedFrom().resolve(TypeIdentifierMap)); } } @@ -975,8 +1068,7 @@ void DebugInfoFinder::processLexicalBlock(DILexicalBlock LB) { else if (Context.isLexicalBlockFile()) { DILexicalBlockFile DBF = DILexicalBlockFile(Context); return processLexicalBlock(DILexicalBlock(DBF.getScope())); - } - else + } else return processSubprogram(DISubprogram(Context)); } @@ -984,14 +1076,30 @@ void DebugInfoFinder::processLexicalBlock(DILexicalBlock LB) { void DebugInfoFinder::processSubprogram(DISubprogram SP) { if (!addSubprogram(SP)) return; - processScope(SP.getContext()); + processScope(SP.getContext().resolve(TypeIdentifierMap)); processType(SP.getType()); + DIArray TParams = SP.getTemplateParams(); + for (unsigned I = 0, E = TParams.getNumElements(); I != E; ++I) { + DIDescriptor Element = TParams.getElement(I); + if (Element.isTemplateTypeParameter()) { + DITemplateTypeParameter TType(Element); + processScope(TType.getContext().resolve(TypeIdentifierMap)); + processType(TType.getType().resolve(TypeIdentifierMap)); + } else if (Element.isTemplateValueParameter()) { + DITemplateValueParameter TVal(Element); + processScope(TVal.getContext().resolve(TypeIdentifierMap)); + processType(TVal.getType().resolve(TypeIdentifierMap)); + } + } } /// processDeclare - Process DbgDeclareInst. -void DebugInfoFinder::processDeclare(const DbgDeclareInst *DDI) { +void DebugInfoFinder::processDeclare(const Module &M, + const DbgDeclareInst *DDI) { MDNode *N = dyn_cast<MDNode>(DDI->getVariable()); - if (!N) return; + if (!N) + return; + InitializeTypeMap(M); DIDescriptor DV(N); if (!DV.isVariable()) @@ -1003,9 +1111,11 @@ void DebugInfoFinder::processDeclare(const DbgDeclareInst *DDI) { processType(DIVariable(N).getType()); } -void DebugInfoFinder::processValue(const DbgValueInst *DVI) { +void DebugInfoFinder::processValue(const Module &M, const DbgValueInst *DVI) { MDNode *N = dyn_cast<MDNode>(DVI->getVariable()); - if (!N) return; + if (!N) + return; + InitializeTypeMap(M); DIDescriptor DV(N); if (!DV.isVariable()) @@ -1083,12 +1193,14 @@ bool DebugInfoFinder::addScope(DIScope Scope) { /// dump - Print descriptor to dbgs() with a newline. void DIDescriptor::dump() const { - print(dbgs()); dbgs() << '\n'; + print(dbgs()); + dbgs() << '\n'; } /// print - Print descriptor. void DIDescriptor::print(raw_ostream &OS) const { - if (!DbgNode) return; + if (!DbgNode) + return; if (const char *Tag = dwarf::TagString(getTag())) OS << "[ " << Tag << " ]"; @@ -1150,7 +1262,8 @@ void DIEnumerator::printInternal(raw_ostream &OS) const { } void DIType::printInternal(raw_ostream &OS) const { - if (!DbgNode) return; + if (!DbgNode) + return; StringRef Res = getName(); if (!Res.empty()) @@ -1158,13 +1271,11 @@ void DIType::printInternal(raw_ostream &OS) const { // TODO: Print context? - OS << " [line " << getLineNumber() - << ", size " << getSizeInBits() - << ", align " << getAlignInBits() - << ", offset " << getOffsetInBits(); + OS << " [line " << getLineNumber() << ", size " << getSizeInBits() + << ", align " << getAlignInBits() << ", offset " << getOffsetInBits(); if (isBasicType()) if (const char *Enc = - dwarf::AttributeEncodingString(DIBasicType(DbgNode).getEncoding())) + dwarf::AttributeEncodingString(DIBasicType(DbgNode).getEncoding())) OS << ", enc " << Enc; OS << "]"; @@ -1260,16 +1371,15 @@ void DIObjCProperty::printInternal(raw_ostream &OS) const { if (!Name.empty()) OS << " [" << Name << ']'; - OS << " [line " << getLineNumber() - << ", properties " << getUnsignedField(6) << ']'; + OS << " [line " << getLineNumber() << ", properties " << getUnsignedField(6) + << ']'; } static void printDebugLoc(DebugLoc DL, raw_ostream &CommentOS, const LLVMContext &Ctx) { - if (!DL.isUnknown()) { // Print source line info. + if (!DL.isUnknown()) { // Print source line info. DIScope Scope(DL.getScope(Ctx)); - assert(Scope.isScope() && - "Scope of a DebugLoc should be a DIScope."); + assert(Scope.isScope() && "Scope of a DebugLoc should be a DIScope."); // Omit the directory, because it's likely to be long and uninteresting. CommentOS << Scope.getFilename(); CommentOS << ':' << DL.getLine(); @@ -1298,3 +1408,81 @@ void DIVariable::printExtendedName(raw_ostream &OS) const { } } } + +/// Specialize constructor to make sure it has the correct type. +template <> DIRef<DIScope>::DIRef(const Value *V) : Val(V) { + assert(isScopeRef(V) && "DIScopeRef should be a MDString or MDNode"); +} +template <> DIRef<DIType>::DIRef(const Value *V) : Val(V) { + assert(isTypeRef(V) && "DITypeRef should be a MDString or MDNode"); +} + +/// Specialize getFieldAs to handle fields that are references to DIScopes. +template <> +DIScopeRef DIDescriptor::getFieldAs<DIScopeRef>(unsigned Elt) const { + return DIScopeRef(getField(DbgNode, Elt)); +} +/// Specialize getFieldAs to handle fields that are references to DITypes. +template <> DITypeRef DIDescriptor::getFieldAs<DITypeRef>(unsigned Elt) const { + return DITypeRef(getField(DbgNode, Elt)); +} + +/// Strip debug info in the module if it exists. +/// To do this, we remove all calls to the debugger intrinsics and any named +/// metadata for debugging. We also remove debug locations for instructions. +/// Return true if module is modified. +bool llvm::StripDebugInfo(Module &M) { + + bool Changed = false; + + // Remove all of the calls to the debugger intrinsics, and remove them from + // the module. + if (Function *Declare = M.getFunction("llvm.dbg.declare")) { + while (!Declare->use_empty()) { + CallInst *CI = cast<CallInst>(Declare->use_back()); + CI->eraseFromParent(); + } + Declare->eraseFromParent(); + Changed = true; + } + + if (Function *DbgVal = M.getFunction("llvm.dbg.value")) { + while (!DbgVal->use_empty()) { + CallInst *CI = cast<CallInst>(DbgVal->use_back()); + CI->eraseFromParent(); + } + DbgVal->eraseFromParent(); + Changed = true; + } + + for (Module::named_metadata_iterator NMI = M.named_metadata_begin(), + NME = M.named_metadata_end(); NMI != NME;) { + NamedMDNode *NMD = NMI; + ++NMI; + if (NMD->getName().startswith("llvm.dbg.")) { + NMD->eraseFromParent(); + Changed = true; + } + } + + for (Module::iterator MI = M.begin(), ME = M.end(); MI != ME; ++MI) + for (Function::iterator FI = MI->begin(), FE = MI->end(); FI != FE; + ++FI) + for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); BI != BE; + ++BI) { + if (!BI->getDebugLoc().isUnknown()) { + Changed = true; + BI->setDebugLoc(DebugLoc()); + } + } + + return Changed; +} + +/// Return Debug Info Metadata Version by checking module flags. +unsigned llvm::getDebugMetadataVersionFromModule(const Module &M) { + Value *Val = M.getModuleFlag("Debug Info Version"); + if (!Val) + return 0; + return cast<ConstantInt>(Val)->getZExtValue(); +} diff --git a/lib/IR/Function.cpp b/lib/IR/Function.cpp index bf9d949..e8a2402 100644 --- a/lib/IR/Function.cpp +++ b/lib/IR/Function.cpp @@ -276,6 +276,9 @@ void Function::dropAllReferences() { // blockaddresses, but BasicBlock's destructor takes care of those. while (!BasicBlocks.empty()) BasicBlocks.begin()->eraseFromParent(); + + // Prefix data is stored in a side table. + setPrefixData(0); } void Function::addAttribute(unsigned i, Attribute::AttrKind attr) { @@ -351,6 +354,10 @@ void Function::copyAttributesFrom(const GlobalValue *Src) { setGC(SrcF->getGC()); else clearGC(); + if (SrcF->hasPrefixData()) + setPrefixData(SrcF->getPrefixData()); + else + setPrefixData(0); } /// getIntrinsicID - This method returns the ID number of the specified @@ -446,7 +453,9 @@ enum IIT_Info { IIT_STRUCT5 = 22, IIT_EXTEND_VEC_ARG = 23, IIT_TRUNC_VEC_ARG = 24, - IIT_ANYPTR = 25 + IIT_ANYPTR = 25, + IIT_V1 = 26, + IIT_VARARG = 27 }; @@ -460,6 +469,9 @@ static void DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos, case IIT_Done: OutputTable.push_back(IITDescriptor::get(IITDescriptor::Void, 0)); return; + case IIT_VARARG: + OutputTable.push_back(IITDescriptor::get(IITDescriptor::VarArg, 0)); + return; case IIT_MMX: OutputTable.push_back(IITDescriptor::get(IITDescriptor::MMX, 0)); return; @@ -490,6 +502,10 @@ static void DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos, case IIT_I64: OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer, 64)); return; + case IIT_V1: + OutputTable.push_back(IITDescriptor::get(IITDescriptor::Vector, 1)); + DecodeIITType(NextElt, Infos, OutputTable); + return; case IIT_V2: OutputTable.push_back(IITDescriptor::get(IITDescriptor::Vector, 2)); DecodeIITType(NextElt, Infos, OutputTable); @@ -601,6 +617,7 @@ static Type *DecodeFixedType(ArrayRef<Intrinsic::IITDescriptor> &Infos, switch (D.Kind) { case IITDescriptor::Void: return Type::getVoidTy(Context); + case IITDescriptor::VarArg: return Type::getVoidTy(Context); case IITDescriptor::MMX: return Type::getX86_MMXTy(Context); case IITDescriptor::Metadata: return Type::getMetadataTy(Context); case IITDescriptor::Half: return Type::getHalfTy(Context); @@ -720,3 +737,32 @@ bool Function::callsFunctionThatReturnsTwice() const { return false; } + +Constant *Function::getPrefixData() const { + assert(hasPrefixData()); + const LLVMContextImpl::PrefixDataMapTy &PDMap = + getContext().pImpl->PrefixDataMap; + assert(PDMap.find(this) != PDMap.end()); + return cast<Constant>(PDMap.find(this)->second->getReturnValue()); +} + +void Function::setPrefixData(Constant *PrefixData) { + if (!PrefixData && !hasPrefixData()) + return; + + unsigned SCData = getSubclassDataFromValue(); + LLVMContextImpl::PrefixDataMapTy &PDMap = getContext().pImpl->PrefixDataMap; + ReturnInst *&PDHolder = PDMap[this]; + if (PrefixData) { + if (PDHolder) + PDHolder->setOperand(0, PrefixData); + else + PDHolder = ReturnInst::Create(getContext(), PrefixData); + SCData |= 2; + } else { + delete PDHolder; + PDMap.erase(this); + SCData &= ~2; + } + setValueSubclassData(SCData); +} diff --git a/lib/IR/GCOV.cpp b/lib/IR/GCOV.cpp index e9baa5c..f0f8c7d 100644 --- a/lib/IR/GCOV.cpp +++ b/lib/IR/GCOV.cpp @@ -7,14 +7,16 @@ // //===----------------------------------------------------------------------===// // -// GCOV implements the interface to read and write coverage files that use +// GCOV implements the interface to read and write coverage files that use // 'gcov' format. // //===----------------------------------------------------------------------===// +#include "llvm/Support/Debug.h" #include "llvm/Support/GCOV.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/Support/Format.h" #include "llvm/Support/MemoryObject.h" #include "llvm/Support/system_error.h" using namespace llvm; @@ -43,25 +45,45 @@ bool GCOVFile::read(GCOVBuffer &Buffer) { if (Format == GCOV::InvalidGCOV) return false; - unsigned i = 0; - while (1) { - GCOVFunction *GFun = NULL; - if (isGCDAFile(Format)) { - // Use existing function while reading .gcda file. - assert(i < Functions.size() && ".gcda data does not match .gcno data"); - GFun = Functions[i]; - } else if (isGCNOFile(Format)){ - GFun = new GCOVFunction(); + if (isGCNOFile(Format)) { + while (true) { + if (!Buffer.readFunctionTag()) break; + GCOVFunction *GFun = new GCOVFunction(); + if (!GFun->read(Buffer, Format)) + return false; Functions.push_back(GFun); } - if (!GFun || !GFun->read(Buffer, Format)) - break; - ++i; } + else if (isGCDAFile(Format)) { + for (size_t i = 0, e = Functions.size(); i < e; ++i) { + if (!Buffer.readFunctionTag()) { + errs() << "Unexpected number of functions.\n"; + return false; + } + if (!Functions[i]->read(Buffer, Format)) + return false; + } + if (Buffer.readObjectTag()) { + uint32_t Length; + uint32_t Dummy; + if (!Buffer.readInt(Length)) return false; + if (!Buffer.readInt(Dummy)) return false; // checksum + if (!Buffer.readInt(Dummy)) return false; // num + if (!Buffer.readInt(RunCount)) return false;; + Buffer.advanceCursor(Length-3); + } + while (Buffer.readProgramTag()) { + uint32_t Length; + if (!Buffer.readInt(Length)) return false; + Buffer.advanceCursor(Length); + ++ProgramCount; + } + } + return true; } -/// dump - Dump GCOVFile content on standard out for debugging purposes. +/// dump - Dump GCOVFile content to dbgs() for debugging purposes. void GCOVFile::dump() { for (SmallVectorImpl<GCOVFunction *>::iterator I = Functions.begin(), E = Functions.end(); I != E; ++I) @@ -72,9 +94,10 @@ void GCOVFile::dump() { /// reading .gcno and .gcda files. void GCOVFile::collectLineCounts(FileInfo &FI) { for (SmallVectorImpl<GCOVFunction *>::iterator I = Functions.begin(), - E = Functions.end(); I != E; ++I) + E = Functions.end(); I != E; ++I) (*I)->collectLineCounts(FI); - FI.print(); + FI.setRunCount(RunCount); + FI.setProgramCount(ProgramCount); } //===----------------------------------------------------------------------===// @@ -85,76 +108,121 @@ GCOVFunction::~GCOVFunction() { DeleteContainerPointers(Blocks); } -/// read - Read a aunction from the buffer. Return false if buffer cursor +/// read - Read a function from the buffer. Return false if buffer cursor /// does not point to a function tag. bool GCOVFunction::read(GCOVBuffer &Buff, GCOV::GCOVFormat Format) { - if (!Buff.readFunctionTag()) - return false; - - Buff.readInt(); // Function header length - Ident = Buff.readInt(); - Buff.readInt(); // Checksum #1 + uint32_t Dummy; + if (!Buff.readInt(Dummy)) return false; // Function header length + if (!Buff.readInt(Ident)) return false; + if (!Buff.readInt(Dummy)) return false; // Checksum #1 if (Format != GCOV::GCNO_402 && Format != GCOV::GCDA_402) - Buff.readInt(); // Checksum #2 + if (!Buff.readInt(Dummy)) return false; // Checksum #2 + + if (!Buff.readString(Name)) return false; - Name = Buff.readString(); if (Format == GCOV::GCNO_402 || Format == GCOV::GCNO_404) - Filename = Buff.readString(); + if (!Buff.readString(Filename)) return false; if (Format == GCOV::GCDA_402 || Format == GCOV::GCDA_404) { - Buff.readArcTag(); - uint32_t Count = Buff.readInt() / 2; - for (unsigned i = 0, e = Count; i != e; ++i) { - Blocks[i]->addCount(Buff.readInt64()); + if (!Buff.readArcTag()) { + errs() << "Arc tag not found.\n"; + return false; + } + uint32_t Count; + if (!Buff.readInt(Count)) return false; + Count /= 2; + + // This for loop adds the counts for each block. A second nested loop is + // required to combine the edge counts that are contained in the GCDA file. + for (uint32_t Line = 0; Count > 0; ++Line) { + if (Line >= Blocks.size()) { + errs() << "Unexpected number of edges.\n"; + return false; + } + GCOVBlock &Block = *Blocks[Line]; + for (size_t Edge = 0, End = Block.getNumEdges(); Edge < End; ++Edge) { + if (Count == 0) { + errs() << "Unexpected number of edges.\n"; + return false; + } + uint64_t ArcCount; + if (!Buff.readInt64(ArcCount)) return false; + Block.addCount(ArcCount); + --Count; + } } return true; } - LineNumber = Buff.readInt(); + if (!Buff.readInt(LineNumber)) return false; // read blocks. - bool BlockTagFound = Buff.readBlockTag(); - (void)BlockTagFound; - assert(BlockTagFound && "Block Tag not found!"); - uint32_t BlockCount = Buff.readInt(); - for (int i = 0, e = BlockCount; i != e; ++i) { - Buff.readInt(); // Block flags; - Blocks.push_back(new GCOVBlock(i)); + if (!Buff.readBlockTag()) { + errs() << "Block tag not found.\n"; + return false; + } + uint32_t BlockCount; + if (!Buff.readInt(BlockCount)) return false; + for (uint32_t i = 0, e = BlockCount; i != e; ++i) { + if (!Buff.readInt(Dummy)) return false; // Block flags; + Blocks.push_back(new GCOVBlock(*this, i)); } // read edges. while (Buff.readEdgeTag()) { - uint32_t EdgeCount = (Buff.readInt() - 1) / 2; - uint32_t BlockNo = Buff.readInt(); - assert(BlockNo < BlockCount && "Unexpected Block number!"); - for (int i = 0, e = EdgeCount; i != e; ++i) { - Blocks[BlockNo]->addEdge(Buff.readInt()); - Buff.readInt(); // Edge flag + uint32_t EdgeCount; + if (!Buff.readInt(EdgeCount)) return false; + EdgeCount = (EdgeCount - 1) / 2; + uint32_t BlockNo; + if (!Buff.readInt(BlockNo)) return false; + if (BlockNo >= BlockCount) { + errs() << "Unexpected block number.\n"; + return false; + } + for (uint32_t i = 0, e = EdgeCount; i != e; ++i) { + uint32_t Dst; + if (!Buff.readInt(Dst)) return false; + Blocks[BlockNo]->addEdge(Dst); + if (!Buff.readInt(Dummy)) return false; // Edge flag } } // read line table. while (Buff.readLineTag()) { - uint32_t LineTableLength = Buff.readInt(); - uint32_t Size = Buff.getCursor() + LineTableLength*4; - uint32_t BlockNo = Buff.readInt(); - assert(BlockNo < BlockCount && "Unexpected Block number!"); + uint32_t LineTableLength; + if (!Buff.readInt(LineTableLength)) return false; + uint32_t EndPos = Buff.getCursor() + LineTableLength*4; + uint32_t BlockNo; + if (!Buff.readInt(BlockNo)) return false; + if (BlockNo >= BlockCount) { + errs() << "Unexpected block number.\n"; + return false; + } GCOVBlock *Block = Blocks[BlockNo]; - Buff.readInt(); // flag - while (Buff.getCursor() != (Size - 4)) { - StringRef Filename = Buff.readString(); - if (Buff.getCursor() == (Size - 4)) break; - while (uint32_t L = Buff.readInt()) - Block->addLine(Filename, L); + if (!Buff.readInt(Dummy)) return false; // flag + while (Buff.getCursor() != (EndPos - 4)) { + StringRef F; + if (!Buff.readString(F)) return false; + if (F != Filename) { + errs() << "Multiple sources for a single basic block.\n"; + return false; + } + if (Buff.getCursor() == (EndPos - 4)) break; + while (true) { + uint32_t Line; + if (!Buff.readInt(Line)) return false; + if (!Line) break; + Block->addLine(Line); + } } - Buff.readInt(); // flag + if (!Buff.readInt(Dummy)) return false; // flag } return true; } -/// dump - Dump GCOVFunction content on standard out for debugging purposes. +/// dump - Dump GCOVFunction content to dbgs() for debugging purposes. void GCOVFunction::dump() { - outs() << "===== " << Name << " @ " << Filename << ":" << LineNumber << "\n"; + dbgs() << "===== " << Name << " @ " << Filename << ":" << LineNumber << "\n"; for (SmallVectorImpl<GCOVBlock *>::iterator I = Blocks.begin(), E = Blocks.end(); I != E; ++I) (*I)->dump(); @@ -174,110 +242,73 @@ void GCOVFunction::collectLineCounts(FileInfo &FI) { /// ~GCOVBlock - Delete GCOVBlock and its content. GCOVBlock::~GCOVBlock() { Edges.clear(); - DeleteContainerSeconds(Lines); -} - -void GCOVBlock::addLine(StringRef Filename, uint32_t LineNo) { - GCOVLines *&LinesForFile = Lines[Filename]; - if (!LinesForFile) - LinesForFile = new GCOVLines(); - LinesForFile->add(LineNo); + Lines.clear(); } /// collectLineCounts - Collect line counts. This must be used after /// reading .gcno and .gcda files. void GCOVBlock::collectLineCounts(FileInfo &FI) { - for (StringMap<GCOVLines *>::iterator I = Lines.begin(), + for (SmallVectorImpl<uint32_t>::iterator I = Lines.begin(), E = Lines.end(); I != E; ++I) - I->second->collectLineCounts(FI, I->first(), Counter); + FI.addLineCount(Parent.getFilename(), *I, Counter); } -/// dump - Dump GCOVBlock content on standard out for debugging purposes. +/// dump - Dump GCOVBlock content to dbgs() for debugging purposes. void GCOVBlock::dump() { - outs() << "Block : " << Number << " Counter : " << Counter << "\n"; + dbgs() << "Block : " << Number << " Counter : " << Counter << "\n"; if (!Edges.empty()) { - outs() << "\tEdges : "; + dbgs() << "\tEdges : "; for (SmallVectorImpl<uint32_t>::iterator I = Edges.begin(), E = Edges.end(); I != E; ++I) - outs() << (*I) << ","; - outs() << "\n"; + dbgs() << (*I) << ","; + dbgs() << "\n"; } if (!Lines.empty()) { - outs() << "\tLines : "; - for (StringMap<GCOVLines *>::iterator LI = Lines.begin(), - LE = Lines.end(); LI != LE; ++LI) { - outs() << LI->first() << " -> "; - LI->second->dump(); - outs() << "\n"; - } + dbgs() << "\tLines : "; + for (SmallVectorImpl<uint32_t>::iterator I = Lines.begin(), + E = Lines.end(); I != E; ++I) + dbgs() << (*I) << ","; + dbgs() << "\n"; } } //===----------------------------------------------------------------------===// -// GCOVLines implementation. - -/// collectLineCounts - Collect line counts. This must be used after -/// reading .gcno and .gcda files. -void GCOVLines::collectLineCounts(FileInfo &FI, StringRef Filename, - uint32_t Count) { - for (SmallVectorImpl<uint32_t>::iterator I = Lines.begin(), - E = Lines.end(); I != E; ++I) - FI.addLineCount(Filename, *I, Count); -} - -/// dump - Dump GCOVLines content on standard out for debugging purposes. -void GCOVLines::dump() { - for (SmallVectorImpl<uint32_t>::iterator I = Lines.begin(), - E = Lines.end(); I != E; ++I) - outs() << (*I) << ","; -} - -//===----------------------------------------------------------------------===// // FileInfo implementation. -/// addLineCount - Add line count for the given line number in a file. -void FileInfo::addLineCount(StringRef Filename, uint32_t Line, uint32_t Count) { - if (LineInfo.find(Filename) == LineInfo.end()) { - OwningPtr<MemoryBuffer> Buff; - if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename, Buff)) { - errs() << Filename << ": " << ec.message() << "\n"; - return; - } - StringRef AllLines = Buff.take()->getBuffer(); - LineCounts L(AllLines.count('\n')+2); - L[Line-1] = Count; - LineInfo[Filename] = L; - return; - } - LineCounts &L = LineInfo[Filename]; - L[Line-1] = Count; -} - /// print - Print source files with collected line count information. -void FileInfo::print() { +void FileInfo::print(raw_fd_ostream &OS, StringRef gcnoFile, + StringRef gcdaFile) { for (StringMap<LineCounts>::iterator I = LineInfo.begin(), E = LineInfo.end(); I != E; ++I) { StringRef Filename = I->first(); - outs() << Filename << "\n"; + OS << " -: 0:Source:" << Filename << "\n"; + OS << " -: 0:Graph:" << gcnoFile << "\n"; + OS << " -: 0:Data:" << gcdaFile << "\n"; + OS << " -: 0:Runs:" << RunCount << "\n"; + OS << " -: 0:Programs:" << ProgramCount << "\n"; LineCounts &L = LineInfo[Filename]; OwningPtr<MemoryBuffer> Buff; if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename, Buff)) { errs() << Filename << ": " << ec.message() << "\n"; return; } - StringRef AllLines = Buff.take()->getBuffer(); - for (unsigned i = 0, e = L.size(); i != e; ++i) { - if (L[i]) - outs() << L[i] << ":\t"; - else - outs() << " :\t"; + StringRef AllLines = Buff->getBuffer(); + uint32_t i = 0; + while (!AllLines.empty()) { + if (L.find(i) != L.end()) { + if (L[i] == 0) + OS << " #####:"; + else + OS << format("%9" PRIu64 ":", L[i]); + } else { + OS << " -:"; + } std::pair<StringRef, StringRef> P = AllLines.split('\n'); if (AllLines != P.first) - outs() << P.first; - outs() << "\n"; + OS << format("%5u:", i+1) << P.first; + OS << "\n"; AllLines = P.second; + ++i; } } } - - diff --git a/lib/IR/Globals.cpp b/lib/IR/Globals.cpp index 6d547f3..da3b02a 100644 --- a/lib/IR/Globals.cpp +++ b/lib/IR/Globals.cpp @@ -229,14 +229,14 @@ void GlobalAlias::setAliasee(Constant *Aliasee) { setOperand(0, Aliasee); } -const GlobalValue *GlobalAlias::getAliasedGlobal() const { - const Constant *C = getAliasee(); +GlobalValue *GlobalAlias::getAliasedGlobal() { + Constant *C = getAliasee(); if (C == 0) return 0; - if (const GlobalValue *GV = dyn_cast<GlobalValue>(C)) + if (GlobalValue *GV = dyn_cast<GlobalValue>(C)) return GV; - const ConstantExpr *CE = cast<ConstantExpr>(C); + ConstantExpr *CE = cast<ConstantExpr>(C); assert((CE->getOpcode() == Instruction::BitCast || CE->getOpcode() == Instruction::GetElementPtr) && "Unsupported aliasee"); @@ -244,18 +244,18 @@ const GlobalValue *GlobalAlias::getAliasedGlobal() const { return cast<GlobalValue>(CE->getOperand(0)); } -const GlobalValue *GlobalAlias::resolveAliasedGlobal(bool stopOnWeak) const { - SmallPtrSet<const GlobalValue*, 3> Visited; +GlobalValue *GlobalAlias::resolveAliasedGlobal(bool stopOnWeak) { + SmallPtrSet<GlobalValue*, 3> Visited; // Check if we need to stop early. if (stopOnWeak && mayBeOverridden()) return this; - const GlobalValue *GV = getAliasedGlobal(); + GlobalValue *GV = getAliasedGlobal(); Visited.insert(GV); // Iterate over aliasing chain, stopping on weak alias if necessary. - while (const GlobalAlias *GA = dyn_cast<GlobalAlias>(GV)) { + while (GlobalAlias *GA = dyn_cast<GlobalAlias>(GV)) { if (stopOnWeak && GA->mayBeOverridden()) break; diff --git a/lib/IR/Instruction.cpp b/lib/IR/Instruction.cpp index 2b5a0b3..a7773c4 100644 --- a/lib/IR/Instruction.cpp +++ b/lib/IR/Instruction.cpp @@ -223,18 +223,19 @@ const char *Instruction::getOpcodeName(unsigned OpCode) { case GetElementPtr: return "getelementptr"; // Convert instructions... - case Trunc: return "trunc"; - case ZExt: return "zext"; - case SExt: return "sext"; - case FPTrunc: return "fptrunc"; - case FPExt: return "fpext"; - case FPToUI: return "fptoui"; - case FPToSI: return "fptosi"; - case UIToFP: return "uitofp"; - case SIToFP: return "sitofp"; - case IntToPtr: return "inttoptr"; - case PtrToInt: return "ptrtoint"; - case BitCast: return "bitcast"; + case Trunc: return "trunc"; + case ZExt: return "zext"; + case SExt: return "sext"; + case FPTrunc: return "fptrunc"; + case FPExt: return "fpext"; + case FPToUI: return "fptoui"; + case FPToSI: return "fptosi"; + case UIToFP: return "uitofp"; + case SIToFP: return "sitofp"; + case IntToPtr: return "inttoptr"; + case PtrToInt: return "ptrtoint"; + case BitCast: return "bitcast"; + case AddrSpaceCast: return "addrspacecast"; // Other instructions... case ICmp: return "icmp"; diff --git a/lib/IR/Instructions.cpp b/lib/IR/Instructions.cpp index 205cb43..8a6b77b 100644 --- a/lib/IR/Instructions.cpp +++ b/lib/IR/Instructions.cpp @@ -2095,7 +2095,9 @@ bool CastInst::isNoopCast(Instruction::CastOps Opcode, case Instruction::SIToFP: case Instruction::FPToUI: case Instruction::FPToSI: - return false; // These always modify bits + case Instruction::AddrSpaceCast: + // TODO: Target informations may give a more accurate answer here. + return false; case Instruction::BitCast: return true; // BitCast never modifies bits. case Instruction::PtrToInt: @@ -2137,44 +2139,46 @@ unsigned CastInst::isEliminableCastPair( // ZEXT < Integral Unsigned Integer Any // SEXT < Integral Signed Integer Any // FPTOUI n/a FloatPt n/a Integral Unsigned - // FPTOSI n/a FloatPt n/a Integral Signed - // UITOFP n/a Integral Unsigned FloatPt n/a - // SITOFP n/a Integral Signed FloatPt n/a - // FPTRUNC > FloatPt n/a FloatPt n/a - // FPEXT < FloatPt n/a FloatPt n/a + // FPTOSI n/a FloatPt n/a Integral Signed + // UITOFP n/a Integral Unsigned FloatPt n/a + // SITOFP n/a Integral Signed FloatPt n/a + // FPTRUNC > FloatPt n/a FloatPt n/a + // FPEXT < FloatPt n/a FloatPt n/a // PTRTOINT n/a Pointer n/a Integral Unsigned // INTTOPTR n/a Integral Unsigned Pointer n/a - // BITCAST = FirstClass n/a FirstClass n/a + // BITCAST = FirstClass n/a FirstClass n/a + // ADDRSPCST n/a Pointer n/a Pointer n/a // // NOTE: some transforms are safe, but we consider them to be non-profitable. // For example, we could merge "fptoui double to i32" + "zext i32 to i64", // into "fptoui double to i64", but this loses information about the range - // of the produced value (we no longer know the top-part is all zeros). + // of the produced value (we no longer know the top-part is all zeros). // Further this conversion is often much more expensive for typical hardware, - // and causes issues when building libgcc. We disallow fptosi+sext for the + // and causes issues when building libgcc. We disallow fptosi+sext for the // same reason. - const unsigned numCastOps = + const unsigned numCastOps = Instruction::CastOpsEnd - Instruction::CastOpsBegin; static const uint8_t CastResults[numCastOps][numCastOps] = { - // T F F U S F F P I B -+ - // R Z S P P I I T P 2 N T | - // U E E 2 2 2 2 R E I T C +- secondOp - // N X X U S F F N X N 2 V | - // C T T I I P P C T T P T -+ - { 1, 0, 0,99,99, 0, 0,99,99,99, 0, 3 }, // Trunc -+ - { 8, 1, 9,99,99, 2, 0,99,99,99, 2, 3 }, // ZExt | - { 8, 0, 1,99,99, 0, 2,99,99,99, 0, 3 }, // SExt | - { 0, 0, 0,99,99, 0, 0,99,99,99, 0, 3 }, // FPToUI | - { 0, 0, 0,99,99, 0, 0,99,99,99, 0, 3 }, // FPToSI | - { 99,99,99, 0, 0,99,99, 0, 0,99,99, 4 }, // UIToFP +- firstOp - { 99,99,99, 0, 0,99,99, 0, 0,99,99, 4 }, // SIToFP | - { 99,99,99, 0, 0,99,99, 1, 0,99,99, 4 }, // FPTrunc | - { 99,99,99, 2, 2,99,99,10, 2,99,99, 4 }, // FPExt | - { 1, 0, 0,99,99, 0, 0,99,99,99, 7, 3 }, // PtrToInt | - { 99,99,99,99,99,99,99,99,99,13,99,12 }, // IntToPtr | - { 5, 5, 5, 6, 6, 5, 5, 6, 6,11, 5, 1 }, // BitCast -+ + // T F F U S F F P I B A -+ + // R Z S P P I I T P 2 N T S | + // U E E 2 2 2 2 R E I T C C +- secondOp + // N X X U S F F N X N 2 V V | + // C T T I I P P C T T P T T -+ + { 1, 0, 0,99,99, 0, 0,99,99,99, 0, 3, 0}, // Trunc -+ + { 8, 1, 9,99,99, 2, 0,99,99,99, 2, 3, 0}, // ZExt | + { 8, 0, 1,99,99, 0, 2,99,99,99, 0, 3, 0}, // SExt | + { 0, 0, 0,99,99, 0, 0,99,99,99, 0, 3, 0}, // FPToUI | + { 0, 0, 0,99,99, 0, 0,99,99,99, 0, 3, 0}, // FPToSI | + { 99,99,99, 0, 0,99,99, 0, 0,99,99, 4, 0}, // UIToFP +- firstOp + { 99,99,99, 0, 0,99,99, 0, 0,99,99, 4, 0}, // SIToFP | + { 99,99,99, 0, 0,99,99, 1, 0,99,99, 4, 0}, // FPTrunc | + { 99,99,99, 2, 2,99,99,10, 2,99,99, 4, 0}, // FPExt | + { 1, 0, 0,99,99, 0, 0,99,99,99, 7, 3, 0}, // PtrToInt | + { 99,99,99,99,99,99,99,99,99,11,99,15, 0}, // IntToPtr | + { 5, 5, 5, 6, 6, 5, 5, 6, 6,16, 5, 1,14}, // BitCast | + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,13,12}, // AddrSpaceCast -+ }; - + // If either of the casts are a bitcast from scalar to vector, disallow the // merging. However, bitcast of A->B->A are allowed. bool isFirstBitcast = (firstOp == Instruction::BitCast); @@ -2191,47 +2195,50 @@ unsigned CastInst::isEliminableCastPair( [secondOp-Instruction::CastOpsBegin]; switch (ElimCase) { case 0: - // categorically disallowed + // Categorically disallowed. return 0; case 1: - // allowed, use first cast's opcode + // Allowed, use first cast's opcode. return firstOp; case 2: - // allowed, use second cast's opcode + // Allowed, use second cast's opcode. return secondOp; case 3: - // no-op cast in second op implies firstOp as long as the DestTy + // No-op cast in second op implies firstOp as long as the DestTy // is integer and we are not converting between a vector and a // non vector type. if (!SrcTy->isVectorTy() && DstTy->isIntegerTy()) return firstOp; return 0; case 4: - // no-op cast in second op implies firstOp as long as the DestTy + // No-op cast in second op implies firstOp as long as the DestTy // is floating point. if (DstTy->isFloatingPointTy()) return firstOp; return 0; case 5: - // no-op cast in first op implies secondOp as long as the SrcTy + // No-op cast in first op implies secondOp as long as the SrcTy // is an integer. if (SrcTy->isIntegerTy()) return secondOp; return 0; case 6: - // no-op cast in first op implies secondOp as long as the SrcTy + // No-op cast in first op implies secondOp as long as the SrcTy // is a floating point. if (SrcTy->isFloatingPointTy()) return secondOp; return 0; case 7: { + // Cannot simplify if address spaces are different! + if (SrcTy->getPointerAddressSpace() != DstTy->getPointerAddressSpace()) + return 0; + unsigned MidSize = MidTy->getScalarSizeInBits(); - // Check the address spaces first. If we know they are in the same address - // space, the pointer sizes must be the same so we can still fold this - // without knowing the actual sizes as long we know that the intermediate - // pointer is the largest possible pointer size. - if (MidSize == 64 && - SrcTy->getPointerAddressSpace() == DstTy->getPointerAddressSpace()) + // We can still fold this without knowing the actual sizes as long we + // know that the intermediate pointer is the largest possible + // pointer size. + // FIXME: Is this always true? + if (MidSize == 64) return Instruction::BitCast; // ptrtoint, inttoptr -> bitcast (ptr -> ptr) if int size is >= ptr size. @@ -2254,7 +2261,8 @@ unsigned CastInst::isEliminableCastPair( return firstOp; return secondOp; } - case 9: // zext, sext -> zext, because sext can't sign extend after zext + case 9: + // zext, sext -> zext, because sext can't sign extend after zext return Instruction::ZExt; case 10: // fpext followed by ftrunc is allowed if the bit size returned to is @@ -2263,46 +2271,6 @@ unsigned CastInst::isEliminableCastPair( return Instruction::BitCast; return 0; // If the types are not the same we can't eliminate it. case 11: { - // bitcast followed by ptrtoint is allowed as long as the bitcast is a - // pointer to pointer cast, and the pointers are the same size. - PointerType *SrcPtrTy = dyn_cast<PointerType>(SrcTy); - PointerType *MidPtrTy = dyn_cast<PointerType>(MidTy); - if (!SrcPtrTy || !MidPtrTy) - return 0; - - // If the address spaces are the same, we know they are the same size - // without size information - if (SrcPtrTy->getAddressSpace() == MidPtrTy->getAddressSpace()) - return secondOp; - - if (!SrcIntPtrTy || !MidIntPtrTy) - return 0; - - if (SrcIntPtrTy->getScalarSizeInBits() == - MidIntPtrTy->getScalarSizeInBits()) - return secondOp; - - return 0; - } - case 12: { - // inttoptr, bitcast -> inttoptr if bitcast is a ptr to ptr cast - // and the ptrs are to address spaces of the same size - PointerType *MidPtrTy = dyn_cast<PointerType>(MidTy); - PointerType *DstPtrTy = dyn_cast<PointerType>(DstTy); - if (!MidPtrTy || !DstPtrTy) - return 0; - - if (MidPtrTy->getAddressSpace() == DstPtrTy->getAddressSpace()) - return firstOp; - - if (MidIntPtrTy && - DstIntPtrTy && - MidIntPtrTy->getScalarSizeInBits() == - DstIntPtrTy->getScalarSizeInBits()) - return firstOp; - return 0; - } - case 13: { // inttoptr, ptrtoint -> bitcast if SrcSize<=PtrSize and SrcSize==DstSize if (!MidIntPtrTy) return 0; @@ -2313,8 +2281,65 @@ unsigned CastInst::isEliminableCastPair( return Instruction::BitCast; return 0; } + case 12: { + // addrspacecast, addrspacecast -> bitcast, if SrcAS == DstAS + // addrspacecast, addrspacecast -> addrspacecast, if SrcAS != DstAS + if (SrcTy->getPointerAddressSpace() != DstTy->getPointerAddressSpace()) + return Instruction::AddrSpaceCast; + return Instruction::BitCast; + } + case 13: + // FIXME: this state can be merged with (1), but the following assert + // is useful to check the correcteness of the sequence due to semantic + // change of bitcast. + assert( + SrcTy->isPtrOrPtrVectorTy() && + MidTy->isPtrOrPtrVectorTy() && + DstTy->isPtrOrPtrVectorTy() && + SrcTy->getPointerAddressSpace() != MidTy->getPointerAddressSpace() && + MidTy->getPointerAddressSpace() == DstTy->getPointerAddressSpace() && + "Illegal addrspacecast, bitcast sequence!"); + // Allowed, use first cast's opcode + return firstOp; + case 14: + // FIXME: this state can be merged with (2), but the following assert + // is useful to check the correcteness of the sequence due to semantic + // change of bitcast. + assert( + SrcTy->isPtrOrPtrVectorTy() && + MidTy->isPtrOrPtrVectorTy() && + DstTy->isPtrOrPtrVectorTy() && + SrcTy->getPointerAddressSpace() == MidTy->getPointerAddressSpace() && + MidTy->getPointerAddressSpace() != DstTy->getPointerAddressSpace() && + "Illegal bitcast, addrspacecast sequence!"); + // Allowed, use second cast's opcode + return secondOp; + case 15: + // FIXME: this state can be merged with (1), but the following assert + // is useful to check the correcteness of the sequence due to semantic + // change of bitcast. + assert( + SrcTy->isIntOrIntVectorTy() && + MidTy->isPtrOrPtrVectorTy() && + DstTy->isPtrOrPtrVectorTy() && + MidTy->getPointerAddressSpace() == DstTy->getPointerAddressSpace() && + "Illegal inttoptr, bitcast sequence!"); + // Allowed, use first cast's opcode + return firstOp; + case 16: + // FIXME: this state can be merged with (2), but the following assert + // is useful to check the correcteness of the sequence due to semantic + // change of bitcast. + assert( + SrcTy->isPtrOrPtrVectorTy() && + MidTy->isPtrOrPtrVectorTy() && + DstTy->isIntOrIntVectorTy() && + SrcTy->getPointerAddressSpace() == MidTy->getPointerAddressSpace() && + "Illegal bitcast, ptrtoint sequence!"); + // Allowed, use second cast's opcode + return secondOp; case 99: - // cast combination can't happen (error in input). This is for all cases + // Cast combination can't happen (error in input). This is for all cases // where the MidTy is not the same for the two cast instructions. llvm_unreachable("Invalid Cast Combination"); default: @@ -2327,19 +2352,20 @@ CastInst *CastInst::Create(Instruction::CastOps op, Value *S, Type *Ty, 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); - case ZExt: return new ZExtInst (S, Ty, Name, InsertBefore); - case SExt: return new SExtInst (S, Ty, Name, InsertBefore); - case FPTrunc: return new FPTruncInst (S, Ty, Name, InsertBefore); - case FPExt: return new FPExtInst (S, Ty, Name, InsertBefore); - case UIToFP: return new UIToFPInst (S, Ty, Name, InsertBefore); - case SIToFP: return new SIToFPInst (S, Ty, Name, InsertBefore); - case FPToUI: return new FPToUIInst (S, Ty, Name, InsertBefore); - case FPToSI: return new FPToSIInst (S, Ty, Name, InsertBefore); - case PtrToInt: return new PtrToIntInst (S, Ty, Name, InsertBefore); - case IntToPtr: return new IntToPtrInst (S, Ty, Name, InsertBefore); - case BitCast: return new BitCastInst (S, Ty, Name, InsertBefore); - default: llvm_unreachable("Invalid opcode provided"); + case Trunc: return new TruncInst (S, Ty, Name, InsertBefore); + case ZExt: return new ZExtInst (S, Ty, Name, InsertBefore); + case SExt: return new SExtInst (S, Ty, Name, InsertBefore); + case FPTrunc: return new FPTruncInst (S, Ty, Name, InsertBefore); + case FPExt: return new FPExtInst (S, Ty, Name, InsertBefore); + case UIToFP: return new UIToFPInst (S, Ty, Name, InsertBefore); + case SIToFP: return new SIToFPInst (S, Ty, Name, InsertBefore); + case FPToUI: return new FPToUIInst (S, Ty, Name, InsertBefore); + case FPToSI: return new FPToSIInst (S, Ty, Name, InsertBefore); + case PtrToInt: return new PtrToIntInst (S, Ty, Name, InsertBefore); + case IntToPtr: return new IntToPtrInst (S, Ty, Name, InsertBefore); + case BitCast: return new BitCastInst (S, Ty, Name, InsertBefore); + case AddrSpaceCast: return new AddrSpaceCastInst (S, Ty, Name, InsertBefore); + default: llvm_unreachable("Invalid opcode provided"); } } @@ -2348,19 +2374,20 @@ CastInst *CastInst::Create(Instruction::CastOps op, Value *S, Type *Ty, 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); - case ZExt: return new ZExtInst (S, Ty, Name, InsertAtEnd); - case SExt: return new SExtInst (S, Ty, Name, InsertAtEnd); - case FPTrunc: return new FPTruncInst (S, Ty, Name, InsertAtEnd); - case FPExt: return new FPExtInst (S, Ty, Name, InsertAtEnd); - case UIToFP: return new UIToFPInst (S, Ty, Name, InsertAtEnd); - case SIToFP: return new SIToFPInst (S, Ty, Name, InsertAtEnd); - case FPToUI: return new FPToUIInst (S, Ty, Name, InsertAtEnd); - case FPToSI: return new FPToSIInst (S, Ty, Name, InsertAtEnd); - case PtrToInt: return new PtrToIntInst (S, Ty, Name, InsertAtEnd); - case IntToPtr: return new IntToPtrInst (S, Ty, Name, InsertAtEnd); - case BitCast: return new BitCastInst (S, Ty, Name, InsertAtEnd); - default: llvm_unreachable("Invalid opcode provided"); + case Trunc: return new TruncInst (S, Ty, Name, InsertAtEnd); + case ZExt: return new ZExtInst (S, Ty, Name, InsertAtEnd); + case SExt: return new SExtInst (S, Ty, Name, InsertAtEnd); + case FPTrunc: return new FPTruncInst (S, Ty, Name, InsertAtEnd); + case FPExt: return new FPExtInst (S, Ty, Name, InsertAtEnd); + case UIToFP: return new UIToFPInst (S, Ty, Name, InsertAtEnd); + case SIToFP: return new SIToFPInst (S, Ty, Name, InsertAtEnd); + case FPToUI: return new FPToUIInst (S, Ty, Name, InsertAtEnd); + case FPToSI: return new FPToSIInst (S, Ty, Name, InsertAtEnd); + case PtrToInt: return new PtrToIntInst (S, Ty, Name, InsertAtEnd); + case IntToPtr: return new IntToPtrInst (S, Ty, Name, InsertAtEnd); + case BitCast: return new BitCastInst (S, Ty, Name, InsertAtEnd); + case AddrSpaceCast: return new AddrSpaceCastInst (S, Ty, Name, InsertAtEnd); + default: llvm_unreachable("Invalid opcode provided"); } } @@ -2425,6 +2452,11 @@ CastInst *CastInst::CreatePointerCast(Value *S, Type *Ty, if (Ty->isIntOrIntVectorTy()) return Create(Instruction::PtrToInt, S, Ty, Name, InsertAtEnd); + + Type *STy = S->getType(); + if (STy->getPointerAddressSpace() != Ty->getPointerAddressSpace()) + return Create(Instruction::AddrSpaceCast, S, Ty, Name, InsertAtEnd); + return Create(Instruction::BitCast, S, Ty, Name, InsertAtEnd); } @@ -2442,6 +2474,11 @@ CastInst *CastInst::CreatePointerCast(Value *S, Type *Ty, if (Ty->isIntOrIntVectorTy()) return Create(Instruction::PtrToInt, S, Ty, Name, InsertBefore); + + Type *STy = S->getType(); + if (STy->getPointerAddressSpace() != Ty->getPointerAddressSpace()) + return Create(Instruction::AddrSpaceCast, S, Ty, Name, InsertBefore); + return Create(Instruction::BitCast, S, Ty, Name, InsertBefore); } @@ -2687,7 +2724,8 @@ CastInst::getCastOpcode( return BitCast; } else if (DestTy->isPointerTy()) { if (SrcTy->isPointerTy()) { - // TODO: Address space pointer sizes may not match + if (DestTy->getPointerAddressSpace() != SrcTy->getPointerAddressSpace()) + return AddrSpaceCast; return BitCast; // ptr -> ptr } else if (SrcTy->isIntegerTy()) { return IntToPtr; // int -> ptr @@ -2782,13 +2820,27 @@ CastInst::castIsValid(Instruction::CastOps op, Value *S, Type *DstTy) { case Instruction::BitCast: // BitCast implies a no-op cast of type only. No bits change. // However, you can't cast pointers to anything but pointers. - if (SrcTy->isPointerTy() != DstTy->isPointerTy()) + if (SrcTy->isPtrOrPtrVectorTy() != DstTy->isPtrOrPtrVectorTy()) return false; - // Now we know we're not dealing with a pointer/non-pointer mismatch. In all - // these cases, the cast is okay if the source and destination bit widths - // are identical. - return SrcTy->getPrimitiveSizeInBits() == DstTy->getPrimitiveSizeInBits(); + // For non pointer cases, the cast is okay if the source and destination bit + // widths are identical. + if (!SrcTy->isPtrOrPtrVectorTy()) + return SrcTy->getPrimitiveSizeInBits() == DstTy->getPrimitiveSizeInBits(); + + // If both are pointers then the address spaces must match and vector of + // pointers must have the same number of elements. + return SrcTy->getPointerAddressSpace() == DstTy->getPointerAddressSpace() && + SrcTy->isVectorTy() == DstTy->isVectorTy() && + (!SrcTy->isVectorTy() || + SrcTy->getVectorNumElements() == SrcTy->getVectorNumElements()); + + case Instruction::AddrSpaceCast: + return SrcTy->isPtrOrPtrVectorTy() && DstTy->isPtrOrPtrVectorTy() && + SrcTy->getPointerAddressSpace() != DstTy->getPointerAddressSpace() && + SrcTy->isVectorTy() == DstTy->isVectorTy() && + (!SrcTy->isVectorTy() || + SrcTy->getVectorNumElements() == SrcTy->getVectorNumElements()); } } @@ -2935,6 +2987,18 @@ BitCastInst::BitCastInst( assert(castIsValid(getOpcode(), S, Ty) && "Illegal BitCast"); } +AddrSpaceCastInst::AddrSpaceCastInst( + Value *S, Type *Ty, const Twine &Name, Instruction *InsertBefore +) : CastInst(Ty, AddrSpaceCast, S, Name, InsertBefore) { + assert(castIsValid(getOpcode(), S, Ty) && "Illegal AddrSpaceCast"); +} + +AddrSpaceCastInst::AddrSpaceCastInst( + Value *S, Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd +) : CastInst(Ty, AddrSpaceCast, S, Name, InsertAtEnd) { + assert(castIsValid(getOpcode(), S, Ty) && "Illegal AddrSpaceCast"); +} + //===----------------------------------------------------------------------===// // CmpInst Classes //===----------------------------------------------------------------------===// @@ -3267,7 +3331,6 @@ SwitchInst::SwitchInst(const SwitchInst &SI) OL[i] = InOL[i]; OL[i+1] = InOL[i+1]; } - TheSubsets = SI.TheSubsets; SubclassOptionalData = SI.SubclassOptionalData; } @@ -3279,16 +3342,6 @@ SwitchInst::~SwitchInst() { /// addCase - Add an entry to the switch instruction... /// void SwitchInst::addCase(ConstantInt *OnVal, BasicBlock *Dest) { - IntegersSubsetToBB Mapping; - - // FIXME: Currently we work with ConstantInt based cases. - // So inititalize IntItem container directly from ConstantInt. - Mapping.add(IntItem::fromConstantInt(OnVal)); - IntegersSubset CaseRanges = Mapping.getCase(); - addCase(CaseRanges, Dest); -} - -void SwitchInst::addCase(IntegersSubset& OnVal, BasicBlock *Dest) { unsigned NewCaseIdx = getNumCases(); unsigned OpNo = NumOperands; if (OpNo+2 > ReservedSpace) @@ -3296,17 +3349,14 @@ void SwitchInst::addCase(IntegersSubset& OnVal, BasicBlock *Dest) { // Initialize some new operands. assert(OpNo+1 < ReservedSpace && "Growing didn't work!"); NumOperands = OpNo+2; - - SubsetsIt TheSubsetsIt = TheSubsets.insert(TheSubsets.end(), OnVal); - - CaseIt Case(this, NewCaseIdx, TheSubsetsIt); - Case.updateCaseValueOperand(OnVal); + CaseIt Case(this, NewCaseIdx); + Case.setValue(OnVal); Case.setSuccessor(Dest); } /// removeCase - This method removes the specified case and its successor /// from the switch instruction. -void SwitchInst::removeCase(CaseIt& i) { +void SwitchInst::removeCase(CaseIt i) { unsigned idx = i.getCaseIndex(); assert(2 + idx*2 < getNumOperands() && "Case index out of range!!!"); @@ -3323,16 +3373,6 @@ void SwitchInst::removeCase(CaseIt& i) { // Nuke the last value. OL[NumOps-2].set(0); OL[NumOps-2+1].set(0); - - // Do the same with TheCases collection: - if (i.SubsetIt != --TheSubsets.end()) { - *i.SubsetIt = TheSubsets.back(); - TheSubsets.pop_back(); - } else { - TheSubsets.pop_back(); - i.SubsetIt = TheSubsets.end(); - } - NumOperands = NumOps-2; } @@ -3577,6 +3617,10 @@ BitCastInst *BitCastInst::clone_impl() const { return new BitCastInst(getOperand(0), getType()); } +AddrSpaceCastInst *AddrSpaceCastInst::clone_impl() const { + return new AddrSpaceCastInst(getOperand(0), getType()); +} + CallInst *CallInst::clone_impl() const { return new(getNumOperands()) CallInst(*this); } diff --git a/lib/IR/LLVMContextImpl.h b/lib/IR/LLVMContextImpl.h index 0c659b8..407b985 100644 --- a/lib/IR/LLVMContextImpl.h +++ b/lib/IR/LLVMContextImpl.h @@ -355,6 +355,11 @@ public: typedef DenseMap<const Function*, unsigned> IntrinsicIDCacheTy; IntrinsicIDCacheTy IntrinsicIDCache; + /// \brief Mapping from a function to its prefix data, which is stored as the + /// operand of an unparented ReturnInst so that the prefix data has a Use. + typedef DenseMap<const Function *, ReturnInst *> PrefixDataMapTy; + PrefixDataMapTy PrefixDataMap; + int getOrAddScopeRecordIdxEntry(MDNode *N, int ExistingIdx); int getOrAddScopeInlinedAtIdxEntry(MDNode *Scope, MDNode *IA,int ExistingIdx); diff --git a/lib/IR/LegacyPassManager.cpp b/lib/IR/LegacyPassManager.cpp new file mode 100644 index 0000000..a431d82 --- /dev/null +++ b/lib/IR/LegacyPassManager.cpp @@ -0,0 +1,1920 @@ +//===- LegacyPassManager.cpp - LLVM Pass Infrastructure Implementation ----===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the legacy LLVM Pass Manager infrastructure. +// +//===----------------------------------------------------------------------===// + + +#include "llvm/Assembly/PrintModulePass.h" +#include "llvm/Assembly/Writer.h" +#include "llvm/IR/LegacyPassManager.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/LegacyPassManagers.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/ManagedStatic.h" +#include "llvm/Support/Mutex.h" +#include "llvm/Support/PassNameParser.h" +#include "llvm/Support/Timer.h" +#include "llvm/Support/raw_ostream.h" +#include <algorithm> +#include <map> +using namespace llvm; +using namespace llvm::legacy; + +// See PassManagers.h for Pass Manager infrastructure overview. + +//===----------------------------------------------------------------------===// +// Pass debugging information. Often it is useful to find out what pass is +// running when a crash occurs in a utility. When this library is compiled with +// debugging on, a command line option (--debug-pass) is enabled that causes the +// pass name to be printed before it executes. +// + +namespace { +// Different debug levels that can be enabled... +enum PassDebugLevel { + Disabled, Arguments, Structure, Executions, Details +}; +} + +static cl::opt<enum PassDebugLevel> +PassDebugging("debug-pass", cl::Hidden, + cl::desc("Print PassManager debugging information"), + cl::values( + clEnumVal(Disabled , "disable debug output"), + clEnumVal(Arguments , "print pass arguments to pass to 'opt'"), + clEnumVal(Structure , "print pass structure before run()"), + clEnumVal(Executions, "print pass name before it is executed"), + clEnumVal(Details , "print pass details when it is executed"), + clEnumValEnd)); + +namespace { +typedef llvm::cl::list<const llvm::PassInfo *, bool, PassNameParser> +PassOptionList; +} + +// Print IR out before/after specified passes. +static PassOptionList +PrintBefore("print-before", + llvm::cl::desc("Print IR before specified passes"), + cl::Hidden); + +static PassOptionList +PrintAfter("print-after", + llvm::cl::desc("Print IR after specified passes"), + cl::Hidden); + +static cl::opt<bool> +PrintBeforeAll("print-before-all", + llvm::cl::desc("Print IR before each pass"), + cl::init(false)); +static cl::opt<bool> +PrintAfterAll("print-after-all", + llvm::cl::desc("Print IR after each pass"), + cl::init(false)); + +/// This is a helper to determine whether to print IR before or +/// after a pass. + +static bool ShouldPrintBeforeOrAfterPass(const PassInfo *PI, + PassOptionList &PassesToPrint) { + for (unsigned i = 0, ie = PassesToPrint.size(); i < ie; ++i) { + const llvm::PassInfo *PassInf = PassesToPrint[i]; + if (PassInf) + if (PassInf->getPassArgument() == PI->getPassArgument()) { + return true; + } + } + return false; +} + +/// This is a utility to check whether a pass should have IR dumped +/// before it. +static bool ShouldPrintBeforePass(const PassInfo *PI) { + return PrintBeforeAll || ShouldPrintBeforeOrAfterPass(PI, PrintBefore); +} + +/// This is a utility to check whether a pass should have IR dumped +/// after it. +static bool ShouldPrintAfterPass(const PassInfo *PI) { + return PrintAfterAll || ShouldPrintBeforeOrAfterPass(PI, PrintAfter); +} + +/// isPassDebuggingExecutionsOrMore - Return true if -debug-pass=Executions +/// or higher is specified. +bool PMDataManager::isPassDebuggingExecutionsOrMore() const { + return PassDebugging >= Executions; +} + + + + +void PassManagerPrettyStackEntry::print(raw_ostream &OS) const { + if (V == 0 && M == 0) + OS << "Releasing pass '"; + else + OS << "Running pass '"; + + OS << P->getPassName() << "'"; + + if (M) { + OS << " on module '" << M->getModuleIdentifier() << "'.\n"; + return; + } + if (V == 0) { + OS << '\n'; + return; + } + + OS << " on "; + if (isa<Function>(V)) + OS << "function"; + else if (isa<BasicBlock>(V)) + OS << "basic block"; + else + OS << "value"; + + OS << " '"; + WriteAsOperand(OS, V, /*PrintTy=*/false, M); + OS << "'\n"; +} + + +namespace { +//===----------------------------------------------------------------------===// +// BBPassManager +// +/// BBPassManager manages BasicBlockPass. It batches all the +/// pass together and sequence them to process one basic block before +/// processing next basic block. +class BBPassManager : public PMDataManager, public FunctionPass { + +public: + static char ID; + explicit BBPassManager() + : PMDataManager(), FunctionPass(ID) {} + + /// Execute all of the passes scheduled for execution. Keep track of + /// whether any of the passes modifies the function, and if so, return true. + bool runOnFunction(Function &F); + + /// Pass Manager itself does not invalidate any analysis info. + void getAnalysisUsage(AnalysisUsage &Info) const { + Info.setPreservesAll(); + } + + bool doInitialization(Module &M); + bool doInitialization(Function &F); + bool doFinalization(Module &M); + bool doFinalization(Function &F); + + virtual PMDataManager *getAsPMDataManager() { return this; } + virtual Pass *getAsPass() { return this; } + + virtual const char *getPassName() const { + return "BasicBlock Pass Manager"; + } + + // Print passes managed by this manager + void dumpPassStructure(unsigned Offset) { + llvm::dbgs().indent(Offset*2) << "BasicBlockPass Manager\n"; + for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { + BasicBlockPass *BP = getContainedPass(Index); + BP->dumpPassStructure(Offset + 1); + dumpLastUses(BP, Offset+1); + } + } + + BasicBlockPass *getContainedPass(unsigned N) { + assert(N < PassVector.size() && "Pass number out of range!"); + BasicBlockPass *BP = static_cast<BasicBlockPass *>(PassVector[N]); + return BP; + } + + virtual PassManagerType getPassManagerType() const { + return PMT_BasicBlockPassManager; + } +}; + +char BBPassManager::ID = 0; +} // End anonymous namespace + +namespace llvm { +namespace legacy { +//===----------------------------------------------------------------------===// +// FunctionPassManagerImpl +// +/// FunctionPassManagerImpl manages FPPassManagers +class FunctionPassManagerImpl : public Pass, + public PMDataManager, + public PMTopLevelManager { + virtual void anchor(); +private: + bool wasRun; +public: + static char ID; + explicit FunctionPassManagerImpl() : + Pass(PT_PassManager, ID), PMDataManager(), + PMTopLevelManager(new FPPassManager()), wasRun(false) {} + + /// add - Add a pass to the queue of passes to run. This passes ownership of + /// the Pass to the PassManager. When the PassManager is destroyed, the pass + /// will be destroyed as well, so there is no need to delete the pass. This + /// implies that all passes MUST be allocated with 'new'. + void add(Pass *P) { + schedulePass(P); + } + + /// createPrinterPass - Get a function printer pass. + Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const { + return createPrintFunctionPass(Banner, &O); + } + + // Prepare for running an on the fly pass, freeing memory if needed + // from a previous run. + void releaseMemoryOnTheFly(); + + /// run - Execute all of the passes scheduled for execution. Keep track of + /// whether any of the passes modifies the module, and if so, return true. + bool run(Function &F); + + /// doInitialization - Run all of the initializers for the function passes. + /// + bool doInitialization(Module &M); + + /// doFinalization - Run all of the finalizers for the function passes. + /// + bool doFinalization(Module &M); + + + virtual PMDataManager *getAsPMDataManager() { return this; } + virtual Pass *getAsPass() { return this; } + virtual PassManagerType getTopLevelPassManagerType() { + return PMT_FunctionPassManager; + } + + /// Pass Manager itself does not invalidate any analysis info. + void getAnalysisUsage(AnalysisUsage &Info) const { + Info.setPreservesAll(); + } + + FPPassManager *getContainedManager(unsigned N) { + assert(N < PassManagers.size() && "Pass number out of range!"); + FPPassManager *FP = static_cast<FPPassManager *>(PassManagers[N]); + return FP; + } +}; + +void FunctionPassManagerImpl::anchor() {} + +char FunctionPassManagerImpl::ID = 0; +} // End of legacy namespace +} // End of llvm namespace + +namespace { +//===----------------------------------------------------------------------===// +// MPPassManager +// +/// MPPassManager manages ModulePasses and function pass managers. +/// It batches all Module passes and function pass managers together and +/// sequences them to process one module. +class MPPassManager : public Pass, public PMDataManager { +public: + static char ID; + explicit MPPassManager() : + Pass(PT_PassManager, ID), PMDataManager() { } + + // Delete on the fly managers. + virtual ~MPPassManager() { + for (std::map<Pass *, FunctionPassManagerImpl *>::iterator + I = OnTheFlyManagers.begin(), E = OnTheFlyManagers.end(); + I != E; ++I) { + FunctionPassManagerImpl *FPP = I->second; + delete FPP; + } + } + + /// createPrinterPass - Get a module printer pass. + Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const { + return createPrintModulePass(&O, false, Banner); + } + + /// run - Execute all of the passes scheduled for execution. Keep track of + /// whether any of the passes modifies the module, and if so, return true. + bool runOnModule(Module &M); + + using llvm::Pass::doInitialization; + using llvm::Pass::doFinalization; + + /// doInitialization - Run all of the initializers for the module passes. + /// + bool doInitialization(); + + /// doFinalization - Run all of the finalizers for the module passes. + /// + bool doFinalization(); + + /// Pass Manager itself does not invalidate any analysis info. + void getAnalysisUsage(AnalysisUsage &Info) const { + Info.setPreservesAll(); + } + + /// Add RequiredPass into list of lower level passes required by pass P. + /// RequiredPass is run on the fly by Pass Manager when P requests it + /// through getAnalysis interface. + virtual void addLowerLevelRequiredPass(Pass *P, Pass *RequiredPass); + + /// Return function pass corresponding to PassInfo PI, that is + /// required by module pass MP. Instantiate analysis pass, by using + /// its runOnFunction() for function F. + virtual Pass* getOnTheFlyPass(Pass *MP, AnalysisID PI, Function &F); + + virtual const char *getPassName() const { + return "Module Pass Manager"; + } + + virtual PMDataManager *getAsPMDataManager() { return this; } + virtual Pass *getAsPass() { return this; } + + // Print passes managed by this manager + void dumpPassStructure(unsigned Offset) { + llvm::dbgs().indent(Offset*2) << "ModulePass Manager\n"; + for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { + ModulePass *MP = getContainedPass(Index); + MP->dumpPassStructure(Offset + 1); + std::map<Pass *, FunctionPassManagerImpl *>::const_iterator I = + OnTheFlyManagers.find(MP); + if (I != OnTheFlyManagers.end()) + I->second->dumpPassStructure(Offset + 2); + dumpLastUses(MP, Offset+1); + } + } + + ModulePass *getContainedPass(unsigned N) { + assert(N < PassVector.size() && "Pass number out of range!"); + return static_cast<ModulePass *>(PassVector[N]); + } + + virtual PassManagerType getPassManagerType() const { + return PMT_ModulePassManager; + } + + private: + /// Collection of on the fly FPPassManagers. These managers manage + /// function passes that are required by module passes. + std::map<Pass *, FunctionPassManagerImpl *> OnTheFlyManagers; +}; + +char MPPassManager::ID = 0; +} // End anonymous namespace + +namespace llvm { +namespace legacy { +//===----------------------------------------------------------------------===// +// PassManagerImpl +// + +/// PassManagerImpl manages MPPassManagers +class PassManagerImpl : public Pass, + public PMDataManager, + public PMTopLevelManager { + virtual void anchor(); + +public: + static char ID; + explicit PassManagerImpl() : + Pass(PT_PassManager, ID), PMDataManager(), + PMTopLevelManager(new MPPassManager()) {} + + /// add - Add a pass to the queue of passes to run. This passes ownership of + /// the Pass to the PassManager. When the PassManager is destroyed, the pass + /// will be destroyed as well, so there is no need to delete the pass. This + /// implies that all passes MUST be allocated with 'new'. + void add(Pass *P) { + schedulePass(P); + } + + /// createPrinterPass - Get a module printer pass. + Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const { + return createPrintModulePass(&O, false, Banner); + } + + /// run - Execute all of the passes scheduled for execution. Keep track of + /// whether any of the passes modifies the module, and if so, return true. + bool run(Module &M); + + using llvm::Pass::doInitialization; + using llvm::Pass::doFinalization; + + /// doInitialization - Run all of the initializers for the module passes. + /// + bool doInitialization(); + + /// doFinalization - Run all of the finalizers for the module passes. + /// + bool doFinalization(); + + /// Pass Manager itself does not invalidate any analysis info. + void getAnalysisUsage(AnalysisUsage &Info) const { + Info.setPreservesAll(); + } + + virtual PMDataManager *getAsPMDataManager() { return this; } + virtual Pass *getAsPass() { return this; } + virtual PassManagerType getTopLevelPassManagerType() { + return PMT_ModulePassManager; + } + + MPPassManager *getContainedManager(unsigned N) { + assert(N < PassManagers.size() && "Pass number out of range!"); + MPPassManager *MP = static_cast<MPPassManager *>(PassManagers[N]); + return MP; + } +}; + +void PassManagerImpl::anchor() {} + +char PassManagerImpl::ID = 0; +} // End of legacy namespace +} // End of llvm namespace + +namespace { + +//===----------------------------------------------------------------------===// +/// TimingInfo Class - This class is used to calculate information about the +/// amount of time each pass takes to execute. This only happens when +/// -time-passes is enabled on the command line. +/// + +static ManagedStatic<sys::SmartMutex<true> > TimingInfoMutex; + +class TimingInfo { + DenseMap<Pass*, Timer*> TimingData; + TimerGroup TG; +public: + // Use 'create' member to get this. + TimingInfo() : TG("... Pass execution timing report ...") {} + + // TimingDtor - Print out information about timing information + ~TimingInfo() { + // Delete all of the timers, which accumulate their info into the + // TimerGroup. + for (DenseMap<Pass*, Timer*>::iterator I = TimingData.begin(), + E = TimingData.end(); I != E; ++I) + delete I->second; + // TimerGroup is deleted next, printing the report. + } + + // createTheTimeInfo - This method either initializes the TheTimeInfo pointer + // to a non null value (if the -time-passes option is enabled) or it leaves it + // null. It may be called multiple times. + static void createTheTimeInfo(); + + /// getPassTimer - Return the timer for the specified pass if it exists. + Timer *getPassTimer(Pass *P) { + if (P->getAsPMDataManager()) + return 0; + + sys::SmartScopedLock<true> Lock(*TimingInfoMutex); + Timer *&T = TimingData[P]; + if (T == 0) + T = new Timer(P->getPassName(), TG); + return T; + } +}; + +} // End of anon namespace + +static TimingInfo *TheTimeInfo; + +//===----------------------------------------------------------------------===// +// PMTopLevelManager implementation + +/// Initialize top level manager. Create first pass manager. +PMTopLevelManager::PMTopLevelManager(PMDataManager *PMDM) { + PMDM->setTopLevelManager(this); + addPassManager(PMDM); + activeStack.push(PMDM); +} + +/// Set pass P as the last user of the given analysis passes. +void +PMTopLevelManager::setLastUser(ArrayRef<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; + + 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 existing entries. + LastUser[LUI->first] = P; + } + } +} + +/// Collect passes whose last user is P +void PMTopLevelManager::collectLastUses(SmallVectorImpl<Pass *> &LastUses, + Pass *P) { + DenseMap<Pass *, SmallPtrSet<Pass *, 8> >::iterator DMI = + InversedLastUser.find(P); + if (DMI == InversedLastUser.end()) + return; + + SmallPtrSet<Pass *, 8> &LU = DMI->second; + for (SmallPtrSet<Pass *, 8>::iterator I = LU.begin(), + E = LU.end(); I != E; ++I) { + LastUses.push_back(*I); + } + +} + +AnalysisUsage *PMTopLevelManager::findAnalysisUsage(Pass *P) { + AnalysisUsage *AnUsage = NULL; + DenseMap<Pass *, AnalysisUsage *>::iterator DMI = AnUsageMap.find(P); + if (DMI != AnUsageMap.end()) + AnUsage = DMI->second; + else { + AnUsage = new AnalysisUsage(); + P->getAnalysisUsage(*AnUsage); + AnUsageMap[P] = AnUsage; + } + return AnUsage; +} + +/// Schedule pass P for execution. Make sure that passes required by +/// P are run before P is run. Update analysis info maintained by +/// the manager. Remove dead passes. This is a recursive function. +void PMTopLevelManager::schedulePass(Pass *P) { + + // TODO : Allocate function manager for this pass, other wise required set + // may be inserted into previous function manager + + // Give pass a chance to prepare the stage. + P->preparePassManager(activeStack); + + // If P is an analysis pass and it is available then do not + // generate the analysis again. Stale analysis info should not be + // available at this point. + const PassInfo *PI = + PassRegistry::getPassRegistry()->getPassInfo(P->getPassID()); + if (PI && PI->isAnalysis() && findAnalysisPass(P->getPassID())) { + delete P; + return; + } + + AnalysisUsage *AnUsage = findAnalysisUsage(P); + + bool checkAnalysis = true; + while (checkAnalysis) { + checkAnalysis = false; + + const AnalysisUsage::VectorType &RequiredSet = AnUsage->getRequiredSet(); + for (AnalysisUsage::VectorType::const_iterator I = RequiredSet.begin(), + E = RequiredSet.end(); I != E; ++I) { + + Pass *AnalysisPass = findAnalysisPass(*I); + if (!AnalysisPass) { + const PassInfo *PI = PassRegistry::getPassRegistry()->getPassInfo(*I); + + if (PI == NULL) { + // Pass P is not in the global PassRegistry + dbgs() << "Pass '" << P->getPassName() << "' is not initialized." << "\n"; + dbgs() << "Verify if there is a pass dependency cycle." << "\n"; + dbgs() << "Required Passes:" << "\n"; + for (AnalysisUsage::VectorType::const_iterator I2 = RequiredSet.begin(), + E = RequiredSet.end(); I2 != E && I2 != I; ++I2) { + Pass *AnalysisPass2 = findAnalysisPass(*I2); + if (AnalysisPass2) { + dbgs() << "\t" << AnalysisPass2->getPassName() << "\n"; + } else { + dbgs() << "\t" << "Error: Required pass not found! Possible causes:" << "\n"; + dbgs() << "\t\t" << "- Pass misconfiguration (e.g.: missing macros)" << "\n"; + dbgs() << "\t\t" << "- Corruption of the global PassRegistry" << "\n"; + } + } + } + + assert(PI && "Expected required passes to be initialized"); + AnalysisPass = PI->createPass(); + if (P->getPotentialPassManagerType () == + AnalysisPass->getPotentialPassManagerType()) + // Schedule analysis pass that is managed by the same pass manager. + schedulePass(AnalysisPass); + else if (P->getPotentialPassManagerType () > + AnalysisPass->getPotentialPassManagerType()) { + // Schedule analysis pass that is managed by a new manager. + schedulePass(AnalysisPass); + // Recheck analysis passes to ensure that required analyses that + // are already checked are still available. + checkAnalysis = true; + } else + // Do not schedule this analysis. Lower level analsyis + // passes are run on the fly. + delete AnalysisPass; + } + } + } + + // Now all required passes are available. + if (ImmutablePass *IP = P->getAsImmutablePass()) { + // P is a immutable pass and it will be managed by this + // top level manager. Set up analysis resolver to connect them. + PMDataManager *DM = getAsPMDataManager(); + AnalysisResolver *AR = new AnalysisResolver(*DM); + P->setResolver(AR); + DM->initializeAnalysisImpl(P); + addImmutablePass(IP); + DM->recordAvailableAnalysis(IP); + return; + } + + if (PI && !PI->isAnalysis() && ShouldPrintBeforePass(PI)) { + Pass *PP = P->createPrinterPass( + dbgs(), std::string("*** IR Dump Before ") + P->getPassName() + " ***"); + PP->assignPassManager(activeStack, getTopLevelPassManagerType()); + } + + // Add the requested pass to the best available pass manager. + P->assignPassManager(activeStack, getTopLevelPassManagerType()); + + if (PI && !PI->isAnalysis() && ShouldPrintAfterPass(PI)) { + Pass *PP = P->createPrinterPass( + dbgs(), std::string("*** IR Dump After ") + P->getPassName() + " ***"); + PP->assignPassManager(activeStack, getTopLevelPassManagerType()); + } +} + +/// Find the pass that implements Analysis AID. Search immutable +/// passes and all pass managers. If desired pass is not found +/// then return NULL. +Pass *PMTopLevelManager::findAnalysisPass(AnalysisID AID) { + + // Check pass managers + 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 (SmallVectorImpl<PMDataManager *>::iterator + I = IndirectPassManagers.begin(), + 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 (SmallVectorImpl<ImmutablePass *>::reverse_iterator I = + ImmutablePasses.rbegin(), E = ImmutablePasses.rend(); I != E; ++I) { + AnalysisID PI = (*I)->getPassID(); + if (PI == AID) + return *I; + + // 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(), + EE = ImmPI.end(); II != EE; ++II) { + if ((*II)->getTypeInfo() == AID) + return *I; + } + } + + return 0; +} + +// Print passes managed by this top level manager. +void PMTopLevelManager::dumpPasses() const { + + if (PassDebugging < Structure) + return; + + // Print out the immutable passes + for (unsigned i = 0, e = ImmutablePasses.size(); i != e; ++i) { + ImmutablePasses[i]->dumpPassStructure(0); + } + + // Every class that derives from PMDataManager also derives from Pass + // (sometimes indirectly), but there's no inheritance relationship + // between PMDataManager and Pass, so we have to getAsPass to get + // from a PMDataManager* to a Pass*. + for (SmallVectorImpl<PMDataManager *>::const_iterator I = + PassManagers.begin(), E = PassManagers.end(); I != E; ++I) + (*I)->getAsPass()->dumpPassStructure(1); +} + +void PMTopLevelManager::dumpArguments() const { + + if (PassDebugging < Arguments) + return; + + dbgs() << "Pass Arguments: "; + for (SmallVectorImpl<ImmutablePass *>::const_iterator I = + ImmutablePasses.begin(), E = ImmutablePasses.end(); I != E; ++I) + if (const PassInfo *PI = + PassRegistry::getPassRegistry()->getPassInfo((*I)->getPassID())) { + assert(PI && "Expected all immutable passes to be initialized"); + if (!PI->isAnalysisGroup()) + dbgs() << " -" << PI->getPassArgument(); + } + for (SmallVectorImpl<PMDataManager *>::const_iterator I = + PassManagers.begin(), E = PassManagers.end(); I != E; ++I) + (*I)->dumpPassArguments(); + dbgs() << "\n"; +} + +void PMTopLevelManager::initializeAllAnalysisInfo() { + for (SmallVectorImpl<PMDataManager *>::iterator I = PassManagers.begin(), + E = PassManagers.end(); I != E; ++I) + (*I)->initializeAnalysisInfo(); + + // Initailize other pass managers + for (SmallVectorImpl<PMDataManager *>::iterator + I = IndirectPassManagers.begin(), E = IndirectPassManagers.end(); + I != E; ++I) + (*I)->initializeAnalysisInfo(); + + for (DenseMap<Pass *, Pass *>::iterator DMI = LastUser.begin(), + DME = LastUser.end(); DMI != DME; ++DMI) { + DenseMap<Pass *, SmallPtrSet<Pass *, 8> >::iterator InvDMI = + InversedLastUser.find(DMI->second); + if (InvDMI != InversedLastUser.end()) { + SmallPtrSet<Pass *, 8> &L = InvDMI->second; + L.insert(DMI->first); + } else { + SmallPtrSet<Pass *, 8> L; L.insert(DMI->first); + InversedLastUser[DMI->second] = L; + } + } +} + +/// Destructor +PMTopLevelManager::~PMTopLevelManager() { + for (SmallVectorImpl<PMDataManager *>::iterator I = PassManagers.begin(), + E = PassManagers.end(); I != E; ++I) + delete *I; + + for (SmallVectorImpl<ImmutablePass *>::iterator + I = ImmutablePasses.begin(), E = ImmutablePasses.end(); I != E; ++I) + delete *I; + + for (DenseMap<Pass *, AnalysisUsage *>::iterator DMI = AnUsageMap.begin(), + DME = AnUsageMap.end(); DMI != DME; ++DMI) + delete DMI->second; +} + +//===----------------------------------------------------------------------===// +// PMDataManager implementation + +/// Augement AvailableAnalysis by adding analysis made available by pass P. +void PMDataManager::recordAvailableAnalysis(Pass *P) { + AnalysisID PI = P->getPassID(); + + AvailableAnalysis[PI] = P; + + assert(!AvailableAnalysis.empty()); + + // This pass is the current implementation of all of the interfaces it + // implements as well. + const PassInfo *PInf = PassRegistry::getPassRegistry()->getPassInfo(PI); + if (PInf == 0) return; + const std::vector<const PassInfo*> &II = PInf->getInterfacesImplemented(); + for (unsigned i = 0, e = II.size(); i != e; ++i) + AvailableAnalysis[II[i]->getTypeInfo()] = P; +} + +// Return true if P preserves high level analysis used by other +// passes managed by this manager +bool PMDataManager::preserveHigherLevelAnalysis(Pass *P) { + AnalysisUsage *AnUsage = TPM->findAnalysisUsage(P); + if (AnUsage->getPreservesAll()) + return true; + + const AnalysisUsage::VectorType &PreservedSet = AnUsage->getPreservedSet(); + for (SmallVectorImpl<Pass *>::iterator I = HigherLevelAnalysis.begin(), + E = HigherLevelAnalysis.end(); I != E; ++I) { + Pass *P1 = *I; + if (P1->getAsImmutablePass() == 0 && + std::find(PreservedSet.begin(), PreservedSet.end(), + P1->getPassID()) == + PreservedSet.end()) + return false; + } + + return true; +} + +/// verifyPreservedAnalysis -- Verify analysis preserved by pass P. +void PMDataManager::verifyPreservedAnalysis(Pass *P) { + // Don't do this unless assertions are enabled. +#ifdef NDEBUG + return; +#endif + AnalysisUsage *AnUsage = TPM->findAnalysisUsage(P); + const AnalysisUsage::VectorType &PreservedSet = AnUsage->getPreservedSet(); + + // Verify preserved analysis + for (AnalysisUsage::VectorType::const_iterator I = PreservedSet.begin(), + E = PreservedSet.end(); I != E; ++I) { + AnalysisID AID = *I; + if (Pass *AP = findAnalysisPass(AID, true)) { + TimeRegion PassTimer(getPassTimer(AP)); + AP->verifyAnalysis(); + } + } +} + +/// Remove Analysis not preserved by Pass P +void PMDataManager::removeNotPreservedAnalysis(Pass *P) { + AnalysisUsage *AnUsage = TPM->findAnalysisUsage(P); + if (AnUsage->getPreservesAll()) + return; + + const AnalysisUsage::VectorType &PreservedSet = AnUsage->getPreservedSet(); + for (DenseMap<AnalysisID, Pass*>::iterator I = AvailableAnalysis.begin(), + E = AvailableAnalysis.end(); I != E; ) { + DenseMap<AnalysisID, Pass*>::iterator Info = I++; + if (Info->second->getAsImmutablePass() == 0 && + std::find(PreservedSet.begin(), PreservedSet.end(), Info->first) == + PreservedSet.end()) { + // Remove this analysis + if (PassDebugging >= Details) { + Pass *S = Info->second; + dbgs() << " -- '" << P->getPassName() << "' is not preserving '"; + dbgs() << S->getPassName() << "'\n"; + } + AvailableAnalysis.erase(Info); + } + } + + // Check inherited analysis also. If P is not preserving analysis + // provided by parent manager then remove it here. + for (unsigned Index = 0; Index < PMT_Last; ++Index) { + + if (!InheritedAnalysis[Index]) + continue; + + for (DenseMap<AnalysisID, Pass*>::iterator + I = InheritedAnalysis[Index]->begin(), + E = InheritedAnalysis[Index]->end(); I != E; ) { + DenseMap<AnalysisID, Pass *>::iterator Info = I++; + if (Info->second->getAsImmutablePass() == 0 && + std::find(PreservedSet.begin(), PreservedSet.end(), Info->first) == + PreservedSet.end()) { + // Remove this analysis + if (PassDebugging >= Details) { + Pass *S = Info->second; + dbgs() << " -- '" << P->getPassName() << "' is not preserving '"; + dbgs() << S->getPassName() << "'\n"; + } + InheritedAnalysis[Index]->erase(Info); + } + } + } +} + +/// Remove analysis passes that are not used any longer +void PMDataManager::removeDeadPasses(Pass *P, StringRef Msg, + enum PassDebuggingString DBG_STR) { + + SmallVector<Pass *, 12> DeadPasses; + + // If this is a on the fly manager then it does not have TPM. + if (!TPM) + return; + + TPM->collectLastUses(DeadPasses, P); + + if (PassDebugging >= Details && !DeadPasses.empty()) { + dbgs() << " -*- '" << P->getPassName(); + dbgs() << "' is the last user of following pass instances."; + dbgs() << " Free these instances\n"; + } + + for (SmallVectorImpl<Pass *>::iterator I = DeadPasses.begin(), + E = DeadPasses.end(); I != E; ++I) + freePass(*I, Msg, DBG_STR); +} + +void PMDataManager::freePass(Pass *P, StringRef Msg, + enum PassDebuggingString DBG_STR) { + dumpPassInfo(P, FREEING_MSG, DBG_STR, Msg); + + { + // If the pass crashes releasing memory, remember this. + PassManagerPrettyStackEntry X(P); + TimeRegion PassTimer(getPassTimer(P)); + + P->releaseMemory(); + } + + AnalysisID PI = P->getPassID(); + if (const PassInfo *PInf = PassRegistry::getPassRegistry()->getPassInfo(PI)) { + // Remove the pass itself (if it is not already removed). + AvailableAnalysis.erase(PI); + + // Remove all interfaces this pass implements, for which it is also + // listed as the available implementation. + const std::vector<const PassInfo*> &II = PInf->getInterfacesImplemented(); + for (unsigned i = 0, e = II.size(); i != e; ++i) { + DenseMap<AnalysisID, Pass*>::iterator Pos = + AvailableAnalysis.find(II[i]->getTypeInfo()); + if (Pos != AvailableAnalysis.end() && Pos->second == P) + AvailableAnalysis.erase(Pos); + } + } +} + +/// Add pass P into the PassVector. Update +/// AvailableAnalysis appropriately if ProcessAnalysis is true. +void PMDataManager::add(Pass *P, bool ProcessAnalysis) { + // This manager is going to manage pass P. Set up analysis resolver + // to connect them. + AnalysisResolver *AR = new AnalysisResolver(*this); + P->setResolver(AR); + + // If a FunctionPass F is the last user of ModulePass info M + // then the F's manager, not F, records itself as a last user of M. + SmallVector<Pass *, 12> TransferLastUses; + + if (!ProcessAnalysis) { + // Add pass + PassVector.push_back(P); + return; + } + + // At the moment, this pass is the last user of all required passes. + SmallVector<Pass *, 12> LastUses; + SmallVector<Pass *, 8> RequiredPasses; + SmallVector<AnalysisID, 8> ReqAnalysisNotAvailable; + + unsigned PDepth = this->getDepth(); + + collectRequiredAnalysis(RequiredPasses, + ReqAnalysisNotAvailable, P); + for (SmallVectorImpl<Pass *>::iterator I = RequiredPasses.begin(), + E = RequiredPasses.end(); I != E; ++I) { + Pass *PRequired = *I; + unsigned RDepth = 0; + + assert(PRequired->getResolver() && "Analysis Resolver is not set"); + PMDataManager &DM = PRequired->getResolver()->getPMDataManager(); + RDepth = DM.getDepth(); + + if (PDepth == RDepth) + LastUses.push_back(PRequired); + else if (PDepth > RDepth) { + // Let the parent claim responsibility of last use + TransferLastUses.push_back(PRequired); + // Keep track of higher level analysis used by this manager. + HigherLevelAnalysis.push_back(PRequired); + } else + llvm_unreachable("Unable to accommodate Required Pass"); + } + + // Set P as P's last user until someone starts using P. + // However, if P is a Pass Manager then it does not need + // to record its last user. + if (P->getAsPMDataManager() == 0) + LastUses.push_back(P); + TPM->setLastUser(LastUses, P); + + if (!TransferLastUses.empty()) { + Pass *My_PM = getAsPass(); + TPM->setLastUser(TransferLastUses, My_PM); + TransferLastUses.clear(); + } + + // Now, take care of required analyses that are not available. + for (SmallVectorImpl<AnalysisID>::iterator + I = ReqAnalysisNotAvailable.begin(), + E = ReqAnalysisNotAvailable.end() ;I != E; ++I) { + const PassInfo *PI = PassRegistry::getPassRegistry()->getPassInfo(*I); + Pass *AnalysisPass = PI->createPass(); + this->addLowerLevelRequiredPass(P, AnalysisPass); + } + + // Take a note of analysis required and made available by this pass. + // Remove the analysis not preserved by this pass + removeNotPreservedAnalysis(P); + recordAvailableAnalysis(P); + + // Add pass + PassVector.push_back(P); +} + + +/// 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(SmallVectorImpl<Pass *> &RP, + SmallVectorImpl<AnalysisID> &RP_NotAvail, + Pass *P) { + AnalysisUsage *AnUsage = TPM->findAnalysisUsage(P); + const AnalysisUsage::VectorType &RequiredSet = AnUsage->getRequiredSet(); + for (AnalysisUsage::VectorType::const_iterator + I = RequiredSet.begin(), E = RequiredSet.end(); I != E; ++I) { + if (Pass *AnalysisPass = findAnalysisPass(*I, true)) + RP.push_back(AnalysisPass); + else + RP_NotAvail.push_back(*I); + } + + const AnalysisUsage::VectorType &IDs = AnUsage->getRequiredTransitiveSet(); + for (AnalysisUsage::VectorType::const_iterator I = IDs.begin(), + E = IDs.end(); I != E; ++I) { + if (Pass *AnalysisPass = findAnalysisPass(*I, true)) + RP.push_back(AnalysisPass); + else + RP_NotAvail.push_back(*I); + } +} + +// All Required analyses should be available to the pass as it runs! Here +// we fill in the AnalysisImpls member of the pass so that it can +// successfully use the getAnalysis() method to retrieve the +// implementations it needs. +// +void PMDataManager::initializeAnalysisImpl(Pass *P) { + AnalysisUsage *AnUsage = TPM->findAnalysisUsage(P); + + for (AnalysisUsage::VectorType::const_iterator + I = AnUsage->getRequiredSet().begin(), + E = AnUsage->getRequiredSet().end(); I != E; ++I) { + Pass *Impl = findAnalysisPass(*I, true); + if (Impl == 0) + // This may be analysis pass that is initialized on the fly. + // If that is not the case then it will raise an assert when it is used. + continue; + AnalysisResolver *AR = P->getResolver(); + assert(AR && "Analysis Resolver is not set"); + AR->addAnalysisImplsPair(*I, Impl); + } +} + +/// Find the pass that implements Analysis AID. If desired pass is not found +/// then return NULL. +Pass *PMDataManager::findAnalysisPass(AnalysisID AID, bool SearchParent) { + + // Check if AvailableAnalysis map has one entry. + DenseMap<AnalysisID, Pass*>::const_iterator I = AvailableAnalysis.find(AID); + + if (I != AvailableAnalysis.end()) + return I->second; + + // Search Parents through TopLevelManager + if (SearchParent) + return TPM->findAnalysisPass(AID); + + return NULL; +} + +// Print list of passes that are last used by P. +void PMDataManager::dumpLastUses(Pass *P, unsigned Offset) const{ + + SmallVector<Pass *, 12> LUses; + + // If this is a on the fly manager then it does not have TPM. + if (!TPM) + return; + + TPM->collectLastUses(LUses, P); + + for (SmallVectorImpl<Pass *>::iterator I = LUses.begin(), + E = LUses.end(); I != E; ++I) { + llvm::dbgs() << "--" << std::string(Offset*2, ' '); + (*I)->dumpPassStructure(0); + } +} + +void PMDataManager::dumpPassArguments() const { + for (SmallVectorImpl<Pass *>::const_iterator I = PassVector.begin(), + E = PassVector.end(); I != E; ++I) { + if (PMDataManager *PMD = (*I)->getAsPMDataManager()) + PMD->dumpPassArguments(); + else + if (const PassInfo *PI = + PassRegistry::getPassRegistry()->getPassInfo((*I)->getPassID())) + if (!PI->isAnalysisGroup()) + dbgs() << " -" << PI->getPassArgument(); + } +} + +void PMDataManager::dumpPassInfo(Pass *P, enum PassDebuggingString S1, + enum PassDebuggingString S2, + StringRef Msg) { + if (PassDebugging < Executions) + return; + dbgs() << (void*)this << std::string(getDepth()*2+1, ' '); + switch (S1) { + case EXECUTION_MSG: + dbgs() << "Executing Pass '" << P->getPassName(); + break; + case MODIFICATION_MSG: + dbgs() << "Made Modification '" << P->getPassName(); + break; + case FREEING_MSG: + dbgs() << " Freeing Pass '" << P->getPassName(); + break; + default: + break; + } + switch (S2) { + case ON_BASICBLOCK_MSG: + dbgs() << "' on BasicBlock '" << Msg << "'...\n"; + break; + case ON_FUNCTION_MSG: + dbgs() << "' on Function '" << Msg << "'...\n"; + break; + 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; + case ON_CG_MSG: + dbgs() << "' on Call Graph Nodes '" << Msg << "'...\n"; + break; + default: + break; + } +} + +void PMDataManager::dumpRequiredSet(const Pass *P) const { + if (PassDebugging < Details) + return; + + AnalysisUsage analysisUsage; + P->getAnalysisUsage(analysisUsage); + dumpAnalysisUsage("Required", P, analysisUsage.getRequiredSet()); +} + +void PMDataManager::dumpPreservedSet(const Pass *P) const { + if (PassDebugging < Details) + return; + + AnalysisUsage analysisUsage; + P->getAnalysisUsage(analysisUsage); + dumpAnalysisUsage("Preserved", P, analysisUsage.getPreservedSet()); +} + +void PMDataManager::dumpAnalysisUsage(StringRef Msg, const Pass *P, + const AnalysisUsage::VectorType &Set) const { + assert(PassDebugging >= Details); + if (Set.empty()) + return; + dbgs() << (const void*)P << std::string(getDepth()*2+3, ' ') << Msg << " Analyses:"; + 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'; +} + +/// Add RequiredPass into list of lower level passes required by pass P. +/// RequiredPass is run on the fly by Pass Manager when P requests it +/// through getAnalysis interface. +/// This should be handled by specific pass manager. +void PMDataManager::addLowerLevelRequiredPass(Pass *P, Pass *RequiredPass) { + if (TPM) { + TPM->dumpArguments(); + TPM->dumpPasses(); + } + + // Module Level pass may required Function Level analysis info + // (e.g. dominator info). Pass manager uses on the fly function pass manager + // to provide this on demand. In that case, in Pass manager terminology, + // module level pass is requiring lower level analysis info managed by + // lower level pass manager. + + // When Pass manager is not able to order required analysis info, Pass manager + // checks whether any lower level manager will be able to provide this + // analysis info on demand or not. +#ifndef NDEBUG + dbgs() << "Unable to schedule '" << RequiredPass->getPassName(); + dbgs() << "' required by '" << P->getPassName() << "'\n"; +#endif + llvm_unreachable("Unable to schedule pass"); +} + +Pass *PMDataManager::getOnTheFlyPass(Pass *P, AnalysisID PI, Function &F) { + llvm_unreachable("Unable to find on the fly pass"); +} + +// Destructor +PMDataManager::~PMDataManager() { + for (SmallVectorImpl<Pass *>::iterator I = PassVector.begin(), + E = PassVector.end(); I != E; ++I) + delete *I; +} + +//===----------------------------------------------------------------------===// +// NOTE: Is this the right place to define this method ? +// getAnalysisIfAvailable - Return analysis result or null if it doesn't exist. +Pass *AnalysisResolver::getAnalysisIfAvailable(AnalysisID ID, bool dir) const { + return PM.findAnalysisPass(ID, dir); +} + +Pass *AnalysisResolver::findImplPass(Pass *P, AnalysisID AnalysisPI, + Function &F) { + return PM.getOnTheFlyPass(P, AnalysisPI, F); +} + +//===----------------------------------------------------------------------===// +// BBPassManager implementation + +/// Execute all of the passes scheduled for execution by invoking +/// runOnBasicBlock method. Keep track of whether any of the passes modifies +/// the function, and if so, return true. +bool BBPassManager::runOnFunction(Function &F) { + if (F.isDeclaration()) + return false; + + bool Changed = doInitialization(F); + + for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) + for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { + BasicBlockPass *BP = getContainedPass(Index); + bool LocalChanged = false; + + dumpPassInfo(BP, EXECUTION_MSG, ON_BASICBLOCK_MSG, I->getName()); + dumpRequiredSet(BP); + + initializeAnalysisImpl(BP); + + { + // If the pass crashes, remember this. + PassManagerPrettyStackEntry X(BP, *I); + TimeRegion PassTimer(getPassTimer(BP)); + + LocalChanged |= BP->runOnBasicBlock(*I); + } + + Changed |= LocalChanged; + if (LocalChanged) + dumpPassInfo(BP, MODIFICATION_MSG, ON_BASICBLOCK_MSG, + I->getName()); + dumpPreservedSet(BP); + + verifyPreservedAnalysis(BP); + removeNotPreservedAnalysis(BP); + recordAvailableAnalysis(BP); + removeDeadPasses(BP, I->getName(), ON_BASICBLOCK_MSG); + } + + return doFinalization(F) || Changed; +} + +// Implement doInitialization and doFinalization +bool BBPassManager::doInitialization(Module &M) { + bool Changed = false; + + for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) + Changed |= getContainedPass(Index)->doInitialization(M); + + return Changed; +} + +bool BBPassManager::doFinalization(Module &M) { + bool Changed = false; + + for (int Index = getNumContainedPasses() - 1; Index >= 0; --Index) + Changed |= getContainedPass(Index)->doFinalization(M); + + return Changed; +} + +bool BBPassManager::doInitialization(Function &F) { + bool Changed = false; + + for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { + BasicBlockPass *BP = getContainedPass(Index); + Changed |= BP->doInitialization(F); + } + + return Changed; +} + +bool BBPassManager::doFinalization(Function &F) { + bool Changed = false; + + for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { + BasicBlockPass *BP = getContainedPass(Index); + Changed |= BP->doFinalization(F); + } + + return Changed; +} + + +//===----------------------------------------------------------------------===// +// FunctionPassManager implementation + +/// Create new Function pass manager +FunctionPassManager::FunctionPassManager(Module *m) : M(m) { + FPM = new FunctionPassManagerImpl(); + // FPM is the top level manager. + FPM->setTopLevelManager(FPM); + + AnalysisResolver *AR = new AnalysisResolver(*FPM); + FPM->setResolver(AR); +} + +FunctionPassManager::~FunctionPassManager() { + delete FPM; +} + +/// add - Add a pass to the queue of passes to run. This passes +/// ownership of the Pass to the PassManager. When the +/// PassManager_X is destroyed, the pass will be destroyed as well, so +/// there is no need to delete the pass. (TODO delete passes.) +/// This implies that all passes MUST be allocated with 'new'. +void FunctionPassManager::add(Pass *P) { + FPM->add(P); +} + +/// run - Execute all of the passes scheduled for execution. Keep +/// track of whether any of the passes modifies the function, and if +/// so, return true. +/// +bool FunctionPassManager::run(Function &F) { + if (F.isMaterializable()) { + std::string errstr; + if (F.Materialize(&errstr)) + report_fatal_error("Error reading bitcode file: " + Twine(errstr)); + } + return FPM->run(F); +} + + +/// doInitialization - Run all of the initializers for the function passes. +/// +bool FunctionPassManager::doInitialization() { + return FPM->doInitialization(*M); +} + +/// doFinalization - Run all of the finalizers for the function passes. +/// +bool FunctionPassManager::doFinalization() { + return FPM->doFinalization(*M); +} + +//===----------------------------------------------------------------------===// +// FunctionPassManagerImpl implementation +// +bool FunctionPassManagerImpl::doInitialization(Module &M) { + bool Changed = false; + + dumpArguments(); + dumpPasses(); + + SmallVectorImpl<ImmutablePass *>& IPV = getImmutablePasses(); + for (SmallVectorImpl<ImmutablePass *>::const_iterator I = IPV.begin(), + E = IPV.end(); I != E; ++I) { + Changed |= (*I)->doInitialization(M); + } + + for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) + Changed |= getContainedManager(Index)->doInitialization(M); + + return Changed; +} + +bool FunctionPassManagerImpl::doFinalization(Module &M) { + bool Changed = false; + + for (int Index = getNumContainedManagers() - 1; Index >= 0; --Index) + Changed |= getContainedManager(Index)->doFinalization(M); + + SmallVectorImpl<ImmutablePass *>& IPV = getImmutablePasses(); + for (SmallVectorImpl<ImmutablePass *>::const_iterator I = IPV.begin(), + E = IPV.end(); I != E; ++I) { + Changed |= (*I)->doFinalization(M); + } + + return Changed; +} + +/// cleanup - After running all passes, clean up pass manager cache. +void FPPassManager::cleanup() { + for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { + FunctionPass *FP = getContainedPass(Index); + AnalysisResolver *AR = FP->getResolver(); + assert(AR && "Analysis Resolver is not set"); + AR->clearAnalysisImpls(); + } +} + +void FunctionPassManagerImpl::releaseMemoryOnTheFly() { + if (!wasRun) + return; + for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) { + FPPassManager *FPPM = getContainedManager(Index); + for (unsigned Index = 0; Index < FPPM->getNumContainedPasses(); ++Index) { + FPPM->getContainedPass(Index)->releaseMemory(); + } + } + wasRun = false; +} + +// Execute all the passes managed by this top level manager. +// Return true if any function is modified by a pass. +bool FunctionPassManagerImpl::run(Function &F) { + bool Changed = false; + TimingInfo::createTheTimeInfo(); + + initializeAllAnalysisInfo(); + for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) + Changed |= getContainedManager(Index)->runOnFunction(F); + + for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) + getContainedManager(Index)->cleanup(); + + wasRun = true; + return Changed; +} + +//===----------------------------------------------------------------------===// +// FPPassManager implementation + +char FPPassManager::ID = 0; +/// Print passes managed by this manager +void FPPassManager::dumpPassStructure(unsigned Offset) { + dbgs().indent(Offset*2) << "FunctionPass Manager\n"; + for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { + FunctionPass *FP = getContainedPass(Index); + FP->dumpPassStructure(Offset + 1); + dumpLastUses(FP, Offset+1); + } +} + + +/// Execute all of the passes scheduled for execution by invoking +/// runOnFunction method. Keep track of whether any of the passes modifies +/// the function, and if so, return true. +bool FPPassManager::runOnFunction(Function &F) { + if (F.isDeclaration()) + return false; + + bool Changed = false; + + // Collect inherited analysis from Module level pass manager. + populateInheritedAnalysis(TPM->activeStack); + + for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { + FunctionPass *FP = getContainedPass(Index); + bool LocalChanged = false; + + dumpPassInfo(FP, EXECUTION_MSG, ON_FUNCTION_MSG, F.getName()); + dumpRequiredSet(FP); + + initializeAnalysisImpl(FP); + + { + PassManagerPrettyStackEntry X(FP, F); + TimeRegion PassTimer(getPassTimer(FP)); + + LocalChanged |= FP->runOnFunction(F); + } + + Changed |= LocalChanged; + if (LocalChanged) + dumpPassInfo(FP, MODIFICATION_MSG, ON_FUNCTION_MSG, F.getName()); + dumpPreservedSet(FP); + + verifyPreservedAnalysis(FP); + removeNotPreservedAnalysis(FP); + recordAvailableAnalysis(FP); + removeDeadPasses(FP, F.getName(), ON_FUNCTION_MSG); + } + return Changed; +} + +bool FPPassManager::runOnModule(Module &M) { + bool Changed = false; + + for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) + Changed |= runOnFunction(*I); + + return Changed; +} + +bool FPPassManager::doInitialization(Module &M) { + bool Changed = false; + + for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) + Changed |= getContainedPass(Index)->doInitialization(M); + + return Changed; +} + +bool FPPassManager::doFinalization(Module &M) { + bool Changed = false; + + for (int Index = getNumContainedPasses() - 1; Index >= 0; --Index) + Changed |= getContainedPass(Index)->doFinalization(M); + + return Changed; +} + +//===----------------------------------------------------------------------===// +// MPPassManager implementation + +/// Execute all of the passes scheduled for execution by invoking +/// runOnModule method. Keep track of whether any of the passes modifies +/// the module, and if so, return true. +bool +MPPassManager::runOnModule(Module &M) { + bool Changed = false; + + // Initialize on-the-fly passes + for (std::map<Pass *, FunctionPassManagerImpl *>::iterator + I = OnTheFlyManagers.begin(), E = OnTheFlyManagers.end(); + I != E; ++I) { + FunctionPassManagerImpl *FPP = I->second; + Changed |= FPP->doInitialization(M); + } + + // Initialize module passes + for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) + Changed |= getContainedPass(Index)->doInitialization(M); + + for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { + ModulePass *MP = getContainedPass(Index); + bool LocalChanged = false; + + dumpPassInfo(MP, EXECUTION_MSG, ON_MODULE_MSG, M.getModuleIdentifier()); + dumpRequiredSet(MP); + + initializeAnalysisImpl(MP); + + { + PassManagerPrettyStackEntry X(MP, M); + TimeRegion PassTimer(getPassTimer(MP)); + + LocalChanged |= MP->runOnModule(M); + } + + Changed |= LocalChanged; + if (LocalChanged) + dumpPassInfo(MP, MODIFICATION_MSG, ON_MODULE_MSG, + M.getModuleIdentifier()); + dumpPreservedSet(MP); + + verifyPreservedAnalysis(MP); + removeNotPreservedAnalysis(MP); + recordAvailableAnalysis(MP); + removeDeadPasses(MP, M.getModuleIdentifier(), ON_MODULE_MSG); + } + + // Finalize module passes + for (int Index = getNumContainedPasses() - 1; Index >= 0; --Index) + Changed |= getContainedPass(Index)->doFinalization(M); + + // Finalize on-the-fly passes + for (std::map<Pass *, FunctionPassManagerImpl *>::iterator + I = OnTheFlyManagers.begin(), E = OnTheFlyManagers.end(); + I != E; ++I) { + FunctionPassManagerImpl *FPP = I->second; + // We don't know when is the last time an on-the-fly pass is run, + // so we need to releaseMemory / finalize here + FPP->releaseMemoryOnTheFly(); + Changed |= FPP->doFinalization(M); + } + + return Changed; +} + +/// Add RequiredPass into list of lower level passes required by pass P. +/// RequiredPass is run on the fly by Pass Manager when P requests it +/// through getAnalysis interface. +void MPPassManager::addLowerLevelRequiredPass(Pass *P, Pass *RequiredPass) { + assert(P->getPotentialPassManagerType() == PMT_ModulePassManager && + "Unable to handle Pass that requires lower level Analysis pass"); + assert((P->getPotentialPassManagerType() < + RequiredPass->getPotentialPassManagerType()) && + "Unable to handle Pass that requires lower level Analysis pass"); + + FunctionPassManagerImpl *FPP = OnTheFlyManagers[P]; + if (!FPP) { + FPP = new FunctionPassManagerImpl(); + // FPP is the top level manager. + FPP->setTopLevelManager(FPP); + + OnTheFlyManagers[P] = FPP; + } + FPP->add(RequiredPass); + + // Register P as the last user of RequiredPass. + if (RequiredPass) { + SmallVector<Pass *, 1> LU; + LU.push_back(RequiredPass); + FPP->setLastUser(LU, P); + } +} + +/// Return function pass corresponding to PassInfo PI, that is +/// required by module pass MP. Instantiate analysis pass, by using +/// its runOnFunction() for function F. +Pass* MPPassManager::getOnTheFlyPass(Pass *MP, AnalysisID PI, Function &F){ + FunctionPassManagerImpl *FPP = OnTheFlyManagers[MP]; + assert(FPP && "Unable to find on the fly pass"); + + FPP->releaseMemoryOnTheFly(); + FPP->run(F); + return ((PMTopLevelManager*)FPP)->findAnalysisPass(PI); +} + + +//===----------------------------------------------------------------------===// +// PassManagerImpl implementation + +// +/// run - Execute all of the passes scheduled for execution. Keep track of +/// whether any of the passes modifies the module, and if so, return true. +bool PassManagerImpl::run(Module &M) { + bool Changed = false; + TimingInfo::createTheTimeInfo(); + + dumpArguments(); + dumpPasses(); + + SmallVectorImpl<ImmutablePass *>& IPV = getImmutablePasses(); + for (SmallVectorImpl<ImmutablePass *>::const_iterator I = IPV.begin(), + E = IPV.end(); I != E; ++I) { + Changed |= (*I)->doInitialization(M); + } + + initializeAllAnalysisInfo(); + for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) + Changed |= getContainedManager(Index)->runOnModule(M); + + for (SmallVectorImpl<ImmutablePass *>::const_iterator I = IPV.begin(), + E = IPV.end(); I != E; ++I) { + Changed |= (*I)->doFinalization(M); + } + + return Changed; +} + +//===----------------------------------------------------------------------===// +// PassManager implementation + +/// Create new pass manager +PassManager::PassManager() { + PM = new PassManagerImpl(); + // PM is the top level manager + PM->setTopLevelManager(PM); +} + +PassManager::~PassManager() { + delete PM; +} + +/// add - Add a pass to the queue of passes to run. This passes ownership of +/// the Pass to the PassManager. When the PassManager is destroyed, the pass +/// will be destroyed as well, so there is no need to delete the pass. This +/// implies that all passes MUST be allocated with 'new'. +void PassManager::add(Pass *P) { + PM->add(P); +} + +/// run - Execute all of the passes scheduled for execution. Keep track of +/// whether any of the passes modifies the module, and if so, return true. +bool PassManager::run(Module &M) { + return PM->run(M); +} + +//===----------------------------------------------------------------------===// +// TimingInfo implementation + +bool llvm::TimePassesIsEnabled = false; +static cl::opt<bool,true> +EnableTiming("time-passes", cl::location(TimePassesIsEnabled), + cl::desc("Time each pass, printing elapsed time for each on exit")); + +// createTheTimeInfo - This method either initializes the TheTimeInfo pointer to +// a non null value (if the -time-passes option is enabled) or it leaves it +// null. It may be called multiple times. +void TimingInfo::createTheTimeInfo() { + if (!TimePassesIsEnabled || TheTimeInfo) return; + + // Constructed the first time this is called, iff -time-passes is enabled. + // This guarantees that the object will be constructed before static globals, + // thus it will be destroyed before them. + static ManagedStatic<TimingInfo> TTI; + TheTimeInfo = &*TTI; +} + +/// If TimingInfo is enabled then start pass timer. +Timer *llvm::getPassTimer(Pass *P) { + if (TheTimeInfo) + return TheTimeInfo->getPassTimer(P); + return 0; +} + +//===----------------------------------------------------------------------===// +// PMStack implementation +// + +// Pop Pass Manager from the stack and clear its analysis info. +void PMStack::pop() { + + PMDataManager *Top = this->top(); + Top->initializeAnalysisInfo(); + + S.pop_back(); +} + +// Push PM on the stack and set its top level manager. +void PMStack::push(PMDataManager *PM) { + assert(PM && "Unable to push. Pass Manager expected"); + assert(PM->getDepth()==0 && "Pass Manager depth set too early"); + + if (!this->empty()) { + assert(PM->getPassManagerType() > this->top()->getPassManagerType() + && "pushing bad pass manager to PMStack"); + PMTopLevelManager *TPM = this->top()->getTopLevelManager(); + + assert(TPM && "Unable to find top level manager"); + TPM->addIndirectPassManager(PM); + PM->setTopLevelManager(TPM); + PM->setDepth(this->top()->getDepth()+1); + } else { + assert((PM->getPassManagerType() == PMT_ModulePassManager + || PM->getPassManagerType() == PMT_FunctionPassManager) + && "pushing bad pass manager to PMStack"); + PM->setDepth(1); + } + + S.push_back(PM); +} + +// Dump content of the pass manager stack. +void PMStack::dump() const { + for (std::vector<PMDataManager *>::const_iterator I = S.begin(), + E = S.end(); I != E; ++I) + dbgs() << (*I)->getAsPass()->getPassName() << ' '; + + if (!S.empty()) + dbgs() << '\n'; +} + +/// Find appropriate Module Pass Manager in the PM Stack and +/// add self into that manager. +void ModulePass::assignPassManager(PMStack &PMS, + PassManagerType PreferredType) { + // Find Module Pass Manager + while (!PMS.empty()) { + PassManagerType TopPMType = PMS.top()->getPassManagerType(); + if (TopPMType == PreferredType) + break; // We found desired pass manager + else if (TopPMType > PMT_ModulePassManager) + PMS.pop(); // Pop children pass managers + else + break; + } + assert(!PMS.empty() && "Unable to find appropriate Pass Manager"); + PMS.top()->add(this); +} + +/// Find appropriate Function Pass Manager or Call Graph Pass Manager +/// in the PM Stack and add self into that manager. +void FunctionPass::assignPassManager(PMStack &PMS, + PassManagerType PreferredType) { + + // Find Function Pass Manager + while (!PMS.empty()) { + if (PMS.top()->getPassManagerType() > PMT_FunctionPassManager) + PMS.pop(); + else + break; + } + + // Create new Function Pass Manager if needed. + FPPassManager *FPP; + if (PMS.top()->getPassManagerType() == PMT_FunctionPassManager) { + FPP = (FPPassManager *)PMS.top(); + } else { + assert(!PMS.empty() && "Unable to create Function Pass Manager"); + PMDataManager *PMD = PMS.top(); + + // [1] Create new Function Pass Manager + FPP = new FPPassManager(); + FPP->populateInheritedAnalysis(PMS); + + // [2] Set up new manager's top level manager + PMTopLevelManager *TPM = PMD->getTopLevelManager(); + TPM->addIndirectPassManager(FPP); + + // [3] Assign manager to manage this new manager. This may create + // and push new managers into PMS + FPP->assignPassManager(PMS, PMD->getPassManagerType()); + + // [4] Push new manager into PMS + PMS.push(FPP); + } + + // Assign FPP as the manager of this pass. + FPP->add(this); +} + +/// Find appropriate Basic Pass Manager or Call Graph Pass Manager +/// in the PM Stack and add self into that manager. +void BasicBlockPass::assignPassManager(PMStack &PMS, + PassManagerType PreferredType) { + BBPassManager *BBP; + + // Basic Pass Manager is a leaf pass manager. It does not handle + // any other pass manager. + if (!PMS.empty() && + PMS.top()->getPassManagerType() == PMT_BasicBlockPassManager) { + BBP = (BBPassManager *)PMS.top(); + } else { + // If leaf manager is not Basic Block Pass manager then create new + // basic Block Pass manager. + assert(!PMS.empty() && "Unable to create BasicBlock Pass Manager"); + PMDataManager *PMD = PMS.top(); + + // [1] Create new Basic Block Manager + BBP = new BBPassManager(); + + // [2] Set up new manager's top level manager + // Basic Block Pass Manager does not live by itself + PMTopLevelManager *TPM = PMD->getTopLevelManager(); + TPM->addIndirectPassManager(BBP); + + // [3] Assign manager to manage this new manager. This may create + // and push new managers into PMS + BBP->assignPassManager(PMS, PreferredType); + + // [4] Push new manager into PMS + PMS.push(BBP); + } + + // Assign BBP as the manager of this pass. + BBP->add(this); +} + +PassManagerBase::~PassManagerBase() {} diff --git a/lib/IR/Metadata.cpp b/lib/IR/Metadata.cpp index bd4d9c0..a32d25c 100644 --- a/lib/IR/Metadata.cpp +++ b/lib/IR/Metadata.cpp @@ -65,7 +65,7 @@ class MDNodeOperand : public CallbackVH { public: MDNodeOperand(Value *V) : CallbackVH(V) {} - ~MDNodeOperand() {} + virtual ~MDNodeOperand(); void set(Value *V) { unsigned IsFirst = this->getValPtrInt(); @@ -82,6 +82,8 @@ public: }; } // end namespace llvm. +// Provide out-of-line definition to prevent weak vtable. +MDNodeOperand::~MDNodeOperand() {} void MDNodeOperand::deleted() { getParent()->replaceOperand(this, 0); diff --git a/lib/IR/Module.cpp b/lib/IR/Module.cpp index 968b8f4..4f240c7 100644 --- a/lib/IR/Module.cpp +++ b/lib/IR/Module.cpp @@ -245,7 +245,7 @@ GlobalVariable *Module::getGlobalVariable(StringRef Name, bool AllowLocal) { /// 1. If it does not exist, add a declaration of the global and return it. /// 2. Else, the global exists but has the wrong type: return the function /// with a constantexpr cast to the right type. -/// 3. Finally, if the existing global is the correct delclaration, return the +/// 3. Finally, if the existing global is the correct declaration, return the /// existing global. Constant *Module::getOrInsertGlobal(StringRef Name, Type *Ty) { // See if we have a definition for the specified global already. @@ -260,8 +260,10 @@ Constant *Module::getOrInsertGlobal(StringRef Name, Type *Ty) { // If the variable exists but has the wrong type, return a bitcast to the // right type. - if (GV->getType() != PointerType::getUnqual(Ty)) - return ConstantExpr::getBitCast(GV, PointerType::getUnqual(Ty)); + Type *GVTy = GV->getType(); + PointerType *PTy = PointerType::get(Ty, GVTy->getPointerAddressSpace()); + if (GVTy != PTy) + return ConstantExpr::getBitCast(GV, PTy); // Otherwise, we just found the existing function or a prototype. return GV; @@ -316,11 +318,16 @@ getModuleFlagsMetadata(SmallVectorImpl<ModuleFlagEntry> &Flags) const { for (unsigned i = 0, e = ModFlags->getNumOperands(); i != e; ++i) { MDNode *Flag = ModFlags->getOperand(i); - ConstantInt *Behavior = cast<ConstantInt>(Flag->getOperand(0)); - MDString *Key = cast<MDString>(Flag->getOperand(1)); - Value *Val = Flag->getOperand(2); - Flags.push_back(ModuleFlagEntry(ModFlagBehavior(Behavior->getZExtValue()), - Key, Val)); + if (Flag->getNumOperands() >= 3 && isa<ConstantInt>(Flag->getOperand(0)) && + isa<MDString>(Flag->getOperand(1))) { + // Check the operands of the MDNode before accessing the operands. + // The verifier will actually catch these failures. + ConstantInt *Behavior = cast<ConstantInt>(Flag->getOperand(0)); + MDString *Key = cast<MDString>(Flag->getOperand(1)); + Value *Val = Flag->getOperand(2); + Flags.push_back(ModuleFlagEntry(ModFlagBehavior(Behavior->getZExtValue()), + Key, Val)); + } } } @@ -399,9 +406,15 @@ bool Module::isDematerializable(const GlobalValue *GV) const { } bool Module::Materialize(GlobalValue *GV, std::string *ErrInfo) { - if (Materializer) - return Materializer->Materialize(GV, ErrInfo); - return false; + if (!Materializer) + return false; + + error_code EC = Materializer->Materialize(GV); + if (!EC) + return false; + if (ErrInfo) + *ErrInfo = EC.message(); + return true; } void Module::Dematerialize(GlobalValue *GV) { @@ -412,7 +425,12 @@ void Module::Dematerialize(GlobalValue *GV) { bool Module::MaterializeAll(std::string *ErrInfo) { if (!Materializer) return false; - return Materializer->MaterializeModule(this, ErrInfo); + error_code EC = Materializer->MaterializeModule(this); + if (!EC) + return false; + if (ErrInfo) + *ErrInfo = EC.message(); + return true; } bool Module::MaterializeAllPermanently(std::string *ErrInfo) { diff --git a/lib/IR/PassManager.cpp b/lib/IR/PassManager.cpp index ee53c85..966af7d 100644 --- a/lib/IR/PassManager.cpp +++ b/lib/IR/PassManager.cpp @@ -1,4 +1,4 @@ -//===- PassManager.cpp - LLVM Pass Infrastructure Implementation ----------===// +//===- PassManager.h - Infrastructure for managing & running IR passes ----===// // // The LLVM Compiler Infrastructure // @@ -6,1907 +6,152 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -// -// This file implements the LLVM Pass Manager infrastructure. -// -//===----------------------------------------------------------------------===// +#include "llvm/IR/PassManager.h" +#include "llvm/ADT/STLExtras.h" -#include "llvm/PassManagers.h" -#include "llvm/Assembly/PrintModulePass.h" -#include "llvm/Assembly/Writer.h" -#include "llvm/IR/Module.h" -#include "llvm/PassManager.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/ManagedStatic.h" -#include "llvm/Support/Mutex.h" -#include "llvm/Support/PassNameParser.h" -#include "llvm/Support/Timer.h" -#include "llvm/Support/raw_ostream.h" -#include <algorithm> -#include <map> using namespace llvm; -// See PassManagers.h for Pass Manager infrastructure overview. - -namespace llvm { - -//===----------------------------------------------------------------------===// -// Pass debugging information. Often it is useful to find out what pass is -// running when a crash occurs in a utility. When this library is compiled with -// debugging on, a command line option (--debug-pass) is enabled that causes the -// pass name to be printed before it executes. -// - -// Different debug levels that can be enabled... -enum PassDebugLevel { - Disabled, Arguments, Structure, Executions, Details -}; - -static cl::opt<enum PassDebugLevel> -PassDebugging("debug-pass", cl::Hidden, - cl::desc("Print PassManager debugging information"), - cl::values( - clEnumVal(Disabled , "disable debug output"), - clEnumVal(Arguments , "print pass arguments to pass to 'opt'"), - clEnumVal(Structure , "print pass structure before run()"), - clEnumVal(Executions, "print pass name before it is executed"), - clEnumVal(Details , "print pass details when it is executed"), - clEnumValEnd)); - -typedef llvm::cl::list<const llvm::PassInfo *, bool, PassNameParser> -PassOptionList; - -// Print IR out before/after specified passes. -static PassOptionList -PrintBefore("print-before", - llvm::cl::desc("Print IR before specified passes"), - cl::Hidden); - -static PassOptionList -PrintAfter("print-after", - llvm::cl::desc("Print IR after specified passes"), - cl::Hidden); - -static cl::opt<bool> -PrintBeforeAll("print-before-all", - llvm::cl::desc("Print IR before each pass"), - cl::init(false)); -static cl::opt<bool> -PrintAfterAll("print-after-all", - llvm::cl::desc("Print IR after each pass"), - cl::init(false)); - -/// This is a helper to determine whether to print IR before or -/// after a pass. - -static bool ShouldPrintBeforeOrAfterPass(const PassInfo *PI, - PassOptionList &PassesToPrint) { - for (unsigned i = 0, ie = PassesToPrint.size(); i < ie; ++i) { - const llvm::PassInfo *PassInf = PassesToPrint[i]; - if (PassInf) - if (PassInf->getPassArgument() == PI->getPassArgument()) { - return true; - } - } - return false; -} - -/// This is a utility to check whether a pass should have IR dumped -/// before it. -static bool ShouldPrintBeforePass(const PassInfo *PI) { - return PrintBeforeAll || ShouldPrintBeforeOrAfterPass(PI, PrintBefore); -} - -/// This is a utility to check whether a pass should have IR dumped -/// after it. -static bool ShouldPrintAfterPass(const PassInfo *PI) { - return PrintAfterAll || ShouldPrintBeforeOrAfterPass(PI, PrintAfter); -} - -} // End of llvm namespace - -/// isPassDebuggingExecutionsOrMore - Return true if -debug-pass=Executions -/// or higher is specified. -bool PMDataManager::isPassDebuggingExecutionsOrMore() const { - return PassDebugging >= Executions; -} - - - - -void PassManagerPrettyStackEntry::print(raw_ostream &OS) const { - if (V == 0 && M == 0) - OS << "Releasing pass '"; - else - OS << "Running pass '"; - - OS << P->getPassName() << "'"; - - if (M) { - OS << " on module '" << M->getModuleIdentifier() << "'.\n"; - return; - } - if (V == 0) { - OS << '\n'; - return; - } - - OS << " on "; - if (isa<Function>(V)) - OS << "function"; - else if (isa<BasicBlock>(V)) - OS << "basic block"; - else - OS << "value"; - - OS << " '"; - WriteAsOperand(OS, V, /*PrintTy=*/false, M); - OS << "'\n"; +void ModulePassManager::run() { + for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx) + if (Passes[Idx]->run(M)) + if (AM) AM->invalidateAll(M); } - -namespace { - -//===----------------------------------------------------------------------===// -// BBPassManager -// -/// BBPassManager manages BasicBlockPass. It batches all the -/// pass together and sequence them to process one basic block before -/// processing next basic block. -class BBPassManager : public PMDataManager, public FunctionPass { - -public: - static char ID; - explicit BBPassManager() - : PMDataManager(), FunctionPass(ID) {} - - /// Execute all of the passes scheduled for execution. Keep track of - /// whether any of the passes modifies the function, and if so, return true. - bool runOnFunction(Function &F); - - /// Pass Manager itself does not invalidate any analysis info. - void getAnalysisUsage(AnalysisUsage &Info) const { - Info.setPreservesAll(); - } - - bool doInitialization(Module &M); - bool doInitialization(Function &F); - bool doFinalization(Module &M); - bool doFinalization(Function &F); - - virtual PMDataManager *getAsPMDataManager() { return this; } - virtual Pass *getAsPass() { return this; } - - virtual const char *getPassName() const { - return "BasicBlock Pass Manager"; - } - - // Print passes managed by this manager - void dumpPassStructure(unsigned Offset) { - llvm::dbgs().indent(Offset*2) << "BasicBlockPass Manager\n"; - for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { - BasicBlockPass *BP = getContainedPass(Index); - BP->dumpPassStructure(Offset + 1); - dumpLastUses(BP, Offset+1); - } - } - - BasicBlockPass *getContainedPass(unsigned N) { - assert(N < PassVector.size() && "Pass number out of range!"); - BasicBlockPass *BP = static_cast<BasicBlockPass *>(PassVector[N]); - return BP; - } - - virtual PassManagerType getPassManagerType() const { - return PMT_BasicBlockPassManager; - } -}; - -char BBPassManager::ID = 0; -} - -namespace llvm { - -//===----------------------------------------------------------------------===// -// FunctionPassManagerImpl -// -/// FunctionPassManagerImpl manages FPPassManagers -class FunctionPassManagerImpl : public Pass, - public PMDataManager, - public PMTopLevelManager { - virtual void anchor(); -private: - bool wasRun; -public: - static char ID; - explicit FunctionPassManagerImpl() : - Pass(PT_PassManager, ID), PMDataManager(), - PMTopLevelManager(new FPPassManager()), wasRun(false) {} - - /// add - Add a pass to the queue of passes to run. This passes ownership of - /// the Pass to the PassManager. When the PassManager is destroyed, the pass - /// will be destroyed as well, so there is no need to delete the pass. This - /// implies that all passes MUST be allocated with 'new'. - void add(Pass *P) { - schedulePass(P); - } - - /// createPrinterPass - Get a function printer pass. - Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const { - return createPrintFunctionPass(Banner, &O); - } - - // Prepare for running an on the fly pass, freeing memory if needed - // from a previous run. - void releaseMemoryOnTheFly(); - - /// run - Execute all of the passes scheduled for execution. Keep track of - /// whether any of the passes modifies the module, and if so, return true. - bool run(Function &F); - - /// doInitialization - Run all of the initializers for the function passes. - /// - bool doInitialization(Module &M); - - /// doFinalization - Run all of the finalizers for the function passes. - /// - bool doFinalization(Module &M); - - - virtual PMDataManager *getAsPMDataManager() { return this; } - virtual Pass *getAsPass() { return this; } - virtual PassManagerType getTopLevelPassManagerType() { - return PMT_FunctionPassManager; - } - - /// Pass Manager itself does not invalidate any analysis info. - void getAnalysisUsage(AnalysisUsage &Info) const { - Info.setPreservesAll(); - } - - FPPassManager *getContainedManager(unsigned N) { - assert(N < PassManagers.size() && "Pass number out of range!"); - FPPassManager *FP = static_cast<FPPassManager *>(PassManagers[N]); - return FP; - } -}; - -void FunctionPassManagerImpl::anchor() {} - -char FunctionPassManagerImpl::ID = 0; - -//===----------------------------------------------------------------------===// -// MPPassManager -// -/// MPPassManager manages ModulePasses and function pass managers. -/// It batches all Module passes and function pass managers together and -/// sequences them to process one module. -class MPPassManager : public Pass, public PMDataManager { -public: - static char ID; - explicit MPPassManager() : - Pass(PT_PassManager, ID), PMDataManager() { } - - // Delete on the fly managers. - virtual ~MPPassManager() { - for (std::map<Pass *, FunctionPassManagerImpl *>::iterator - I = OnTheFlyManagers.begin(), E = OnTheFlyManagers.end(); - I != E; ++I) { - FunctionPassManagerImpl *FPP = I->second; - delete FPP; - } - } - - /// createPrinterPass - Get a module printer pass. - Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const { - return createPrintModulePass(&O, false, Banner); - } - - /// run - Execute all of the passes scheduled for execution. Keep track of - /// whether any of the passes modifies the module, and if so, return true. - bool runOnModule(Module &M); - - using llvm::Pass::doInitialization; - using llvm::Pass::doFinalization; - - /// doInitialization - Run all of the initializers for the module passes. - /// - bool doInitialization(); - - /// doFinalization - Run all of the finalizers for the module passes. - /// - bool doFinalization(); - - /// Pass Manager itself does not invalidate any analysis info. - void getAnalysisUsage(AnalysisUsage &Info) const { - Info.setPreservesAll(); - } - - /// Add RequiredPass into list of lower level passes required by pass P. - /// RequiredPass is run on the fly by Pass Manager when P requests it - /// through getAnalysis interface. - virtual void addLowerLevelRequiredPass(Pass *P, Pass *RequiredPass); - - /// Return function pass corresponding to PassInfo PI, that is - /// required by module pass MP. Instantiate analysis pass, by using - /// its runOnFunction() for function F. - virtual Pass* getOnTheFlyPass(Pass *MP, AnalysisID PI, Function &F); - - virtual const char *getPassName() const { - return "Module Pass Manager"; - } - - virtual PMDataManager *getAsPMDataManager() { return this; } - virtual Pass *getAsPass() { return this; } - - // Print passes managed by this manager - void dumpPassStructure(unsigned Offset) { - llvm::dbgs().indent(Offset*2) << "ModulePass Manager\n"; - for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { - ModulePass *MP = getContainedPass(Index); - MP->dumpPassStructure(Offset + 1); - std::map<Pass *, FunctionPassManagerImpl *>::const_iterator I = - OnTheFlyManagers.find(MP); - if (I != OnTheFlyManagers.end()) - I->second->dumpPassStructure(Offset + 2); - dumpLastUses(MP, Offset+1); - } - } - - ModulePass *getContainedPass(unsigned N) { - assert(N < PassVector.size() && "Pass number out of range!"); - return static_cast<ModulePass *>(PassVector[N]); - } - - virtual PassManagerType getPassManagerType() const { - return PMT_ModulePassManager; - } - - private: - /// Collection of on the fly FPPassManagers. These managers manage - /// function passes that are required by module passes. - std::map<Pass *, FunctionPassManagerImpl *> OnTheFlyManagers; -}; - -char MPPassManager::ID = 0; -//===----------------------------------------------------------------------===// -// PassManagerImpl -// - -/// PassManagerImpl manages MPPassManagers -class PassManagerImpl : public Pass, - public PMDataManager, - public PMTopLevelManager { - virtual void anchor(); - -public: - static char ID; - explicit PassManagerImpl() : - Pass(PT_PassManager, ID), PMDataManager(), - PMTopLevelManager(new MPPassManager()) {} - - /// add - Add a pass to the queue of passes to run. This passes ownership of - /// the Pass to the PassManager. When the PassManager is destroyed, the pass - /// will be destroyed as well, so there is no need to delete the pass. This - /// implies that all passes MUST be allocated with 'new'. - void add(Pass *P) { - schedulePass(P); - } - - /// createPrinterPass - Get a module printer pass. - Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const { - return createPrintModulePass(&O, false, Banner); - } - - /// run - Execute all of the passes scheduled for execution. Keep track of - /// whether any of the passes modifies the module, and if so, return true. - bool run(Module &M); - - using llvm::Pass::doInitialization; - using llvm::Pass::doFinalization; - - /// doInitialization - Run all of the initializers for the module passes. - /// - bool doInitialization(); - - /// doFinalization - Run all of the finalizers for the module passes. - /// - bool doFinalization(); - - /// Pass Manager itself does not invalidate any analysis info. - void getAnalysisUsage(AnalysisUsage &Info) const { - Info.setPreservesAll(); - } - - virtual PMDataManager *getAsPMDataManager() { return this; } - virtual Pass *getAsPass() { return this; } - virtual PassManagerType getTopLevelPassManagerType() { - return PMT_ModulePassManager; - } - - MPPassManager *getContainedManager(unsigned N) { - assert(N < PassManagers.size() && "Pass number out of range!"); - MPPassManager *MP = static_cast<MPPassManager *>(PassManagers[N]); - return MP; - } -}; - -void PassManagerImpl::anchor() {} - -char PassManagerImpl::ID = 0; -} // End of llvm namespace - -namespace { - -//===----------------------------------------------------------------------===// -/// TimingInfo Class - This class is used to calculate information about the -/// amount of time each pass takes to execute. This only happens when -/// -time-passes is enabled on the command line. -/// - -static ManagedStatic<sys::SmartMutex<true> > TimingInfoMutex; - -class TimingInfo { - DenseMap<Pass*, Timer*> TimingData; - TimerGroup TG; -public: - // Use 'create' member to get this. - TimingInfo() : TG("... Pass execution timing report ...") {} - - // TimingDtor - Print out information about timing information - ~TimingInfo() { - // Delete all of the timers, which accumulate their info into the - // TimerGroup. - for (DenseMap<Pass*, Timer*>::iterator I = TimingData.begin(), - E = TimingData.end(); I != E; ++I) - delete I->second; - // TimerGroup is deleted next, printing the report. - } - - // createTheTimeInfo - This method either initializes the TheTimeInfo pointer - // to a non null value (if the -time-passes option is enabled) or it leaves it - // null. It may be called multiple times. - static void createTheTimeInfo(); - - /// getPassTimer - Return the timer for the specified pass if it exists. - Timer *getPassTimer(Pass *P) { - if (P->getAsPMDataManager()) - return 0; - - sys::SmartScopedLock<true> Lock(*TimingInfoMutex); - Timer *&T = TimingData[P]; - if (T == 0) - T = new Timer(P->getPassName(), TG); - return T; - } -}; - -} // End of anon namespace - -static TimingInfo *TheTimeInfo; - -//===----------------------------------------------------------------------===// -// PMTopLevelManager implementation - -/// Initialize top level manager. Create first pass manager. -PMTopLevelManager::PMTopLevelManager(PMDataManager *PMDM) { - PMDM->setTopLevelManager(this); - addPassManager(PMDM); - activeStack.push(PMDM); -} - -/// Set pass P as the last user of the given analysis passes. -void -PMTopLevelManager::setLastUser(ArrayRef<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; - - 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 existing entries. - LastUser[LUI->first] = P; - } - } -} - -/// Collect passes whose last user is P -void PMTopLevelManager::collectLastUses(SmallVectorImpl<Pass *> &LastUses, - Pass *P) { - DenseMap<Pass *, SmallPtrSet<Pass *, 8> >::iterator DMI = - InversedLastUser.find(P); - if (DMI == InversedLastUser.end()) - return; - - SmallPtrSet<Pass *, 8> &LU = DMI->second; - for (SmallPtrSet<Pass *, 8>::iterator I = LU.begin(), - E = LU.end(); I != E; ++I) { - LastUses.push_back(*I); - } - -} - -AnalysisUsage *PMTopLevelManager::findAnalysisUsage(Pass *P) { - AnalysisUsage *AnUsage = NULL; - DenseMap<Pass *, AnalysisUsage *>::iterator DMI = AnUsageMap.find(P); - if (DMI != AnUsageMap.end()) - AnUsage = DMI->second; - else { - AnUsage = new AnalysisUsage(); - P->getAnalysisUsage(*AnUsage); - AnUsageMap[P] = AnUsage; - } - return AnUsage; -} - -/// Schedule pass P for execution. Make sure that passes required by -/// P are run before P is run. Update analysis info maintained by -/// the manager. Remove dead passes. This is a recursive function. -void PMTopLevelManager::schedulePass(Pass *P) { - - // TODO : Allocate function manager for this pass, other wise required set - // may be inserted into previous function manager - - // Give pass a chance to prepare the stage. - P->preparePassManager(activeStack); - - // If P is an analysis pass and it is available then do not - // generate the analysis again. Stale analysis info should not be - // available at this point. - const PassInfo *PI = - PassRegistry::getPassRegistry()->getPassInfo(P->getPassID()); - if (PI && PI->isAnalysis() && findAnalysisPass(P->getPassID())) { - delete P; - return; - } - - AnalysisUsage *AnUsage = findAnalysisUsage(P); - - bool checkAnalysis = true; - while (checkAnalysis) { - checkAnalysis = false; - - const AnalysisUsage::VectorType &RequiredSet = AnUsage->getRequiredSet(); - for (AnalysisUsage::VectorType::const_iterator I = RequiredSet.begin(), - E = RequiredSet.end(); I != E; ++I) { - - Pass *AnalysisPass = findAnalysisPass(*I); - if (!AnalysisPass) { - const PassInfo *PI = PassRegistry::getPassRegistry()->getPassInfo(*I); - - if (PI == NULL) { - // Pass P is not in the global PassRegistry - dbgs() << "Pass '" << P->getPassName() << "' is not initialized." << "\n"; - dbgs() << "Verify if there is a pass dependency cycle." << "\n"; - dbgs() << "Required Passes:" << "\n"; - for (AnalysisUsage::VectorType::const_iterator I2 = RequiredSet.begin(), - E = RequiredSet.end(); I2 != E && I2 != I; ++I2) { - Pass *AnalysisPass2 = findAnalysisPass(*I2); - if (AnalysisPass2) { - dbgs() << "\t" << AnalysisPass2->getPassName() << "\n"; - } else { - dbgs() << "\t" << "Error: Required pass not found! Possible causes:" << "\n"; - dbgs() << "\t\t" << "- Pass misconfiguration (e.g.: missing macros)" << "\n"; - dbgs() << "\t\t" << "- Corruption of the global PassRegistry" << "\n"; - } - } - } - - assert(PI && "Expected required passes to be initialized"); - AnalysisPass = PI->createPass(); - if (P->getPotentialPassManagerType () == - AnalysisPass->getPotentialPassManagerType()) - // Schedule analysis pass that is managed by the same pass manager. - schedulePass(AnalysisPass); - else if (P->getPotentialPassManagerType () > - AnalysisPass->getPotentialPassManagerType()) { - // Schedule analysis pass that is managed by a new manager. - schedulePass(AnalysisPass); - // Recheck analysis passes to ensure that required analyses that - // are already checked are still available. - checkAnalysis = true; - } else - // Do not schedule this analysis. Lower level analsyis - // passes are run on the fly. - delete AnalysisPass; +bool FunctionPassManager::run(Module *M) { + bool Changed = false; + for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) + for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx) + if (Passes[Idx]->run(I)) { + Changed = true; + if (AM) AM->invalidateAll(I); } - } - } - - // Now all required passes are available. - if (ImmutablePass *IP = P->getAsImmutablePass()) { - // P is a immutable pass and it will be managed by this - // top level manager. Set up analysis resolver to connect them. - PMDataManager *DM = getAsPMDataManager(); - AnalysisResolver *AR = new AnalysisResolver(*DM); - P->setResolver(AR); - DM->initializeAnalysisImpl(P); - addImmutablePass(IP); - DM->recordAvailableAnalysis(IP); - return; - } - - if (PI && !PI->isAnalysis() && ShouldPrintBeforePass(PI)) { - Pass *PP = P->createPrinterPass( - dbgs(), std::string("*** IR Dump Before ") + P->getPassName() + " ***"); - PP->assignPassManager(activeStack, getTopLevelPassManagerType()); - } - - // Add the requested pass to the best available pass manager. - P->assignPassManager(activeStack, getTopLevelPassManagerType()); - - if (PI && !PI->isAnalysis() && ShouldPrintAfterPass(PI)) { - Pass *PP = P->createPrinterPass( - dbgs(), std::string("*** IR Dump After ") + P->getPassName() + " ***"); - PP->assignPassManager(activeStack, getTopLevelPassManagerType()); - } -} - -/// Find the pass that implements Analysis AID. Search immutable -/// passes and all pass managers. If desired pass is not found -/// then return NULL. -Pass *PMTopLevelManager::findAnalysisPass(AnalysisID AID) { - - // Check pass managers - 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 (SmallVectorImpl<PMDataManager *>::iterator - I = IndirectPassManagers.begin(), - 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 (SmallVectorImpl<ImmutablePass *>::reverse_iterator I = - ImmutablePasses.rbegin(), E = ImmutablePasses.rend(); I != E; ++I) { - AnalysisID PI = (*I)->getPassID(); - if (PI == AID) - return *I; - - // 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(), - EE = ImmPI.end(); II != EE; ++II) { - if ((*II)->getTypeInfo() == AID) - return *I; - } - } - - return 0; -} - -// Print passes managed by this top level manager. -void PMTopLevelManager::dumpPasses() const { - - if (PassDebugging < Structure) - return; - - // Print out the immutable passes - for (unsigned i = 0, e = ImmutablePasses.size(); i != e; ++i) { - ImmutablePasses[i]->dumpPassStructure(0); - } - - // Every class that derives from PMDataManager also derives from Pass - // (sometimes indirectly), but there's no inheritance relationship - // between PMDataManager and Pass, so we have to getAsPass to get - // from a PMDataManager* to a Pass*. - for (SmallVectorImpl<PMDataManager *>::const_iterator I = - PassManagers.begin(), E = PassManagers.end(); I != E; ++I) - (*I)->getAsPass()->dumpPassStructure(1); -} - -void PMTopLevelManager::dumpArguments() const { - - if (PassDebugging < Arguments) - return; - - dbgs() << "Pass Arguments: "; - for (SmallVectorImpl<ImmutablePass *>::const_iterator I = - ImmutablePasses.begin(), E = ImmutablePasses.end(); I != E; ++I) - if (const PassInfo *PI = - PassRegistry::getPassRegistry()->getPassInfo((*I)->getPassID())) { - assert(PI && "Expected all immutable passes to be initialized"); - if (!PI->isAnalysisGroup()) - dbgs() << " -" << PI->getPassArgument(); - } - for (SmallVectorImpl<PMDataManager *>::const_iterator I = - PassManagers.begin(), E = PassManagers.end(); I != E; ++I) - (*I)->dumpPassArguments(); - dbgs() << "\n"; + return Changed; } -void PMTopLevelManager::initializeAllAnalysisInfo() { - for (SmallVectorImpl<PMDataManager *>::iterator I = PassManagers.begin(), - E = PassManagers.end(); I != E; ++I) - (*I)->initializeAnalysisInfo(); +void AnalysisManager::invalidateAll(Function *F) { + assert(F->getParent() == M && "Invalidating a function from another module!"); - // Initailize other pass managers - for (SmallVectorImpl<PMDataManager *>::iterator - I = IndirectPassManagers.begin(), E = IndirectPassManagers.end(); + // First invalidate any module results we still have laying about. + // FIXME: This is a total hack based on the fact that erasure doesn't + // invalidate iteration for DenseMap. + for (ModuleAnalysisResultMapT::iterator I = ModuleAnalysisResults.begin(), + E = ModuleAnalysisResults.end(); I != E; ++I) - (*I)->initializeAnalysisInfo(); - - for (DenseMap<Pass *, Pass *>::iterator DMI = LastUser.begin(), - DME = LastUser.end(); DMI != DME; ++DMI) { - DenseMap<Pass *, SmallPtrSet<Pass *, 8> >::iterator InvDMI = - InversedLastUser.find(DMI->second); - if (InvDMI != InversedLastUser.end()) { - SmallPtrSet<Pass *, 8> &L = InvDMI->second; - L.insert(DMI->first); + if (I->second->invalidate(M)) + ModuleAnalysisResults.erase(I); + + // Now clear all the invalidated results associated specifically with this + // function. + SmallVector<void *, 8> InvalidatedPassIDs; + FunctionAnalysisResultListT &ResultsList = FunctionAnalysisResultLists[F]; + for (FunctionAnalysisResultListT::iterator I = ResultsList.begin(), + E = ResultsList.end(); + I != E;) + if (I->second->invalidate(F)) { + InvalidatedPassIDs.push_back(I->first); + I = ResultsList.erase(I); } else { - SmallPtrSet<Pass *, 8> L; L.insert(DMI->first); - InversedLastUser[DMI->second] = L; + ++I; } - } -} - -/// Destructor -PMTopLevelManager::~PMTopLevelManager() { - for (SmallVectorImpl<PMDataManager *>::iterator I = PassManagers.begin(), - E = PassManagers.end(); I != E; ++I) - delete *I; - - for (SmallVectorImpl<ImmutablePass *>::iterator - I = ImmutablePasses.begin(), E = ImmutablePasses.end(); I != E; ++I) - delete *I; - - for (DenseMap<Pass *, AnalysisUsage *>::iterator DMI = AnUsageMap.begin(), - DME = AnUsageMap.end(); DMI != DME; ++DMI) - delete DMI->second; -} - -//===----------------------------------------------------------------------===// -// PMDataManager implementation - -/// Augement AvailableAnalysis by adding analysis made available by pass P. -void PMDataManager::recordAvailableAnalysis(Pass *P) { - AnalysisID PI = P->getPassID(); - - AvailableAnalysis[PI] = P; - - assert(!AvailableAnalysis.empty()); - - // This pass is the current implementation of all of the interfaces it - // implements as well. - const PassInfo *PInf = PassRegistry::getPassRegistry()->getPassInfo(PI); - if (PInf == 0) return; - const std::vector<const PassInfo*> &II = PInf->getInterfacesImplemented(); - for (unsigned i = 0, e = II.size(); i != e; ++i) - AvailableAnalysis[II[i]->getTypeInfo()] = P; + while (!InvalidatedPassIDs.empty()) + FunctionAnalysisResults.erase( + std::make_pair(InvalidatedPassIDs.pop_back_val(), F)); } -// Return true if P preserves high level analysis used by other -// passes managed by this manager -bool PMDataManager::preserveHigherLevelAnalysis(Pass *P) { - AnalysisUsage *AnUsage = TPM->findAnalysisUsage(P); - if (AnUsage->getPreservesAll()) - return true; - - const AnalysisUsage::VectorType &PreservedSet = AnUsage->getPreservedSet(); - for (SmallVectorImpl<Pass *>::iterator I = HigherLevelAnalysis.begin(), - E = HigherLevelAnalysis.end(); I != E; ++I) { - Pass *P1 = *I; - if (P1->getAsImmutablePass() == 0 && - std::find(PreservedSet.begin(), PreservedSet.end(), - P1->getPassID()) == - PreservedSet.end()) - return false; - } - - return true; -} - -/// verifyPreservedAnalysis -- Verify analysis preserved by pass P. -void PMDataManager::verifyPreservedAnalysis(Pass *P) { - // Don't do this unless assertions are enabled. -#ifdef NDEBUG - return; -#endif - AnalysisUsage *AnUsage = TPM->findAnalysisUsage(P); - const AnalysisUsage::VectorType &PreservedSet = AnUsage->getPreservedSet(); - - // Verify preserved analysis - for (AnalysisUsage::VectorType::const_iterator I = PreservedSet.begin(), - E = PreservedSet.end(); I != E; ++I) { - AnalysisID AID = *I; - if (Pass *AP = findAnalysisPass(AID, true)) { - TimeRegion PassTimer(getPassTimer(AP)); - AP->verifyAnalysis(); - } - } -} - -/// Remove Analysis not preserved by Pass P -void PMDataManager::removeNotPreservedAnalysis(Pass *P) { - AnalysisUsage *AnUsage = TPM->findAnalysisUsage(P); - if (AnUsage->getPreservesAll()) - return; - - const AnalysisUsage::VectorType &PreservedSet = AnUsage->getPreservedSet(); - for (DenseMap<AnalysisID, Pass*>::iterator I = AvailableAnalysis.begin(), - E = AvailableAnalysis.end(); I != E; ) { - DenseMap<AnalysisID, Pass*>::iterator Info = I++; - if (Info->second->getAsImmutablePass() == 0 && - std::find(PreservedSet.begin(), PreservedSet.end(), Info->first) == - PreservedSet.end()) { - // Remove this analysis - if (PassDebugging >= Details) { - Pass *S = Info->second; - dbgs() << " -- '" << P->getPassName() << "' is not preserving '"; - dbgs() << S->getPassName() << "'\n"; - } - AvailableAnalysis.erase(Info); - } - } - - // Check inherited analysis also. If P is not preserving analysis - // provided by parent manager then remove it here. - for (unsigned Index = 0; Index < PMT_Last; ++Index) { - - if (!InheritedAnalysis[Index]) - continue; - - for (DenseMap<AnalysisID, Pass*>::iterator - I = InheritedAnalysis[Index]->begin(), - E = InheritedAnalysis[Index]->end(); I != E; ) { - DenseMap<AnalysisID, Pass *>::iterator Info = I++; - if (Info->second->getAsImmutablePass() == 0 && - std::find(PreservedSet.begin(), PreservedSet.end(), Info->first) == - PreservedSet.end()) { - // Remove this analysis - if (PassDebugging >= Details) { - Pass *S = Info->second; - dbgs() << " -- '" << P->getPassName() << "' is not preserving '"; - dbgs() << S->getPassName() << "'\n"; - } - InheritedAnalysis[Index]->erase(Info); - } - } - } -} - -/// Remove analysis passes that are not used any longer -void PMDataManager::removeDeadPasses(Pass *P, StringRef Msg, - enum PassDebuggingString DBG_STR) { - - SmallVector<Pass *, 12> DeadPasses; - - // If this is a on the fly manager then it does not have TPM. - if (!TPM) - return; - - TPM->collectLastUses(DeadPasses, P); - - if (PassDebugging >= Details && !DeadPasses.empty()) { - dbgs() << " -*- '" << P->getPassName(); - dbgs() << "' is the last user of following pass instances."; - dbgs() << " Free these instances\n"; - } - - for (SmallVectorImpl<Pass *>::iterator I = DeadPasses.begin(), - E = DeadPasses.end(); I != E; ++I) - freePass(*I, Msg, DBG_STR); -} - -void PMDataManager::freePass(Pass *P, StringRef Msg, - enum PassDebuggingString DBG_STR) { - dumpPassInfo(P, FREEING_MSG, DBG_STR, Msg); - - { - // If the pass crashes releasing memory, remember this. - PassManagerPrettyStackEntry X(P); - TimeRegion PassTimer(getPassTimer(P)); - - P->releaseMemory(); - } - - AnalysisID PI = P->getPassID(); - if (const PassInfo *PInf = PassRegistry::getPassRegistry()->getPassInfo(PI)) { - // Remove the pass itself (if it is not already removed). - AvailableAnalysis.erase(PI); - - // Remove all interfaces this pass implements, for which it is also - // listed as the available implementation. - const std::vector<const PassInfo*> &II = PInf->getInterfacesImplemented(); - for (unsigned i = 0, e = II.size(); i != e; ++i) { - DenseMap<AnalysisID, Pass*>::iterator Pos = - AvailableAnalysis.find(II[i]->getTypeInfo()); - if (Pos != AvailableAnalysis.end() && Pos->second == P) - AvailableAnalysis.erase(Pos); - } - } -} - -/// Add pass P into the PassVector. Update -/// AvailableAnalysis appropriately if ProcessAnalysis is true. -void PMDataManager::add(Pass *P, bool ProcessAnalysis) { - // This manager is going to manage pass P. Set up analysis resolver - // to connect them. - AnalysisResolver *AR = new AnalysisResolver(*this); - P->setResolver(AR); - - // If a FunctionPass F is the last user of ModulePass info M - // then the F's manager, not F, records itself as a last user of M. - SmallVector<Pass *, 12> TransferLastUses; - - if (!ProcessAnalysis) { - // Add pass - PassVector.push_back(P); - return; - } - - // At the moment, this pass is the last user of all required passes. - SmallVector<Pass *, 12> LastUses; - SmallVector<Pass *, 8> RequiredPasses; - SmallVector<AnalysisID, 8> ReqAnalysisNotAvailable; - - unsigned PDepth = this->getDepth(); - - collectRequiredAnalysis(RequiredPasses, - ReqAnalysisNotAvailable, P); - for (SmallVectorImpl<Pass *>::iterator I = RequiredPasses.begin(), - E = RequiredPasses.end(); I != E; ++I) { - Pass *PRequired = *I; - unsigned RDepth = 0; - - assert(PRequired->getResolver() && "Analysis Resolver is not set"); - PMDataManager &DM = PRequired->getResolver()->getPMDataManager(); - RDepth = DM.getDepth(); - - if (PDepth == RDepth) - LastUses.push_back(PRequired); - else if (PDepth > RDepth) { - // Let the parent claim responsibility of last use - TransferLastUses.push_back(PRequired); - // Keep track of higher level analysis used by this manager. - HigherLevelAnalysis.push_back(PRequired); - } else - llvm_unreachable("Unable to accommodate Required Pass"); - } - - // Set P as P's last user until someone starts using P. - // However, if P is a Pass Manager then it does not need - // to record its last user. - if (P->getAsPMDataManager() == 0) - LastUses.push_back(P); - TPM->setLastUser(LastUses, P); - - if (!TransferLastUses.empty()) { - Pass *My_PM = getAsPass(); - TPM->setLastUser(TransferLastUses, My_PM); - TransferLastUses.clear(); - } - - // Now, take care of required analyses that are not available. - for (SmallVectorImpl<AnalysisID>::iterator - I = ReqAnalysisNotAvailable.begin(), - E = ReqAnalysisNotAvailable.end() ;I != E; ++I) { - const PassInfo *PI = PassRegistry::getPassRegistry()->getPassInfo(*I); - Pass *AnalysisPass = PI->createPass(); - this->addLowerLevelRequiredPass(P, AnalysisPass); - } - - // Take a note of analysis required and made available by this pass. - // Remove the analysis not preserved by this pass - removeNotPreservedAnalysis(P); - recordAvailableAnalysis(P); - - // Add pass - PassVector.push_back(P); -} - - -/// 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(SmallVectorImpl<Pass *> &RP, - SmallVectorImpl<AnalysisID> &RP_NotAvail, - Pass *P) { - AnalysisUsage *AnUsage = TPM->findAnalysisUsage(P); - const AnalysisUsage::VectorType &RequiredSet = AnUsage->getRequiredSet(); - for (AnalysisUsage::VectorType::const_iterator - I = RequiredSet.begin(), E = RequiredSet.end(); I != E; ++I) { - if (Pass *AnalysisPass = findAnalysisPass(*I, true)) - RP.push_back(AnalysisPass); - else - RP_NotAvail.push_back(*I); - } - - const AnalysisUsage::VectorType &IDs = AnUsage->getRequiredTransitiveSet(); - for (AnalysisUsage::VectorType::const_iterator I = IDs.begin(), - E = IDs.end(); I != E; ++I) { - if (Pass *AnalysisPass = findAnalysisPass(*I, true)) - RP.push_back(AnalysisPass); - else - RP_NotAvail.push_back(*I); - } -} - -// All Required analyses should be available to the pass as it runs! Here -// we fill in the AnalysisImpls member of the pass so that it can -// successfully use the getAnalysis() method to retrieve the -// implementations it needs. -// -void PMDataManager::initializeAnalysisImpl(Pass *P) { - AnalysisUsage *AnUsage = TPM->findAnalysisUsage(P); - - for (AnalysisUsage::VectorType::const_iterator - I = AnUsage->getRequiredSet().begin(), - E = AnUsage->getRequiredSet().end(); I != E; ++I) { - Pass *Impl = findAnalysisPass(*I, true); - if (Impl == 0) - // This may be analysis pass that is initialized on the fly. - // If that is not the case then it will raise an assert when it is used. - continue; - AnalysisResolver *AR = P->getResolver(); - assert(AR && "Analysis Resolver is not set"); - AR->addAnalysisImplsPair(*I, Impl); - } -} - -/// Find the pass that implements Analysis AID. If desired pass is not found -/// then return NULL. -Pass *PMDataManager::findAnalysisPass(AnalysisID AID, bool SearchParent) { - - // Check if AvailableAnalysis map has one entry. - DenseMap<AnalysisID, Pass*>::const_iterator I = AvailableAnalysis.find(AID); - - if (I != AvailableAnalysis.end()) - return I->second; - - // Search Parents through TopLevelManager - if (SearchParent) - return TPM->findAnalysisPass(AID); - - return NULL; -} - -// Print list of passes that are last used by P. -void PMDataManager::dumpLastUses(Pass *P, unsigned Offset) const{ - - SmallVector<Pass *, 12> LUses; - - // If this is a on the fly manager then it does not have TPM. - if (!TPM) - return; - - TPM->collectLastUses(LUses, P); - - for (SmallVectorImpl<Pass *>::iterator I = LUses.begin(), - E = LUses.end(); I != E; ++I) { - llvm::dbgs() << "--" << std::string(Offset*2, ' '); - (*I)->dumpPassStructure(0); - } -} - -void PMDataManager::dumpPassArguments() const { - for (SmallVectorImpl<Pass *>::const_iterator I = PassVector.begin(), - E = PassVector.end(); I != E; ++I) { - if (PMDataManager *PMD = (*I)->getAsPMDataManager()) - PMD->dumpPassArguments(); - else - if (const PassInfo *PI = - PassRegistry::getPassRegistry()->getPassInfo((*I)->getPassID())) - if (!PI->isAnalysisGroup()) - dbgs() << " -" << PI->getPassArgument(); - } -} - -void PMDataManager::dumpPassInfo(Pass *P, enum PassDebuggingString S1, - enum PassDebuggingString S2, - StringRef Msg) { - if (PassDebugging < Executions) - return; - dbgs() << (void*)this << std::string(getDepth()*2+1, ' '); - switch (S1) { - case EXECUTION_MSG: - dbgs() << "Executing Pass '" << P->getPassName(); - break; - case MODIFICATION_MSG: - dbgs() << "Made Modification '" << P->getPassName(); - break; - case FREEING_MSG: - dbgs() << " Freeing Pass '" << P->getPassName(); - break; - default: - break; - } - switch (S2) { - case ON_BASICBLOCK_MSG: - dbgs() << "' on BasicBlock '" << Msg << "'...\n"; - break; - case ON_FUNCTION_MSG: - dbgs() << "' on Function '" << Msg << "'...\n"; - break; - 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; - case ON_CG_MSG: - dbgs() << "' on Call Graph Nodes '" << Msg << "'...\n"; - break; - default: - break; - } -} - -void PMDataManager::dumpRequiredSet(const Pass *P) const { - if (PassDebugging < Details) - return; - - AnalysisUsage analysisUsage; - P->getAnalysisUsage(analysisUsage); - dumpAnalysisUsage("Required", P, analysisUsage.getRequiredSet()); -} - -void PMDataManager::dumpPreservedSet(const Pass *P) const { - if (PassDebugging < Details) - return; - - AnalysisUsage analysisUsage; - P->getAnalysisUsage(analysisUsage); - dumpAnalysisUsage("Preserved", P, analysisUsage.getPreservedSet()); -} - -void PMDataManager::dumpAnalysisUsage(StringRef Msg, const Pass *P, - const AnalysisUsage::VectorType &Set) const { - assert(PassDebugging >= Details); - if (Set.empty()) - return; - dbgs() << (const void*)P << std::string(getDepth()*2+3, ' ') << Msg << " Analyses:"; - 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'; -} - -/// Add RequiredPass into list of lower level passes required by pass P. -/// RequiredPass is run on the fly by Pass Manager when P requests it -/// through getAnalysis interface. -/// This should be handled by specific pass manager. -void PMDataManager::addLowerLevelRequiredPass(Pass *P, Pass *RequiredPass) { - if (TPM) { - TPM->dumpArguments(); - TPM->dumpPasses(); - } - - // Module Level pass may required Function Level analysis info - // (e.g. dominator info). Pass manager uses on the fly function pass manager - // to provide this on demand. In that case, in Pass manager terminology, - // module level pass is requiring lower level analysis info managed by - // lower level pass manager. - - // When Pass manager is not able to order required analysis info, Pass manager - // checks whether any lower level manager will be able to provide this - // analysis info on demand or not. -#ifndef NDEBUG - dbgs() << "Unable to schedule '" << RequiredPass->getPassName(); - dbgs() << "' required by '" << P->getPassName() << "'\n"; -#endif - llvm_unreachable("Unable to schedule pass"); -} - -Pass *PMDataManager::getOnTheFlyPass(Pass *P, AnalysisID PI, Function &F) { - llvm_unreachable("Unable to find on the fly pass"); -} - -// Destructor -PMDataManager::~PMDataManager() { - for (SmallVectorImpl<Pass *>::iterator I = PassVector.begin(), - E = PassVector.end(); I != E; ++I) - delete *I; -} - -//===----------------------------------------------------------------------===// -// NOTE: Is this the right place to define this method ? -// getAnalysisIfAvailable - Return analysis result or null if it doesn't exist. -Pass *AnalysisResolver::getAnalysisIfAvailable(AnalysisID ID, bool dir) const { - return PM.findAnalysisPass(ID, dir); -} - -Pass *AnalysisResolver::findImplPass(Pass *P, AnalysisID AnalysisPI, - Function &F) { - return PM.getOnTheFlyPass(P, AnalysisPI, F); -} - -//===----------------------------------------------------------------------===// -// BBPassManager implementation - -/// Execute all of the passes scheduled for execution by invoking -/// runOnBasicBlock method. Keep track of whether any of the passes modifies -/// the function, and if so, return true. -bool BBPassManager::runOnFunction(Function &F) { - if (F.isDeclaration()) - return false; - - bool Changed = doInitialization(F); - - for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) - for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { - BasicBlockPass *BP = getContainedPass(Index); - bool LocalChanged = false; - - dumpPassInfo(BP, EXECUTION_MSG, ON_BASICBLOCK_MSG, I->getName()); - dumpRequiredSet(BP); - - initializeAnalysisImpl(BP); - - { - // If the pass crashes, remember this. - PassManagerPrettyStackEntry X(BP, *I); - TimeRegion PassTimer(getPassTimer(BP)); - - LocalChanged |= BP->runOnBasicBlock(*I); +void AnalysisManager::invalidateAll(Module *M) { + // First invalidate any module results we still have laying about. + // FIXME: This is a total hack based on the fact that erasure doesn't + // invalidate iteration for DenseMap. + for (ModuleAnalysisResultMapT::iterator I = ModuleAnalysisResults.begin(), + E = ModuleAnalysisResults.end(); + I != E; ++I) + if (I->second->invalidate(M)) + ModuleAnalysisResults.erase(I); + + // Now walk all of the functions for which there are cached results, and + // attempt to invalidate each of those as the entire module may have changed. + // FIXME: How do we handle functions which have been deleted or RAUWed? + SmallVector<void *, 8> InvalidatedPassIDs; + for (FunctionAnalysisResultListMapT::iterator + FI = FunctionAnalysisResultLists.begin(), + FE = FunctionAnalysisResultLists.end(); + FI != FE; ++FI) { + Function *F = FI->first; + FunctionAnalysisResultListT &ResultsList = FI->second; + for (FunctionAnalysisResultListT::iterator I = ResultsList.begin(), + E = ResultsList.end(); + I != E;) + if (I->second->invalidate(F)) { + InvalidatedPassIDs.push_back(I->first); + I = ResultsList.erase(I); + } else { + ++I; } - - Changed |= LocalChanged; - if (LocalChanged) - dumpPassInfo(BP, MODIFICATION_MSG, ON_BASICBLOCK_MSG, - I->getName()); - dumpPreservedSet(BP); - - verifyPreservedAnalysis(BP); - removeNotPreservedAnalysis(BP); - recordAvailableAnalysis(BP); - removeDeadPasses(BP, I->getName(), ON_BASICBLOCK_MSG); - } - - return doFinalization(F) || Changed; -} - -// Implement doInitialization and doFinalization -bool BBPassManager::doInitialization(Module &M) { - bool Changed = false; - - for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) - Changed |= getContainedPass(Index)->doInitialization(M); - - return Changed; -} - -bool BBPassManager::doFinalization(Module &M) { - bool Changed = false; - - for (int Index = getNumContainedPasses() - 1; Index >= 0; --Index) - Changed |= getContainedPass(Index)->doFinalization(M); - - return Changed; -} - -bool BBPassManager::doInitialization(Function &F) { - bool Changed = false; - - for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { - BasicBlockPass *BP = getContainedPass(Index); - Changed |= BP->doInitialization(F); + while (!InvalidatedPassIDs.empty()) + FunctionAnalysisResults.erase( + std::make_pair(InvalidatedPassIDs.pop_back_val(), F)); } - - return Changed; } -bool BBPassManager::doFinalization(Function &F) { - bool Changed = false; +const AnalysisManager::AnalysisResultConcept<Module> & +AnalysisManager::getResultImpl(void *PassID, Module *M) { + assert(M == this->M && "Wrong module used when querying the AnalysisManager"); + ModuleAnalysisResultMapT::iterator RI; + bool Inserted; + llvm::tie(RI, Inserted) = ModuleAnalysisResults.insert(std::make_pair( + PassID, polymorphic_ptr<AnalysisResultConcept<Module> >())); - for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { - BasicBlockPass *BP = getContainedPass(Index); - Changed |= BP->doFinalization(F); + if (Inserted) { + // We don't have a cached result for this result. Look up the pass and run + // it to produce a result, which we then add to the cache. + ModuleAnalysisPassMapT::const_iterator PI = + ModuleAnalysisPasses.find(PassID); + assert(PI != ModuleAnalysisPasses.end() && + "Analysis passes must be registered prior to being queried!"); + RI->second = PI->second->run(M); } - return Changed; + return *RI->second; } +const AnalysisManager::AnalysisResultConcept<Function> & +AnalysisManager::getResultImpl(void *PassID, Function *F) { + assert(F->getParent() == M && "Analyzing a function from another module!"); -//===----------------------------------------------------------------------===// -// FunctionPassManager implementation - -/// Create new Function pass manager -FunctionPassManager::FunctionPassManager(Module *m) : M(m) { - FPM = new FunctionPassManagerImpl(); - // FPM is the top level manager. - FPM->setTopLevelManager(FPM); - - AnalysisResolver *AR = new AnalysisResolver(*FPM); - FPM->setResolver(AR); -} - -FunctionPassManager::~FunctionPassManager() { - delete FPM; -} + FunctionAnalysisResultMapT::iterator RI; + bool Inserted; + llvm::tie(RI, Inserted) = FunctionAnalysisResults.insert(std::make_pair( + std::make_pair(PassID, F), FunctionAnalysisResultListT::iterator())); -/// add - Add a pass to the queue of passes to run. This passes -/// ownership of the Pass to the PassManager. When the -/// PassManager_X is destroyed, the pass will be destroyed as well, so -/// there is no need to delete the pass. (TODO delete passes.) -/// This implies that all passes MUST be allocated with 'new'. -void FunctionPassManager::add(Pass *P) { - FPM->add(P); -} - -/// run - Execute all of the passes scheduled for execution. Keep -/// track of whether any of the passes modifies the function, and if -/// so, return true. -/// -bool FunctionPassManager::run(Function &F) { - if (F.isMaterializable()) { - std::string errstr; - if (F.Materialize(&errstr)) - report_fatal_error("Error reading bitcode file: " + Twine(errstr)); + if (Inserted) { + // We don't have a cached result for this result. Look up the pass and run + // it to produce a result, which we then add to the cache. + FunctionAnalysisPassMapT::const_iterator PI = + FunctionAnalysisPasses.find(PassID); + assert(PI != FunctionAnalysisPasses.end() && + "Analysis passes must be registered prior to being queried!"); + FunctionAnalysisResultListT &ResultList = FunctionAnalysisResultLists[F]; + ResultList.push_back(std::make_pair(PassID, PI->second->run(F))); + RI->second = llvm::prior(ResultList.end()); } - return FPM->run(F); -} - -/// doInitialization - Run all of the initializers for the function passes. -/// -bool FunctionPassManager::doInitialization() { - return FPM->doInitialization(*M); -} - -/// doFinalization - Run all of the finalizers for the function passes. -/// -bool FunctionPassManager::doFinalization() { - return FPM->doFinalization(*M); -} - -//===----------------------------------------------------------------------===// -// FunctionPassManagerImpl implementation -// -bool FunctionPassManagerImpl::doInitialization(Module &M) { - bool Changed = false; - - dumpArguments(); - dumpPasses(); - - SmallVectorImpl<ImmutablePass *>& IPV = getImmutablePasses(); - for (SmallVectorImpl<ImmutablePass *>::const_iterator I = IPV.begin(), - E = IPV.end(); I != E; ++I) { - Changed |= (*I)->doInitialization(M); - } - - for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) - Changed |= getContainedManager(Index)->doInitialization(M); - - return Changed; + return *RI->second->second; } -bool FunctionPassManagerImpl::doFinalization(Module &M) { - bool Changed = false; - - for (int Index = getNumContainedManagers() - 1; Index >= 0; --Index) - Changed |= getContainedManager(Index)->doFinalization(M); - - SmallVectorImpl<ImmutablePass *>& IPV = getImmutablePasses(); - for (SmallVectorImpl<ImmutablePass *>::const_iterator I = IPV.begin(), - E = IPV.end(); I != E; ++I) { - Changed |= (*I)->doFinalization(M); - } - - return Changed; +void AnalysisManager::invalidateImpl(void *PassID, Module *M) { + assert(M == this->M && "Invalidating a pass over a different module!"); + ModuleAnalysisResults.erase(PassID); } -/// cleanup - After running all passes, clean up pass manager cache. -void FPPassManager::cleanup() { - for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { - FunctionPass *FP = getContainedPass(Index); - AnalysisResolver *AR = FP->getResolver(); - assert(AR && "Analysis Resolver is not set"); - AR->clearAnalysisImpls(); - } -} +void AnalysisManager::invalidateImpl(void *PassID, Function *F) { + assert(F->getParent() == M && + "Invalidating a pass over a function from another module!"); -void FunctionPassManagerImpl::releaseMemoryOnTheFly() { - if (!wasRun) + FunctionAnalysisResultMapT::iterator RI = + FunctionAnalysisResults.find(std::make_pair(PassID, F)); + if (RI == FunctionAnalysisResults.end()) return; - for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) { - FPPassManager *FPPM = getContainedManager(Index); - for (unsigned Index = 0; Index < FPPM->getNumContainedPasses(); ++Index) { - FPPM->getContainedPass(Index)->releaseMemory(); - } - } - wasRun = false; -} - -// Execute all the passes managed by this top level manager. -// Return true if any function is modified by a pass. -bool FunctionPassManagerImpl::run(Function &F) { - bool Changed = false; - TimingInfo::createTheTimeInfo(); - - initializeAllAnalysisInfo(); - for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) - Changed |= getContainedManager(Index)->runOnFunction(F); - - for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) - getContainedManager(Index)->cleanup(); - - wasRun = true; - return Changed; -} -//===----------------------------------------------------------------------===// -// FPPassManager implementation - -char FPPassManager::ID = 0; -/// Print passes managed by this manager -void FPPassManager::dumpPassStructure(unsigned Offset) { - dbgs().indent(Offset*2) << "FunctionPass Manager\n"; - for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { - FunctionPass *FP = getContainedPass(Index); - FP->dumpPassStructure(Offset + 1); - dumpLastUses(FP, Offset+1); - } -} - - -/// Execute all of the passes scheduled for execution by invoking -/// runOnFunction method. Keep track of whether any of the passes modifies -/// the function, and if so, return true. -bool FPPassManager::runOnFunction(Function &F) { - if (F.isDeclaration()) - return false; - - bool Changed = false; - - // Collect inherited analysis from Module level pass manager. - populateInheritedAnalysis(TPM->activeStack); - - for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { - FunctionPass *FP = getContainedPass(Index); - bool LocalChanged = false; - - dumpPassInfo(FP, EXECUTION_MSG, ON_FUNCTION_MSG, F.getName()); - dumpRequiredSet(FP); - - initializeAnalysisImpl(FP); - - { - PassManagerPrettyStackEntry X(FP, F); - TimeRegion PassTimer(getPassTimer(FP)); - - LocalChanged |= FP->runOnFunction(F); - } - - Changed |= LocalChanged; - if (LocalChanged) - dumpPassInfo(FP, MODIFICATION_MSG, ON_FUNCTION_MSG, F.getName()); - dumpPreservedSet(FP); - - verifyPreservedAnalysis(FP); - removeNotPreservedAnalysis(FP); - recordAvailableAnalysis(FP); - removeDeadPasses(FP, F.getName(), ON_FUNCTION_MSG); - } - return Changed; -} - -bool FPPassManager::runOnModule(Module &M) { - bool Changed = false; - - for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) - Changed |= runOnFunction(*I); - - return Changed; -} - -bool FPPassManager::doInitialization(Module &M) { - bool Changed = false; - - for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) - Changed |= getContainedPass(Index)->doInitialization(M); - - return Changed; -} - -bool FPPassManager::doFinalization(Module &M) { - bool Changed = false; - - for (int Index = getNumContainedPasses() - 1; Index >= 0; --Index) - Changed |= getContainedPass(Index)->doFinalization(M); - - return Changed; + FunctionAnalysisResultLists[F].erase(RI->second); } - -//===----------------------------------------------------------------------===// -// MPPassManager implementation - -/// Execute all of the passes scheduled for execution by invoking -/// runOnModule method. Keep track of whether any of the passes modifies -/// the module, and if so, return true. -bool -MPPassManager::runOnModule(Module &M) { - bool Changed = false; - - // Initialize on-the-fly passes - for (std::map<Pass *, FunctionPassManagerImpl *>::iterator - I = OnTheFlyManagers.begin(), E = OnTheFlyManagers.end(); - I != E; ++I) { - FunctionPassManagerImpl *FPP = I->second; - Changed |= FPP->doInitialization(M); - } - - // Initialize module passes - for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) - Changed |= getContainedPass(Index)->doInitialization(M); - - for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { - ModulePass *MP = getContainedPass(Index); - bool LocalChanged = false; - - dumpPassInfo(MP, EXECUTION_MSG, ON_MODULE_MSG, M.getModuleIdentifier()); - dumpRequiredSet(MP); - - initializeAnalysisImpl(MP); - - { - PassManagerPrettyStackEntry X(MP, M); - TimeRegion PassTimer(getPassTimer(MP)); - - LocalChanged |= MP->runOnModule(M); - } - - Changed |= LocalChanged; - if (LocalChanged) - dumpPassInfo(MP, MODIFICATION_MSG, ON_MODULE_MSG, - M.getModuleIdentifier()); - dumpPreservedSet(MP); - - verifyPreservedAnalysis(MP); - removeNotPreservedAnalysis(MP); - recordAvailableAnalysis(MP); - removeDeadPasses(MP, M.getModuleIdentifier(), ON_MODULE_MSG); - } - - // Finalize module passes - for (int Index = getNumContainedPasses() - 1; Index >= 0; --Index) - Changed |= getContainedPass(Index)->doFinalization(M); - - // Finalize on-the-fly passes - for (std::map<Pass *, FunctionPassManagerImpl *>::iterator - I = OnTheFlyManagers.begin(), E = OnTheFlyManagers.end(); - I != E; ++I) { - FunctionPassManagerImpl *FPP = I->second; - // We don't know when is the last time an on-the-fly pass is run, - // so we need to releaseMemory / finalize here - FPP->releaseMemoryOnTheFly(); - Changed |= FPP->doFinalization(M); - } - - return Changed; -} - -/// Add RequiredPass into list of lower level passes required by pass P. -/// RequiredPass is run on the fly by Pass Manager when P requests it -/// through getAnalysis interface. -void MPPassManager::addLowerLevelRequiredPass(Pass *P, Pass *RequiredPass) { - assert(P->getPotentialPassManagerType() == PMT_ModulePassManager && - "Unable to handle Pass that requires lower level Analysis pass"); - assert((P->getPotentialPassManagerType() < - RequiredPass->getPotentialPassManagerType()) && - "Unable to handle Pass that requires lower level Analysis pass"); - - FunctionPassManagerImpl *FPP = OnTheFlyManagers[P]; - if (!FPP) { - FPP = new FunctionPassManagerImpl(); - // FPP is the top level manager. - FPP->setTopLevelManager(FPP); - - OnTheFlyManagers[P] = FPP; - } - FPP->add(RequiredPass); - - // Register P as the last user of RequiredPass. - if (RequiredPass) { - SmallVector<Pass *, 1> LU; - LU.push_back(RequiredPass); - FPP->setLastUser(LU, P); - } -} - -/// Return function pass corresponding to PassInfo PI, that is -/// required by module pass MP. Instantiate analysis pass, by using -/// its runOnFunction() for function F. -Pass* MPPassManager::getOnTheFlyPass(Pass *MP, AnalysisID PI, Function &F){ - FunctionPassManagerImpl *FPP = OnTheFlyManagers[MP]; - assert(FPP && "Unable to find on the fly pass"); - - FPP->releaseMemoryOnTheFly(); - FPP->run(F); - return ((PMTopLevelManager*)FPP)->findAnalysisPass(PI); -} - - -//===----------------------------------------------------------------------===// -// PassManagerImpl implementation - -// -/// run - Execute all of the passes scheduled for execution. Keep track of -/// whether any of the passes modifies the module, and if so, return true. -bool PassManagerImpl::run(Module &M) { - bool Changed = false; - TimingInfo::createTheTimeInfo(); - - dumpArguments(); - dumpPasses(); - - SmallVectorImpl<ImmutablePass *>& IPV = getImmutablePasses(); - for (SmallVectorImpl<ImmutablePass *>::const_iterator I = IPV.begin(), - E = IPV.end(); I != E; ++I) { - Changed |= (*I)->doInitialization(M); - } - - initializeAllAnalysisInfo(); - for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) - Changed |= getContainedManager(Index)->runOnModule(M); - - for (SmallVectorImpl<ImmutablePass *>::const_iterator I = IPV.begin(), - E = IPV.end(); I != E; ++I) { - Changed |= (*I)->doFinalization(M); - } - - return Changed; -} - -//===----------------------------------------------------------------------===// -// PassManager implementation - -/// Create new pass manager -PassManager::PassManager() { - PM = new PassManagerImpl(); - // PM is the top level manager - PM->setTopLevelManager(PM); -} - -PassManager::~PassManager() { - delete PM; -} - -/// add - Add a pass to the queue of passes to run. This passes ownership of -/// the Pass to the PassManager. When the PassManager is destroyed, the pass -/// will be destroyed as well, so there is no need to delete the pass. This -/// implies that all passes MUST be allocated with 'new'. -void PassManager::add(Pass *P) { - PM->add(P); -} - -/// run - Execute all of the passes scheduled for execution. Keep track of -/// whether any of the passes modifies the module, and if so, return true. -bool PassManager::run(Module &M) { - return PM->run(M); -} - -//===----------------------------------------------------------------------===// -// TimingInfo implementation - -bool llvm::TimePassesIsEnabled = false; -static cl::opt<bool,true> -EnableTiming("time-passes", cl::location(TimePassesIsEnabled), - cl::desc("Time each pass, printing elapsed time for each on exit")); - -// createTheTimeInfo - This method either initializes the TheTimeInfo pointer to -// a non null value (if the -time-passes option is enabled) or it leaves it -// null. It may be called multiple times. -void TimingInfo::createTheTimeInfo() { - if (!TimePassesIsEnabled || TheTimeInfo) return; - - // Constructed the first time this is called, iff -time-passes is enabled. - // This guarantees that the object will be constructed before static globals, - // thus it will be destroyed before them. - static ManagedStatic<TimingInfo> TTI; - TheTimeInfo = &*TTI; -} - -/// If TimingInfo is enabled then start pass timer. -Timer *llvm::getPassTimer(Pass *P) { - if (TheTimeInfo) - return TheTimeInfo->getPassTimer(P); - return 0; -} - -//===----------------------------------------------------------------------===// -// PMStack implementation -// - -// Pop Pass Manager from the stack and clear its analysis info. -void PMStack::pop() { - - PMDataManager *Top = this->top(); - Top->initializeAnalysisInfo(); - - S.pop_back(); -} - -// Push PM on the stack and set its top level manager. -void PMStack::push(PMDataManager *PM) { - assert(PM && "Unable to push. Pass Manager expected"); - assert(PM->getDepth()==0 && "Pass Manager depth set too early"); - - if (!this->empty()) { - assert(PM->getPassManagerType() > this->top()->getPassManagerType() - && "pushing bad pass manager to PMStack"); - PMTopLevelManager *TPM = this->top()->getTopLevelManager(); - - assert(TPM && "Unable to find top level manager"); - TPM->addIndirectPassManager(PM); - PM->setTopLevelManager(TPM); - PM->setDepth(this->top()->getDepth()+1); - } else { - assert((PM->getPassManagerType() == PMT_ModulePassManager - || PM->getPassManagerType() == PMT_FunctionPassManager) - && "pushing bad pass manager to PMStack"); - PM->setDepth(1); - } - - S.push_back(PM); -} - -// Dump content of the pass manager stack. -void PMStack::dump() const { - for (std::vector<PMDataManager *>::const_iterator I = S.begin(), - E = S.end(); I != E; ++I) - dbgs() << (*I)->getAsPass()->getPassName() << ' '; - - if (!S.empty()) - dbgs() << '\n'; -} - -/// Find appropriate Module Pass Manager in the PM Stack and -/// add self into that manager. -void ModulePass::assignPassManager(PMStack &PMS, - PassManagerType PreferredType) { - // Find Module Pass Manager - while (!PMS.empty()) { - PassManagerType TopPMType = PMS.top()->getPassManagerType(); - if (TopPMType == PreferredType) - break; // We found desired pass manager - else if (TopPMType > PMT_ModulePassManager) - PMS.pop(); // Pop children pass managers - else - break; - } - assert(!PMS.empty() && "Unable to find appropriate Pass Manager"); - PMS.top()->add(this); -} - -/// Find appropriate Function Pass Manager or Call Graph Pass Manager -/// in the PM Stack and add self into that manager. -void FunctionPass::assignPassManager(PMStack &PMS, - PassManagerType PreferredType) { - - // Find Function Pass Manager - while (!PMS.empty()) { - if (PMS.top()->getPassManagerType() > PMT_FunctionPassManager) - PMS.pop(); - else - break; - } - - // Create new Function Pass Manager if needed. - FPPassManager *FPP; - if (PMS.top()->getPassManagerType() == PMT_FunctionPassManager) { - FPP = (FPPassManager *)PMS.top(); - } else { - assert(!PMS.empty() && "Unable to create Function Pass Manager"); - PMDataManager *PMD = PMS.top(); - - // [1] Create new Function Pass Manager - FPP = new FPPassManager(); - FPP->populateInheritedAnalysis(PMS); - - // [2] Set up new manager's top level manager - PMTopLevelManager *TPM = PMD->getTopLevelManager(); - TPM->addIndirectPassManager(FPP); - - // [3] Assign manager to manage this new manager. This may create - // and push new managers into PMS - FPP->assignPassManager(PMS, PMD->getPassManagerType()); - - // [4] Push new manager into PMS - PMS.push(FPP); - } - - // Assign FPP as the manager of this pass. - FPP->add(this); -} - -/// Find appropriate Basic Pass Manager or Call Graph Pass Manager -/// in the PM Stack and add self into that manager. -void BasicBlockPass::assignPassManager(PMStack &PMS, - PassManagerType PreferredType) { - BBPassManager *BBP; - - // Basic Pass Manager is a leaf pass manager. It does not handle - // any other pass manager. - if (!PMS.empty() && - PMS.top()->getPassManagerType() == PMT_BasicBlockPassManager) { - BBP = (BBPassManager *)PMS.top(); - } else { - // If leaf manager is not Basic Block Pass manager then create new - // basic Block Pass manager. - assert(!PMS.empty() && "Unable to create BasicBlock Pass Manager"); - PMDataManager *PMD = PMS.top(); - - // [1] Create new Basic Block Manager - BBP = new BBPassManager(); - - // [2] Set up new manager's top level manager - // Basic Block Pass Manager does not live by itself - PMTopLevelManager *TPM = PMD->getTopLevelManager(); - TPM->addIndirectPassManager(BBP); - - // [3] Assign manager to manage this new manager. This may create - // and push new managers into PMS - BBP->assignPassManager(PMS, PreferredType); - - // [4] Push new manager into PMS - PMS.push(BBP); - } - - // Assign BBP as the manager of this pass. - BBP->add(this); -} - -PassManagerBase::~PassManagerBase() {} diff --git a/lib/IR/Type.cpp b/lib/IR/Type.cpp index 46c61fc..432cbc9 100644 --- a/lib/IR/Type.cpp +++ b/lib/IR/Type.cpp @@ -616,11 +616,7 @@ bool StructType::isLayoutIdentical(StructType *Other) const { /// getTypeByName - Return the type with the specified name, or null if there /// is none by that name. StructType *Module::getTypeByName(StringRef Name) const { - StringMap<StructType*>::iterator I = - getContext().pImpl->NamedStructTypes.find(Name); - if (I != getContext().pImpl->NamedStructTypes.end()) - return I->second; - return 0; + return getContext().pImpl->NamedStructTypes.lookup(Name); } diff --git a/lib/IR/TypeFinder.cpp b/lib/IR/TypeFinder.cpp index d5e6203..689b903 100644 --- a/lib/IR/TypeFinder.cpp +++ b/lib/IR/TypeFinder.cpp @@ -44,6 +44,9 @@ void TypeFinder::run(const Module &M, bool onlyNamed) { for (Module::const_iterator FI = M.begin(), E = M.end(); FI != E; ++FI) { incorporateType(FI->getType()); + if (FI->hasPrefixData()) + incorporateValue(FI->getPrefixData()); + // First incorporate the arguments. for (Function::const_arg_iterator AI = FI->arg_begin(), AE = FI->arg_end(); AI != AE; ++AI) @@ -91,19 +94,27 @@ void TypeFinder::clear() { /// incorporateType - This method adds the type to the list of used structures /// if it's not in there already. void TypeFinder::incorporateType(Type *Ty) { - // Check to see if we're already visited this type. + // Check to see if we've already visited this type. if (!VisitedTypes.insert(Ty).second) return; - // If this is a structure or opaque type, add a name for the type. - if (StructType *STy = dyn_cast<StructType>(Ty)) - if (!OnlyNamed || STy->hasName()) - StructTypes.push_back(STy); - - // Recursively walk all contained types. - for (Type::subtype_iterator I = Ty->subtype_begin(), - E = Ty->subtype_end(); I != E; ++I) - incorporateType(*I); + SmallVector<Type *, 4> TypeWorklist; + TypeWorklist.push_back(Ty); + do { + Ty = TypeWorklist.pop_back_val(); + + // If this is a structure or opaque type, add a name for the type. + if (StructType *STy = dyn_cast<StructType>(Ty)) + if (!OnlyNamed || STy->hasName()) + StructTypes.push_back(STy); + + // Add all unvisited subtypes to worklist for processing + for (Type::subtype_reverse_iterator I = Ty->subtype_rbegin(), + E = Ty->subtype_rend(); + I != E; ++I) + if (VisitedTypes.insert(*I).second) + TypeWorklist.push_back(*I); + } while (!TypeWorklist.empty()); } /// incorporateValue - This method is used to walk operand lists finding types diff --git a/lib/IR/Value.cpp b/lib/IR/Value.cpp index 81d7efa..62a3b31 100644 --- a/lib/IR/Value.cpp +++ b/lib/IR/Value.cpp @@ -365,7 +365,8 @@ static Value *stripPointerCastsAndOffsets(Value *V) { break; } V = GEP->getPointerOperand(); - } else if (Operator::getOpcode(V) == Instruction::BitCast) { + } else if (Operator::getOpcode(V) == Instruction::BitCast || + Operator::getOpcode(V) == Instruction::AddrSpaceCast) { V = cast<Operator>(V)->getOperand(0); } else if (GlobalAlias *GA = dyn_cast<GlobalAlias>(V)) { if (StripKind == PSK_ZeroIndices || GA->mayBeOverridden()) @@ -393,6 +394,42 @@ Value *Value::stripInBoundsConstantOffsets() { return stripPointerCastsAndOffsets<PSK_InBoundsConstantIndices>(this); } +Value *Value::stripAndAccumulateInBoundsConstantOffsets(const DataLayout &DL, + APInt &Offset) { + if (!getType()->isPointerTy()) + return this; + + assert(Offset.getBitWidth() == DL.getPointerSizeInBits(cast<PointerType>( + getType())->getAddressSpace()) && + "The offset must have exactly as many bits as our pointer."); + + // Even though we don't look through PHI nodes, we could be called on an + // instruction in an unreachable block, which may be on a cycle. + SmallPtrSet<Value *, 4> Visited; + Visited.insert(this); + Value *V = this; + do { + if (GEPOperator *GEP = dyn_cast<GEPOperator>(V)) { + if (!GEP->isInBounds()) + return V; + APInt GEPOffset(Offset); + if (!GEP->accumulateConstantOffset(DL, GEPOffset)) + return V; + Offset = GEPOffset; + V = GEP->getPointerOperand(); + } else if (Operator::getOpcode(V) == Instruction::BitCast) { + V = cast<Operator>(V)->getOperand(0); + } else if (GlobalAlias *GA = dyn_cast<GlobalAlias>(V)) { + V = GA->getAliasee(); + } else { + return V; + } + assert(V->getType()->isPointerTy() && "Unexpected operand type!"); + } while (Visited.insert(V)); + + return V; +} + Value *Value::stripInBoundsOffsets() { return stripPointerCastsAndOffsets<PSK_InBounds>(this); } @@ -698,9 +735,5 @@ void ValueHandleBase::ValueIsRAUWd(Value *Old, Value *New) { #endif } -// Default implementation for CallbackVH. -void CallbackVH::allUsesReplacedWith(Value *) {} - -void CallbackVH::deleted() { - setValPtr(NULL); -} +// Pin the vtable to this file. +void CallbackVH::anchor() {} diff --git a/lib/IR/ValueTypes.cpp b/lib/IR/ValueTypes.cpp index ba04d60..2d4da95 100644 --- a/lib/IR/ValueTypes.cpp +++ b/lib/IR/ValueTypes.cpp @@ -134,6 +134,7 @@ std::string EVT::getEVTString() const { case MVT::v16i1: return "v16i1"; case MVT::v32i1: return "v32i1"; case MVT::v64i1: return "v64i1"; + case MVT::v1i8: return "v1i8"; case MVT::v2i8: return "v2i8"; case MVT::v4i8: return "v4i8"; case MVT::v8i8: return "v8i8"; @@ -156,11 +157,15 @@ std::string EVT::getEVTString() const { case MVT::v4i64: return "v4i64"; case MVT::v8i64: return "v8i64"; case MVT::v16i64: return "v16i64"; + case MVT::v1f32: return "v1f32"; case MVT::v2f32: return "v2f32"; case MVT::v2f16: return "v2f16"; + case MVT::v4f16: return "v4f16"; + case MVT::v8f16: return "v8f16"; case MVT::v4f32: return "v4f32"; case MVT::v8f32: return "v8f32"; case MVT::v16f32: return "v16f32"; + case MVT::v1f64: return "v1f64"; case MVT::v2f64: return "v2f64"; case MVT::v4f64: return "v4f64"; case MVT::v8f64: return "v8f64"; @@ -197,6 +202,7 @@ Type *EVT::getTypeForEVT(LLVMContext &Context) const { case MVT::v16i1: return VectorType::get(Type::getInt1Ty(Context), 16); case MVT::v32i1: return VectorType::get(Type::getInt1Ty(Context), 32); case MVT::v64i1: return VectorType::get(Type::getInt1Ty(Context), 64); + case MVT::v1i8: return VectorType::get(Type::getInt8Ty(Context), 1); 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); @@ -220,10 +226,14 @@ Type *EVT::getTypeForEVT(LLVMContext &Context) const { case MVT::v8i64: return VectorType::get(Type::getInt64Ty(Context), 8); case MVT::v16i64: return VectorType::get(Type::getInt64Ty(Context), 16); case MVT::v2f16: return VectorType::get(Type::getHalfTy(Context), 2); + case MVT::v4f16: return VectorType::get(Type::getHalfTy(Context), 4); + case MVT::v8f16: return VectorType::get(Type::getHalfTy(Context), 8); + case MVT::v1f32: return VectorType::get(Type::getFloatTy(Context), 1); case MVT::v2f32: return VectorType::get(Type::getFloatTy(Context), 2); case MVT::v4f32: return VectorType::get(Type::getFloatTy(Context), 4); case MVT::v8f32: return VectorType::get(Type::getFloatTy(Context), 8); case MVT::v16f32: return VectorType::get(Type::getFloatTy(Context), 16); + case MVT::v1f64: return VectorType::get(Type::getDoubleTy(Context), 1); case MVT::v2f64: return VectorType::get(Type::getDoubleTy(Context), 2); case MVT::v4f64: return VectorType::get(Type::getDoubleTy(Context), 4); case MVT::v8f64: return VectorType::get(Type::getDoubleTy(Context), 8); diff --git a/lib/IR/Verifier.cpp b/lib/IR/Verifier.cpp index 0eda97f..da6b573 100644 --- a/lib/IR/Verifier.cpp +++ b/lib/IR/Verifier.cpp @@ -78,7 +78,7 @@ using namespace llvm; static cl::opt<bool> DisableDebugInfoVerifier("disable-debug-info-verifier", - cl::init(false)); + cl::init(true)); namespace { // Anonymous namespace for class struct PreVerifier : public FunctionPass { @@ -167,7 +167,6 @@ namespace { bool doInitialization(Module &M) { Mod = &M; Context = &M.getContext(); - Finder.reset(); DL = getAnalysisIfAvailable<DataLayout>(); @@ -183,10 +182,15 @@ namespace { Mod = F.getParent(); if (!Context) Context = &F.getContext(); + Finder.reset(); visit(F); InstsInThisBlock.clear(); PersonalityFn = 0; + if (!DisableDebugInfoVerifier) + // Verify Debug Info. + verifyDebugInfo(); + // We must abort before returning back to the pass manager, or else the // pass manager may try to run other passes on the broken module. return abortIfBroken(); @@ -214,9 +218,14 @@ namespace { visitNamedMDNode(*I); visitModuleFlags(M); + visitModuleIdents(M); - // Verify Debug Info. - verifyDebugInfo(M); + if (!DisableDebugInfoVerifier) { + Finder.reset(); + Finder.processModule(M); + // Verify Debug Info. + verifyDebugInfo(); + } // If the module is broken, abort at this time. return abortIfBroken(); @@ -258,6 +267,7 @@ namespace { void visitGlobalAlias(GlobalAlias &GA); void visitNamedMDNode(NamedMDNode &NMD); void visitMDNode(MDNode &MD, Function *F); + void visitModuleIdents(Module &M); void visitModuleFlags(Module &M); void visitModuleFlag(MDNode *Op, DenseMap<MDString*, MDNode*> &SeenIDs, SmallVectorImpl<MDNode*> &Requirements); @@ -279,6 +289,7 @@ namespace { void visitIntToPtrInst(IntToPtrInst &I); void visitPtrToIntInst(PtrToIntInst &I); void visitBitCastInst(BitCastInst &I); + void visitAddrSpaceCastInst(AddrSpaceCastInst &I); void visitPHINode(PHINode &PN); void visitBinaryOperator(BinaryOperator &B); void visitICmpInst(ICmpInst &IC); @@ -317,6 +328,8 @@ namespace { bool VerifyIntrinsicType(Type *Ty, ArrayRef<Intrinsic::IITDescriptor> &Infos, SmallVectorImpl<Type*> &ArgTys); + bool VerifyIntrinsicIsVarArg(bool isVarArg, + ArrayRef<Intrinsic::IITDescriptor> &Infos); bool VerifyAttributeCount(AttributeSet Attrs, unsigned Params); void VerifyAttributeTypes(AttributeSet Attrs, unsigned Idx, bool isFunction, const Value *V); @@ -328,7 +341,7 @@ namespace { void VerifyBitcastType(const Value *V, Type *DestTy, Type *SrcTy); void VerifyConstantExprBitcastType(const ConstantExpr *CE); - void verifyDebugInfo(Module &M); + void verifyDebugInfo(); void WriteValue(const Value *V) { if (!V) return; @@ -427,10 +440,6 @@ void Verifier::visitGlobalValue(GlobalValue &GV) { Assert1(GVar && GVar->getType()->getElementType()->isArrayTy(), "Only global arrays can have appending linkage!", GVar); } - - Assert1(!GV.hasLinkOnceODRAutoHideLinkage() || GV.hasDefaultVisibility(), - "linkonce_odr_auto_hide can only have default visibility!", - &GV); } void Verifier::visitGlobalVariable(GlobalVariable &GV) { @@ -527,8 +536,7 @@ void Verifier::visitGlobalVariable(GlobalVariable &GV) { void Verifier::visitGlobalAlias(GlobalAlias &GA) { Assert1(!GA.getName().empty(), "Alias name cannot be empty!", &GA); - Assert1(GA.hasExternalLinkage() || GA.hasLocalLinkage() || - GA.hasWeakLinkage(), + Assert1(GlobalAlias::isValidLinkage(GA.getLinkage()), "Alias should have external or external weak linkage!", &GA); Assert1(GA.getAliasee(), "Aliasee cannot be NULL!", &GA); @@ -612,6 +620,24 @@ void Verifier::visitMDNode(MDNode &MD, Function *F) { } } +void Verifier::visitModuleIdents(Module &M) { + const NamedMDNode *Idents = M.getNamedMetadata("llvm.ident"); + if (!Idents) + return; + + // llvm.ident takes a list of metadata entry. Each entry has only one string. + // Scan each llvm.ident entry and make sure that this requirement is met. + for (unsigned i = 0, e = Idents->getNumOperands(); i != e; ++i) { + const MDNode *N = Idents->getOperand(i); + Assert1(N->getNumOperands() == 1, + "incorrect number of operands in llvm.ident metadata", N); + Assert1(isa<MDString>(N->getOperand(0)), + ("invalid value for llvm.ident metadata entry operand" + "(the operand should be a string)"), + N->getOperand(0)); + } +} + void Verifier::visitModuleFlags(Module &M) { const NamedMDNode *Flags = M.getModuleFlagsMetadata(); if (!Flags) return; @@ -751,7 +777,8 @@ void Verifier::VerifyAttributeTypes(AttributeSet Attrs, unsigned Idx, I->getKindAsEnum() == Attribute::NoDuplicate || I->getKindAsEnum() == Attribute::Builtin || I->getKindAsEnum() == Attribute::NoBuiltin || - I->getKindAsEnum() == Attribute::Cold) { + I->getKindAsEnum() == Attribute::Cold || + I->getKindAsEnum() == Attribute::OptimizeNone) { if (!isFunction) { CheckFailed("Attribute '" + I->getAsString() + "' only applies to functions!", V); @@ -897,6 +924,21 @@ void Verifier::VerifyFunctionAttrs(FunctionType *FT, AttributeSet Attrs, Attrs.hasAttribute(AttributeSet::FunctionIndex, Attribute::AlwaysInline)), "Attributes 'noinline and alwaysinline' are incompatible!", V); + + if (Attrs.hasAttribute(AttributeSet::FunctionIndex, + Attribute::OptimizeNone)) { + Assert1(Attrs.hasAttribute(AttributeSet::FunctionIndex, + Attribute::NoInline), + "Attribute 'optnone' requires 'noinline'!", V); + + Assert1(!Attrs.hasAttribute(AttributeSet::FunctionIndex, + Attribute::OptimizeForSize), + "Attributes 'optsize and optnone' are incompatible!", V); + + Assert1(!Attrs.hasAttribute(AttributeSet::FunctionIndex, + Attribute::MinSize), + "Attributes 'minsize and optnone' are incompatible!", V); + } } void Verifier::VerifyBitcastType(const Value *V, Type *DestTy, Type *SrcTy) { @@ -930,11 +972,9 @@ void Verifier::VerifyBitcastType(const Value *V, Type *DestTy, Type *SrcTy) { unsigned SrcAS = SrcTy->getPointerAddressSpace(); unsigned DstAS = DestTy->getPointerAddressSpace(); - unsigned SrcASSize = DL->getPointerSizeInBits(SrcAS); - unsigned DstASSize = DL->getPointerSizeInBits(DstAS); - Assert1(SrcASSize == DstASSize, - "Bitcasts between pointers of different address spaces must have " - "the same size pointers, otherwise use PtrToInt/IntToPtr.", V); + Assert1(SrcAS == DstAS, + "Bitcasts between pointers of different address spaces is not legal." + "Use AddrSpaceCast instead.", V); } void Verifier::VerifyConstantExprBitcastType(const ConstantExpr *CE) { @@ -1152,27 +1192,12 @@ void Verifier::visitSwitchInst(SwitchInst &SI) { // Check to make sure that all of the constants in the switch instruction // have the same type as the switched-on value. Type *SwitchTy = SI.getCondition()->getType(); - IntegerType *IntTy = cast<IntegerType>(SwitchTy); - IntegersSubsetToBB Mapping; - std::map<IntegersSubset::Range, unsigned> RangeSetMap; + SmallPtrSet<ConstantInt*, 32> Constants; for (SwitchInst::CaseIt i = SI.case_begin(), e = SI.case_end(); i != e; ++i) { - IntegersSubset CaseRanges = i.getCaseValueEx(); - for (unsigned ri = 0, rie = CaseRanges.getNumItems(); ri < rie; ++ri) { - IntegersSubset::Range r = CaseRanges.getItem(ri); - Assert1(((const APInt&)r.getLow()).getBitWidth() == IntTy->getBitWidth(), - "Switch constants must all be same type as switch value!", &SI); - Assert1(((const APInt&)r.getHigh()).getBitWidth() == IntTy->getBitWidth(), - "Switch constants must all be same type as switch value!", &SI); - Mapping.add(r); - RangeSetMap[r] = i.getCaseIndex(); - } - } - - IntegersSubsetToBB::RangeIterator errItem; - if (!Mapping.verify(errItem)) { - unsigned CaseIndex = RangeSetMap[errItem->first]; - SwitchInst::CaseIt i(&SI, CaseIndex); - Assert2(false, "Duplicate integer as switch case", &SI, i.getCaseValueEx()); + Assert1(i.getCaseValue()->getType() == SwitchTy, + "Switch constants must all be same type as switch value!", &SI); + Assert2(Constants.insert(i.getCaseValue()), + "Duplicate integer as switch case", &SI, i.getCaseValue()); } visitTerminatorInst(SI); @@ -1435,6 +1460,22 @@ void Verifier::visitBitCastInst(BitCastInst &I) { visitInstruction(I); } +void Verifier::visitAddrSpaceCastInst(AddrSpaceCastInst &I) { + Type *SrcTy = I.getOperand(0)->getType(); + Type *DestTy = I.getType(); + + Assert1(SrcTy->isPtrOrPtrVectorTy(), + "AddrSpaceCast source must be a pointer", &I); + Assert1(DestTy->isPtrOrPtrVectorTy(), + "AddrSpaceCast result must be a pointer", &I); + Assert1(SrcTy->getPointerAddressSpace() != DestTy->getPointerAddressSpace(), + "AddrSpaceCast must be between different address spaces", &I); + if (SrcTy->isVectorTy()) + Assert1(SrcTy->getVectorNumElements() == DestTy->getVectorNumElements(), + "AddrSpaceCast vector pointer number of elements mismatch", &I); + visitInstruction(I); +} + /// visitPHINode - Ensure that a PHI node is well formed. /// void Verifier::visitPHINode(PHINode &PN) { @@ -1537,14 +1578,6 @@ void Verifier::VerifyCallSite(CallSite CS) { "Function has metadata parameter but isn't an intrinsic", I); } - // If the call site has the 'builtin' attribute, verify that it's applied to a - // direct call to a function with the 'nobuiltin' attribute. - if (CS.hasFnAttr(Attribute::Builtin)) - Assert1(CS.getCalledFunction() && - CS.getCalledFunction()->hasFnAttribute(Attribute::NoBuiltin), - "Attribute 'builtin' can only be used in a call to a function with " - "the 'nobuiltin' attribute.", I); - visitInstruction(*I); } @@ -2098,7 +2131,7 @@ void Verifier::visitInstruction(Instruction &I) { if (!DisableDebugInfoVerifier) { MD = I.getMetadata(LLVMContext::MD_dbg); - Finder.processLocation(DILocation(MD)); + Finder.processLocation(*Mod, DILocation(MD)); } InstsInThisBlock.insert(&I); @@ -2121,6 +2154,7 @@ bool Verifier::VerifyIntrinsicType(Type *Ty, switch (D.Kind) { case IITDescriptor::Void: return !Ty->isVoidTy(); + case IITDescriptor::VarArg: return true; case IITDescriptor::MMX: return !Ty->isX86_MMXTy(); case IITDescriptor::Metadata: return !Ty->isMetadataTy(); case IITDescriptor::Half: return !Ty->isHalfTy(); @@ -2185,6 +2219,33 @@ bool Verifier::VerifyIntrinsicType(Type *Ty, llvm_unreachable("unhandled"); } +/// \brief Verify if the intrinsic has variable arguments. +/// This method is intended to be called after all the fixed arguments have been +/// verified first. +/// +/// This method returns true on error and does not print an error message. +bool +Verifier::VerifyIntrinsicIsVarArg(bool isVarArg, + ArrayRef<Intrinsic::IITDescriptor> &Infos) { + using namespace Intrinsic; + + // If there are no descriptors left, then it can't be a vararg. + if (Infos.empty()) + return isVarArg ? true : false; + + // There should be only one descriptor remaining at this point. + if (Infos.size() != 1) + return true; + + // Check and verify the descriptor. + IITDescriptor D = Infos.front(); + Infos = Infos.slice(1); + if (D.Kind == IITDescriptor::VarArg) + return isVarArg ? false : true; + + return true; +} + /// visitIntrinsicFunction - Allow intrinsics to be verified in different ways. /// void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) { @@ -2195,7 +2256,7 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) { // Verify that the intrinsic prototype lines up with what the .td files // describe. FunctionType *IFTy = IF->getFunctionType(); - Assert1(!IFTy->isVarArg(), "Intrinsic prototypes are not varargs", IF); + bool IsVarArg = IFTy->isVarArg(); SmallVector<Intrinsic::IITDescriptor, 8> Table; getIntrinsicInfoTableEntries(ID, Table); @@ -2207,6 +2268,16 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) { for (unsigned i = 0, e = IFTy->getNumParams(); i != e; ++i) Assert1(!VerifyIntrinsicType(IFTy->getParamType(i), TableRef, ArgTys), "Intrinsic has incorrect argument type!", IF); + + // Verify if the intrinsic call matches the vararg property. + if (IsVarArg) + Assert1(!VerifyIntrinsicIsVarArg(IsVarArg, TableRef), + "Intrinsic was not defined with variable arguments!", IF); + else + Assert1(!VerifyIntrinsicIsVarArg(IsVarArg, TableRef), + "Callsite was not defined with variable arguments!", IF); + + // All descriptors should be absorbed by now. Assert1(TableRef.empty(), "Intrinsic has too few arguments!", IF); // Now that we have the intrinsic ID and the actual argument types (and we @@ -2238,13 +2309,13 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) { Assert1(MD->getNumOperands() == 1, "invalid llvm.dbg.declare intrinsic call 2", &CI); if (!DisableDebugInfoVerifier) - Finder.processDeclare(cast<DbgDeclareInst>(&CI)); + Finder.processDeclare(*Mod, cast<DbgDeclareInst>(&CI)); } break; case Intrinsic::dbg_value: { //llvm.dbg.value if (!DisableDebugInfoVerifier) { Assert1(CI.getArgOperand(0) && isa<MDNode>(CI.getArgOperand(0)), "invalid llvm.dbg.value intrinsic call 1", &CI); - Finder.processValue(cast<DbgValueInst>(&CI)); + Finder.processValue(*Mod, cast<DbgValueInst>(&CI)); } break; } @@ -2309,11 +2380,9 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) { } } -void Verifier::verifyDebugInfo(Module &M) { +void Verifier::verifyDebugInfo() { // Verify Debug Info. if (!DisableDebugInfoVerifier) { - Finder.processModule(M); - for (DebugInfoFinder::iterator I = Finder.compile_unit_begin(), E = Finder.compile_unit_end(); I != E; ++I) Assert1(DICompileUnit(*I).Verify(), "DICompileUnit does not Verify!", *I); @@ -2352,6 +2421,7 @@ bool llvm::verifyFunction(const Function &f, VerifierFailureAction action) { FunctionPassManager FPM(F.getParent()); Verifier *V = new Verifier(action); FPM.add(V); + FPM.doInitialization(); FPM.run(F); return V->Broken; } |