aboutsummaryrefslogtreecommitdiffstats
path: root/lib/VMCore
diff options
context:
space:
mode:
authorShih-wei Liao <sliao@google.com>2010-04-28 01:47:00 -0700
committerShih-wei Liao <sliao@google.com>2010-04-28 01:47:00 -0700
commit7abe37e4aee38cc79d91dd069a37d7e91d5bef53 (patch)
treec13b26fc3d8909240f981988535c0b82dd9bf37c /lib/VMCore
parent6037a7c3c97b651dd70e48ebe5453134713971ed (diff)
downloadexternal_llvm-7abe37e4aee38cc79d91dd069a37d7e91d5bef53.zip
external_llvm-7abe37e4aee38cc79d91dd069a37d7e91d5bef53.tar.gz
external_llvm-7abe37e4aee38cc79d91dd069a37d7e91d5bef53.tar.bz2
Sync upstream to r102410.
Re-turn on sdk. Change-Id: I91a890863989a67243b4d2dfd1ae09b843ebaeaf
Diffstat (limited to 'lib/VMCore')
-rw-r--r--lib/VMCore/Android.mk2
-rw-r--r--lib/VMCore/AsmWriter.cpp34
-rw-r--r--lib/VMCore/AutoUpgrade.cpp205
-rw-r--r--lib/VMCore/BasicBlock.cpp11
-rw-r--r--lib/VMCore/CMakeLists.txt2
-rw-r--r--lib/VMCore/Constants.cpp48
-rw-r--r--lib/VMCore/ConstantsContext.h55
-rw-r--r--lib/VMCore/Core.cpp13
-rw-r--r--lib/VMCore/DebugLoc.cpp288
-rw-r--r--lib/VMCore/Dominators.cpp8
-rw-r--r--lib/VMCore/Function.cpp18
-rw-r--r--lib/VMCore/Globals.cpp4
-rw-r--r--lib/VMCore/IRBuilder.cpp13
-rw-r--r--lib/VMCore/InlineAsm.cpp25
-rw-r--r--lib/VMCore/Instruction.cpp2
-rw-r--r--lib/VMCore/Instructions.cpp88
-rw-r--r--lib/VMCore/IntrinsicInst.cpp3
-rw-r--r--lib/VMCore/LLVMContext.cpp110
-rw-r--r--lib/VMCore/LLVMContextImpl.cpp107
-rw-r--r--lib/VMCore/LLVMContextImpl.h122
-rw-r--r--lib/VMCore/LeaksContext.h5
-rw-r--r--lib/VMCore/Makefile2
-rw-r--r--lib/VMCore/Metadata.cpp168
-rw-r--r--lib/VMCore/Module.cpp2
-rw-r--r--lib/VMCore/Pass.cpp42
-rw-r--r--lib/VMCore/PassManager.cpp142
-rw-r--r--lib/VMCore/PrintModulePass.cpp12
-rw-r--r--lib/VMCore/Type.cpp23
-rw-r--r--lib/VMCore/TypeSymbolTable.cpp6
-rw-r--r--lib/VMCore/Value.cpp6
-rw-r--r--lib/VMCore/ValueSymbolTable.cpp10
-rw-r--r--lib/VMCore/Verifier.cpp97
32 files changed, 1249 insertions, 424 deletions
diff --git a/lib/VMCore/Android.mk b/lib/VMCore/Android.mk
index 4784684..8d35cc5 100644
--- a/lib/VMCore/Android.mk
+++ b/lib/VMCore/Android.mk
@@ -8,6 +8,7 @@ vmcore_SRC_FILES := \
ConstantFold.cpp \
Constants.cpp \
Core.cpp \
+ DebugLoc.cpp \
Dominators.cpp \
Function.cpp \
GVMaterializer.cpp \
@@ -18,6 +19,7 @@ vmcore_SRC_FILES := \
Instructions.cpp \
IntrinsicInst.cpp \
LLVMContext.cpp \
+ LLVMContextImpl.cpp \
LeakDetector.cpp \
Metadata.cpp \
Module.cpp \
diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp
index fd74241..6c1aa5e 100644
--- a/lib/VMCore/AsmWriter.cpp
+++ b/lib/VMCore/AsmWriter.cpp
@@ -227,13 +227,15 @@ void TypePrinting::CalcTypeName(const Type *Ty,
const StructType *STy = cast<StructType>(Ty);
if (STy->isPacked())
OS << '<';
- OS << "{ ";
+ OS << '{';
for (StructType::element_iterator I = STy->element_begin(),
E = STy->element_end(); I != E; ++I) {
+ OS << ' ';
CalcTypeName(*I, TypeStack, OS);
- if (next(I) != STy->element_end())
+ if (next(I) == STy->element_end())
+ OS << ' ';
+ else
OS << ',';
- OS << ' ';
}
OS << '}';
if (STy->isPacked())
@@ -242,13 +244,15 @@ void TypePrinting::CalcTypeName(const Type *Ty,
}
case Type::UnionTyID: {
const UnionType *UTy = cast<UnionType>(Ty);
- OS << "union { ";
+ OS << "union {";
for (StructType::element_iterator I = UTy->element_begin(),
E = UTy->element_end(); I != E; ++I) {
+ OS << ' ';
CalcTypeName(*I, TypeStack, OS);
- if (next(I) != UTy->element_end())
+ if (next(I) == UTy->element_end())
+ OS << ' ';
+ else
OS << ',';
- OS << ' ';
}
OS << '}';
break;
@@ -1027,6 +1031,15 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV,
return;
}
+ if (const ConstantUnion *CU = dyn_cast<ConstantUnion>(CV)) {
+ Out << "{ ";
+ TypePrinter.print(CU->getOperand(0)->getType(), Out);
+ Out << ' ';
+ WriteAsOperandInternal(Out, CU->getOperand(0), &TypePrinter, Machine);
+ Out << " }";
+ return;
+ }
+
if (const ConstantVector *CP = dyn_cast<ConstantVector>(CV)) {
const Type *ETy = CP->getType()->getElementType();
assert(CP->getNumOperands() > 0 &&
@@ -1672,7 +1685,7 @@ void AssemblyWriter::printBasicBlock(const BasicBlock *BB) {
// Output predecessors for the block...
Out.PadToColumn(50);
Out << ";";
- pred_const_iterator PI = pred_begin(BB), PE = pred_end(BB);
+ const_pred_iterator PI = pred_begin(BB), PE = pred_end(BB);
if (PI == PE) {
Out << " No predecessors!";
@@ -1866,6 +1879,7 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
if (PAL.getFnAttributes() != Attribute::None)
Out << ' ' << Attribute::getAsString(PAL.getFnAttributes());
} else if (const InvokeInst *II = dyn_cast<InvokeInst>(&I)) {
+ Operand = II->getCalledValue();
const PointerType *PTy = cast<PointerType>(Operand->getType());
const FunctionType *FTy = cast<FunctionType>(PTy->getElementType());
const Type *RetTy = FTy->getReturnType();
@@ -1903,10 +1917,10 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
writeOperand(Operand, true);
}
Out << '(';
- for (unsigned op = 3, Eop = I.getNumOperands(); op < Eop; ++op) {
- if (op > 3)
+ for (unsigned op = 0, Eop = I.getNumOperands() - 3; op < Eop; ++op) {
+ if (op)
Out << ", ";
- writeParamOperand(I.getOperand(op), PAL.getParamAttributes(op-2));
+ writeParamOperand(I.getOperand(op), PAL.getParamAttributes(op + 1));
}
Out << ')';
diff --git a/lib/VMCore/AutoUpgrade.cpp b/lib/VMCore/AutoUpgrade.cpp
index 5e4c9fb..0144210 100644
--- a/lib/VMCore/AutoUpgrade.cpp
+++ b/lib/VMCore/AutoUpgrade.cpp
@@ -19,6 +19,7 @@
#include "llvm/IntrinsicInst.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/IRBuilder.h"
#include <cstring>
using namespace llvm;
@@ -145,6 +146,54 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
}
break;
+ case 'm': {
+ // This upgrades the llvm.memcpy, llvm.memmove, and llvm.memset to the
+ // new format that allows overloading the pointer for different address
+ // space (e.g., llvm.memcpy.i16 => llvm.memcpy.p0i8.p0i8.i16)
+ const char* NewFnName = NULL;
+ if (Name.compare(5,8,"memcpy.i",8) == 0) {
+ if (Name[13] == '8')
+ NewFnName = "llvm.memcpy.p0i8.p0i8.i8";
+ else if (Name.compare(13,2,"16") == 0)
+ NewFnName = "llvm.memcpy.p0i8.p0i8.i16";
+ else if (Name.compare(13,2,"32") == 0)
+ NewFnName = "llvm.memcpy.p0i8.p0i8.i32";
+ else if (Name.compare(13,2,"64") == 0)
+ NewFnName = "llvm.memcpy.p0i8.p0i8.i64";
+ } else if (Name.compare(5,9,"memmove.i",9) == 0) {
+ if (Name[14] == '8')
+ NewFnName = "llvm.memmove.p0i8.p0i8.i8";
+ else if (Name.compare(14,2,"16") == 0)
+ NewFnName = "llvm.memmove.p0i8.p0i8.i16";
+ else if (Name.compare(14,2,"32") == 0)
+ NewFnName = "llvm.memmove.p0i8.p0i8.i32";
+ else if (Name.compare(14,2,"64") == 0)
+ NewFnName = "llvm.memmove.p0i8.p0i8.i64";
+ }
+ else if (Name.compare(5,8,"memset.i",8) == 0) {
+ if (Name[13] == '8')
+ NewFnName = "llvm.memset.p0i8.i8";
+ else if (Name.compare(13,2,"16") == 0)
+ NewFnName = "llvm.memset.p0i8.i16";
+ else if (Name.compare(13,2,"32") == 0)
+ NewFnName = "llvm.memset.p0i8.i32";
+ else if (Name.compare(13,2,"64") == 0)
+ NewFnName = "llvm.memset.p0i8.i64";
+ }
+ if (NewFnName) {
+ const FunctionType *FTy = F->getFunctionType();
+ NewFn = cast<Function>(M->getOrInsertFunction(NewFnName,
+ FTy->getReturnType(),
+ FTy->getParamType(0),
+ FTy->getParamType(1),
+ FTy->getParamType(2),
+ FTy->getParamType(3),
+ Type::getInt1Ty(F->getContext()),
+ (Type *)0));
+ return true;
+ }
+ break;
+ }
case 'p':
// This upgrades the llvm.part.select overloaded intrinsic names to only
// use one type specifier in the name. We only care about the old format
@@ -225,6 +274,16 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
// Calls to these intrinsics are transformed into ShuffleVector's.
NewFn = 0;
return true;
+ } else if (Name.compare(5, 16, "x86.sse41.pmulld", 16) == 0) {
+ // Calls to these intrinsics are transformed into vector multiplies.
+ NewFn = 0;
+ return true;
+ } else if (Name.compare(5, 18, "x86.ssse3.palign.r", 18) == 0 ||
+ Name.compare(5, 22, "x86.ssse3.palign.r.128", 22) == 0) {
+ // Calls to these intrinsics are transformed into vector shuffles, shifts,
+ // or 0.
+ NewFn = 0;
+ return true;
}
break;
@@ -355,6 +414,130 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
// Clean up the old call now that it has been completely upgraded.
CI->eraseFromParent();
+ } else if (F->getName() == "llvm.x86.sse41.pmulld") {
+ // Upgrade this set of intrinsics into vector multiplies.
+ Instruction *Mul = BinaryOperator::CreateMul(CI->getOperand(1),
+ CI->getOperand(2),
+ CI->getName(),
+ CI);
+ // Fix up all the uses with our new multiply.
+ if (!CI->use_empty())
+ CI->replaceAllUsesWith(Mul);
+
+ // Remove upgraded multiply.
+ CI->eraseFromParent();
+ } else if (F->getName() == "llvm.x86.ssse3.palign.r") {
+ Value *Op1 = CI->getOperand(1);
+ Value *Op2 = CI->getOperand(2);
+ Value *Op3 = CI->getOperand(3);
+ unsigned shiftVal = cast<ConstantInt>(Op3)->getZExtValue();
+ Value *Rep;
+ IRBuilder<> Builder(C);
+ Builder.SetInsertPoint(CI->getParent(), CI);
+
+ // If palignr is shifting the pair of input vectors less than 9 bytes,
+ // emit a shuffle instruction.
+ if (shiftVal <= 8) {
+ const Type *IntTy = Type::getInt32Ty(C);
+ const Type *EltTy = Type::getInt8Ty(C);
+ const Type *VecTy = VectorType::get(EltTy, 8);
+
+ Op2 = Builder.CreateBitCast(Op2, VecTy);
+ Op1 = Builder.CreateBitCast(Op1, VecTy);
+
+ llvm::SmallVector<llvm::Constant*, 8> Indices;
+ for (unsigned i = 0; i != 8; ++i)
+ Indices.push_back(ConstantInt::get(IntTy, shiftVal + i));
+
+ Value *SV = ConstantVector::get(Indices.begin(), Indices.size());
+ Rep = Builder.CreateShuffleVector(Op2, Op1, SV, "palignr");
+ Rep = Builder.CreateBitCast(Rep, F->getReturnType());
+ }
+
+ // If palignr is shifting the pair of input vectors more than 8 but less
+ // than 16 bytes, emit a logical right shift of the destination.
+ else if (shiftVal < 16) {
+ // MMX has these as 1 x i64 vectors for some odd optimization reasons.
+ const Type *EltTy = Type::getInt64Ty(C);
+ const Type *VecTy = VectorType::get(EltTy, 1);
+
+ Op1 = Builder.CreateBitCast(Op1, VecTy, "cast");
+ Op2 = ConstantInt::get(VecTy, (shiftVal-8) * 8);
+
+ // create i32 constant
+ Function *I =
+ Intrinsic::getDeclaration(F->getParent(), Intrinsic::x86_mmx_psrl_q);
+ Rep = Builder.CreateCall2(I, Op1, Op2, "palignr");
+ }
+
+ // If palignr is shifting the pair of vectors more than 32 bytes, emit zero.
+ else {
+ Rep = Constant::getNullValue(F->getReturnType());
+ }
+
+ // Replace any uses with our new instruction.
+ if (!CI->use_empty())
+ CI->replaceAllUsesWith(Rep);
+
+ // Remove upgraded instruction.
+ CI->eraseFromParent();
+
+ } else if (F->getName() == "llvm.x86.ssse3.palign.r.128") {
+ Value *Op1 = CI->getOperand(1);
+ Value *Op2 = CI->getOperand(2);
+ Value *Op3 = CI->getOperand(3);
+ unsigned shiftVal = cast<ConstantInt>(Op3)->getZExtValue();
+ Value *Rep;
+ IRBuilder<> Builder(C);
+ Builder.SetInsertPoint(CI->getParent(), CI);
+
+ // If palignr is shifting the pair of input vectors less than 17 bytes,
+ // emit a shuffle instruction.
+ if (shiftVal <= 16) {
+ const Type *IntTy = Type::getInt32Ty(C);
+ const Type *EltTy = Type::getInt8Ty(C);
+ const Type *VecTy = VectorType::get(EltTy, 16);
+
+ Op2 = Builder.CreateBitCast(Op2, VecTy);
+ Op1 = Builder.CreateBitCast(Op1, VecTy);
+
+ llvm::SmallVector<llvm::Constant*, 16> Indices;
+ for (unsigned i = 0; i != 16; ++i)
+ Indices.push_back(ConstantInt::get(IntTy, shiftVal + i));
+
+ Value *SV = ConstantVector::get(Indices.begin(), Indices.size());
+ Rep = Builder.CreateShuffleVector(Op2, Op1, SV, "palignr");
+ Rep = Builder.CreateBitCast(Rep, F->getReturnType());
+ }
+
+ // If palignr is shifting the pair of input vectors more than 16 but less
+ // than 32 bytes, emit a logical right shift of the destination.
+ else if (shiftVal < 32) {
+ const Type *EltTy = Type::getInt64Ty(C);
+ const Type *VecTy = VectorType::get(EltTy, 2);
+ const Type *IntTy = Type::getInt32Ty(C);
+
+ Op1 = Builder.CreateBitCast(Op1, VecTy, "cast");
+ Op2 = ConstantInt::get(IntTy, (shiftVal-16) * 8);
+
+ // create i32 constant
+ Function *I =
+ Intrinsic::getDeclaration(F->getParent(), Intrinsic::x86_sse2_psrl_dq);
+ Rep = Builder.CreateCall2(I, Op1, Op2, "palignr");
+ }
+
+ // If palignr is shifting the pair of vectors more than 32 bytes, emit zero.
+ else {
+ Rep = Constant::getNullValue(F->getReturnType());
+ }
+
+ // Replace any uses with our new instruction.
+ if (!CI->use_empty())
+ CI->replaceAllUsesWith(Rep);
+
+ // Remove upgraded instruction.
+ CI->eraseFromParent();
+
} else {
llvm_unreachable("Unknown function for CallInst upgrade.");
}
@@ -455,6 +638,28 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
CI->eraseFromParent();
}
break;
+ case Intrinsic::memcpy:
+ case Intrinsic::memmove:
+ case Intrinsic::memset: {
+ // Add isVolatile
+ const llvm::Type *I1Ty = llvm::Type::getInt1Ty(CI->getContext());
+ Value *Operands[5] = { CI->getOperand(1), CI->getOperand(2),
+ CI->getOperand(3), CI->getOperand(4),
+ llvm::ConstantInt::get(I1Ty, 0) };
+ CallInst *NewCI = CallInst::Create(NewFn, Operands, Operands+5,
+ CI->getName(), CI);
+ NewCI->setTailCall(CI->isTailCall());
+ NewCI->setCallingConv(CI->getCallingConv());
+ // Handle any uses of the old CallInst.
+ if (!CI->use_empty())
+ // Replace all uses of the old call with the new cast which has the
+ // correct type.
+ CI->replaceAllUsesWith(NewCI);
+
+ // Clean up the old call now that it has been completely upgraded.
+ CI->eraseFromParent();
+ break;
+ }
}
}
diff --git a/lib/VMCore/BasicBlock.cpp b/lib/VMCore/BasicBlock.cpp
index 16437bc..8ad5373 100644
--- a/lib/VMCore/BasicBlock.cpp
+++ b/lib/VMCore/BasicBlock.cpp
@@ -14,6 +14,7 @@
#include "llvm/BasicBlock.h"
#include "llvm/Constants.h"
#include "llvm/Instructions.h"
+#include "llvm/IntrinsicInst.h"
#include "llvm/LLVMContext.h"
#include "llvm/Type.h"
#include "llvm/ADT/STLExtras.h"
@@ -136,6 +137,16 @@ Instruction* BasicBlock::getFirstNonPHI() {
return &*i;
}
+Instruction* BasicBlock::getFirstNonPHIOrDbg() {
+ BasicBlock::iterator i = begin();
+ // All valid basic blocks should have a terminator,
+ // which is not a PHINode. If we have an invalid basic
+ // block we'll get an assertion failure when dereferencing
+ // a past-the-end iterator.
+ while (isa<PHINode>(i) || isa<DbgInfoIntrinsic>(i)) ++i;
+ return &*i;
+}
+
void BasicBlock::dropAllReferences() {
for(iterator I = begin(), E = end(); I != E; ++I)
I->dropAllReferences();
diff --git a/lib/VMCore/CMakeLists.txt b/lib/VMCore/CMakeLists.txt
index 4b80e36..c64564b 100644
--- a/lib/VMCore/CMakeLists.txt
+++ b/lib/VMCore/CMakeLists.txt
@@ -6,6 +6,7 @@ add_llvm_library(LLVMCore
ConstantFold.cpp
Constants.cpp
Core.cpp
+ DebugLoc.cpp
Dominators.cpp
Function.cpp
GVMaterializer.cpp
@@ -16,6 +17,7 @@ add_llvm_library(LLVMCore
Instructions.cpp
IntrinsicInst.cpp
LLVMContext.cpp
+ LLVMContextImpl.cpp
LeakDetector.cpp
Metadata.cpp
Module.cpp
diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp
index 10f8879..d969dbb 100644
--- a/lib/VMCore/Constants.cpp
+++ b/lib/VMCore/Constants.cpp
@@ -59,6 +59,7 @@ Constant *Constant::getNullValue(const Type *Ty) {
case Type::PointerTyID:
return ConstantPointerNull::get(cast<PointerType>(Ty));
case Type::StructTyID:
+ case Type::UnionTyID:
case Type::ArrayTyID:
case Type::VectorTyID:
return ConstantAggregateZero::get(Ty);
@@ -160,7 +161,7 @@ bool Constant::canTrap() const {
/// isConstantUsed - Return true if the constant has users other than constant
/// exprs and other dangling things.
bool Constant::isConstantUsed() const {
- for (use_const_iterator UI = use_begin(), E = use_end(); UI != E; ++UI) {
+ for (const_use_iterator UI = use_begin(), E = use_end(); UI != E; ++UI) {
const Constant *UC = dyn_cast<Constant>(*UI);
if (UC == 0 || isa<GlobalValue>(UC))
return true;
@@ -944,7 +945,8 @@ bool ConstantFP::isValueValidForType(const Type *Ty, const APFloat& Val) {
// Factory Function Implementation
ConstantAggregateZero* ConstantAggregateZero::get(const Type* Ty) {
- assert((Ty->isStructTy() || Ty->isArrayTy() || Ty->isVectorTy()) &&
+ assert((Ty->isStructTy() || Ty->isUnionTy()
+ || Ty->isArrayTy() || Ty->isVectorTy()) &&
"Cannot create an aggregate zero of non-aggregate type!");
LLVMContextImpl *pImpl = Ty->getContext().pImpl;
@@ -1222,20 +1224,20 @@ Constant *ConstantExpr::getCast(unsigned oc, Constant *C, const Type *Ty) {
Constant *ConstantExpr::getZExtOrBitCast(Constant *C, const Type *Ty) {
if (C->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits())
- return getCast(Instruction::BitCast, C, Ty);
- return getCast(Instruction::ZExt, C, Ty);
+ return getBitCast(C, Ty);
+ return getZExt(C, Ty);
}
Constant *ConstantExpr::getSExtOrBitCast(Constant *C, const Type *Ty) {
if (C->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits())
- return getCast(Instruction::BitCast, C, Ty);
- return getCast(Instruction::SExt, C, Ty);
+ return getBitCast(C, Ty);
+ return getSExt(C, Ty);
}
Constant *ConstantExpr::getTruncOrBitCast(Constant *C, const Type *Ty) {
if (C->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits())
- return getCast(Instruction::BitCast, C, Ty);
- return getCast(Instruction::Trunc, C, Ty);
+ return getBitCast(C, Ty);
+ return getTrunc(C, Ty);
}
Constant *ConstantExpr::getPointerCast(Constant *S, const Type *Ty) {
@@ -1243,8 +1245,8 @@ Constant *ConstantExpr::getPointerCast(Constant *S, const Type *Ty) {
assert((Ty->isIntegerTy() || Ty->isPointerTy()) && "Invalid cast");
if (Ty->isIntegerTy())
- return getCast(Instruction::PtrToInt, S, Ty);
- return getCast(Instruction::BitCast, S, Ty);
+ return getPtrToInt(S, Ty);
+ return getBitCast(S, Ty);
}
Constant *ConstantExpr::getIntegerCast(Constant *C, const Type *Ty,
@@ -1521,8 +1523,8 @@ Constant* ConstantExpr::getSizeOf(const Type* Ty) {
Constant *GEPIdx = ConstantInt::get(Type::getInt32Ty(Ty->getContext()), 1);
Constant *GEP = getGetElementPtr(
Constant::getNullValue(PointerType::getUnqual(Ty)), &GEPIdx, 1);
- return getCast(Instruction::PtrToInt, GEP,
- Type::getInt64Ty(Ty->getContext()));
+ return getPtrToInt(GEP,
+ Type::getInt64Ty(Ty->getContext()));
}
Constant* ConstantExpr::getAlignOf(const Type* Ty) {
@@ -1535,8 +1537,8 @@ Constant* ConstantExpr::getAlignOf(const Type* Ty) {
Constant *One = ConstantInt::get(Type::getInt32Ty(Ty->getContext()), 1);
Constant *Indices[2] = { Zero, One };
Constant *GEP = getGetElementPtr(NullPtr, Indices, 2);
- return getCast(Instruction::PtrToInt, GEP,
- Type::getInt64Ty(Ty->getContext()));
+ return getPtrToInt(GEP,
+ Type::getInt64Ty(Ty->getContext()));
}
Constant* ConstantExpr::getOffsetOf(const StructType* STy, unsigned FieldNo) {
@@ -1553,8 +1555,8 @@ Constant* ConstantExpr::getOffsetOf(const Type* Ty, Constant *FieldNo) {
};
Constant *GEP = getGetElementPtr(
Constant::getNullValue(PointerType::getUnqual(Ty)), GEPIdx, 2);
- return getCast(Instruction::PtrToInt, GEP,
- Type::getInt64Ty(Ty->getContext()));
+ return getPtrToInt(GEP,
+ Type::getInt64Ty(Ty->getContext()));
}
Constant *ConstantExpr::getCompare(unsigned short pred,
@@ -1945,6 +1947,20 @@ const char *ConstantExpr::getOpcodeName() const {
return Instruction::getOpcodeName(getOpcode());
}
+
+
+GetElementPtrConstantExpr::
+GetElementPtrConstantExpr(Constant *C, const std::vector<Constant*> &IdxList,
+ const Type *DestTy)
+ : ConstantExpr(DestTy, Instruction::GetElementPtr,
+ OperandTraits<GetElementPtrConstantExpr>::op_end(this)
+ - (IdxList.size()+1), IdxList.size()+1) {
+ OperandList[0] = C;
+ for (unsigned i = 0, E = IdxList.size(); i != E; ++i)
+ OperandList[i+1] = IdxList[i];
+}
+
+
//===----------------------------------------------------------------------===//
// replaceUsesOfWithOnConstant implementations
diff --git a/lib/VMCore/ConstantsContext.h b/lib/VMCore/ConstantsContext.h
index c798ba2..2f2fac5 100644
--- a/lib/VMCore/ConstantsContext.h
+++ b/lib/VMCore/ConstantsContext.h
@@ -15,6 +15,7 @@
#ifndef LLVM_CONSTANTSCONTEXT_H
#define LLVM_CONSTANTSCONTEXT_H
+#include "llvm/InlineAsm.h"
#include "llvm/Instructions.h"
#include "llvm/Operator.h"
#include "llvm/Support/Debug.h"
@@ -327,6 +328,39 @@ struct ExprMapKeyType {
}
};
+struct InlineAsmKeyType {
+ InlineAsmKeyType(StringRef AsmString,
+ StringRef Constraints, bool hasSideEffects,
+ bool isAlignStack)
+ : asm_string(AsmString), constraints(Constraints),
+ has_side_effects(hasSideEffects), is_align_stack(isAlignStack) {}
+ std::string asm_string;
+ std::string constraints;
+ bool has_side_effects;
+ bool is_align_stack;
+ bool operator==(const InlineAsmKeyType& that) const {
+ return this->asm_string == that.asm_string &&
+ this->constraints == that.constraints &&
+ this->has_side_effects == that.has_side_effects &&
+ this->is_align_stack == that.is_align_stack;
+ }
+ bool operator<(const InlineAsmKeyType& that) const {
+ if (this->asm_string != that.asm_string)
+ return this->asm_string < that.asm_string;
+ if (this->constraints != that.constraints)
+ return this->constraints < that.constraints;
+ if (this->has_side_effects != that.has_side_effects)
+ return this->has_side_effects < that.has_side_effects;
+ if (this->is_align_stack != that.is_align_stack)
+ return this->is_align_stack < that.is_align_stack;
+ return false;
+ }
+
+ bool operator!=(const InlineAsmKeyType& that) const {
+ return !(*this == that);
+ }
+};
+
// The number of operands for each ConstantCreator::create method is
// determined by the ConstantTraits template.
// ConstantCreator - A class that is used to create constants by
@@ -517,6 +551,23 @@ struct ConstantKeyData<UndefValue> {
}
};
+template<>
+struct ConstantCreator<InlineAsm, PointerType, InlineAsmKeyType> {
+ static InlineAsm *create(const PointerType *Ty, const InlineAsmKeyType &Key) {
+ return new InlineAsm(Ty, Key.asm_string, Key.constraints,
+ Key.has_side_effects, Key.is_align_stack);
+ }
+};
+
+template<>
+struct ConstantKeyData<InlineAsm> {
+ typedef InlineAsmKeyType ValType;
+ static ValType getValType(InlineAsm *Asm) {
+ return InlineAsmKeyType(Asm->getAsmString(), Asm->getConstraintString(),
+ Asm->hasSideEffects(), Asm->isAlignStack());
+ }
+};
+
template<class ValType, class TypeClass, class ConstantClass,
bool HasLargeKey = false /*true for arrays and structs*/ >
class ConstantUniqueMap : public AbstractTypeUser {
@@ -549,8 +600,8 @@ public:
void freeConstants() {
for (typename MapTy::iterator I=Map.begin(), E=Map.end();
I != E; ++I) {
- if (I->second->use_empty())
- delete I->second;
+ // Asserts that use_empty().
+ delete I->second;
}
}
diff --git a/lib/VMCore/Core.cpp b/lib/VMCore/Core.cpp
index f4f65c5..8c88f5d 100644
--- a/lib/VMCore/Core.cpp
+++ b/lib/VMCore/Core.cpp
@@ -119,6 +119,11 @@ void LLVMDumpModule(LLVMModuleRef M) {
unwrap(M)->dump();
}
+/*--.. Operations on inline assembler ......................................--*/
+void LLVMSetModuleInlineAsm(LLVMModuleRef M, const char *Asm) {
+ unwrap(M)->setModuleInlineAsm(StringRef(Asm));
+}
+
/*===-- Operations on types -----------------------------------------------===*/
@@ -1651,7 +1656,7 @@ LLVMBasicBlockRef LLVMGetInsertBlock(LLVMBuilderRef Builder) {
}
void LLVMClearInsertionPosition(LLVMBuilderRef Builder) {
- unwrap(Builder)->ClearInsertionPoint ();
+ unwrap(Builder)->ClearInsertionPoint();
}
void LLVMInsertIntoBuilder(LLVMBuilderRef Builder, LLVMValueRef Instr) {
@@ -1670,11 +1675,13 @@ void LLVMDisposeBuilder(LLVMBuilderRef Builder) {
/*--.. Metadata builders ...................................................--*/
void LLVMSetCurrentDebugLocation(LLVMBuilderRef Builder, LLVMValueRef L) {
- unwrap(Builder)->SetCurrentDebugLocation(L? unwrap<MDNode>(L) : NULL);
+ MDNode *Loc = L ? unwrap<MDNode>(L) : NULL;
+ unwrap(Builder)->SetCurrentDebugLocation(DebugLoc::getFromDILocation(Loc));
}
LLVMValueRef LLVMGetCurrentDebugLocation(LLVMBuilderRef Builder) {
- return wrap(unwrap(Builder)->getCurrentDebugLocation());
+ return wrap(unwrap(Builder)->getCurrentDebugLocation()
+ .getAsMDNode(unwrap(Builder)->getContext()));
}
void LLVMSetInstDebugLocation(LLVMBuilderRef Builder, LLVMValueRef Inst) {
diff --git a/lib/VMCore/DebugLoc.cpp b/lib/VMCore/DebugLoc.cpp
new file mode 100644
index 0000000..f8b45ee
--- /dev/null
+++ b/lib/VMCore/DebugLoc.cpp
@@ -0,0 +1,288 @@
+//===-- DebugLoc.cpp - Implement DebugLoc class ---------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/DebugLoc.h"
+#include "LLVMContextImpl.h"
+using namespace llvm;
+
+//===----------------------------------------------------------------------===//
+// DebugLoc Implementation
+//===----------------------------------------------------------------------===//
+
+MDNode *DebugLoc::getScope(const LLVMContext &Ctx) const {
+ if (ScopeIdx == 0) return 0;
+
+ if (ScopeIdx > 0) {
+ // Positive ScopeIdx is an index into ScopeRecords, which has no inlined-at
+ // position specified.
+ assert(unsigned(ScopeIdx) <= Ctx.pImpl->ScopeRecords.size() &&
+ "Invalid ScopeIdx!");
+ return Ctx.pImpl->ScopeRecords[ScopeIdx-1].get();
+ }
+
+ // Otherwise, the index is in the ScopeInlinedAtRecords array.
+ assert(unsigned(-ScopeIdx) <= Ctx.pImpl->ScopeInlinedAtRecords.size() &&
+ "Invalid ScopeIdx");
+ return Ctx.pImpl->ScopeInlinedAtRecords[-ScopeIdx-1].first.get();
+}
+
+MDNode *DebugLoc::getInlinedAt(const LLVMContext &Ctx) const {
+ // Positive ScopeIdx is an index into ScopeRecords, which has no inlined-at
+ // position specified. Zero is invalid.
+ if (ScopeIdx >= 0) return 0;
+
+ // Otherwise, the index is in the ScopeInlinedAtRecords array.
+ assert(unsigned(-ScopeIdx) <= Ctx.pImpl->ScopeInlinedAtRecords.size() &&
+ "Invalid ScopeIdx");
+ return Ctx.pImpl->ScopeInlinedAtRecords[-ScopeIdx-1].second.get();
+}
+
+/// Return both the Scope and the InlinedAt values.
+void DebugLoc::getScopeAndInlinedAt(MDNode *&Scope, MDNode *&IA,
+ const LLVMContext &Ctx) const {
+ if (ScopeIdx == 0) {
+ Scope = IA = 0;
+ return;
+ }
+
+ if (ScopeIdx > 0) {
+ // Positive ScopeIdx is an index into ScopeRecords, which has no inlined-at
+ // position specified.
+ assert(unsigned(ScopeIdx) <= Ctx.pImpl->ScopeRecords.size() &&
+ "Invalid ScopeIdx!");
+ Scope = Ctx.pImpl->ScopeRecords[ScopeIdx-1].get();
+ IA = 0;
+ return;
+ }
+
+ // Otherwise, the index is in the ScopeInlinedAtRecords array.
+ assert(unsigned(-ScopeIdx) <= Ctx.pImpl->ScopeInlinedAtRecords.size() &&
+ "Invalid ScopeIdx");
+ Scope = Ctx.pImpl->ScopeInlinedAtRecords[-ScopeIdx-1].first.get();
+ IA = Ctx.pImpl->ScopeInlinedAtRecords[-ScopeIdx-1].second.get();
+}
+
+
+DebugLoc DebugLoc::get(unsigned Line, unsigned Col,
+ MDNode *Scope, MDNode *InlinedAt) {
+ DebugLoc Result;
+
+ // If no scope is available, this is an unknown location.
+ if (Scope == 0) return Result;
+
+ // Saturate line and col to "unknown".
+ if (Col > 255) Col = 0;
+ if (Line >= (1 << 24)) Line = 0;
+ Result.LineCol = Line | (Col << 24);
+
+ LLVMContext &Ctx = Scope->getContext();
+
+ // If there is no inlined-at location, use the ScopeRecords array.
+ if (InlinedAt == 0)
+ Result.ScopeIdx = Ctx.pImpl->getOrAddScopeRecordIdxEntry(Scope, 0);
+ else
+ Result.ScopeIdx = Ctx.pImpl->getOrAddScopeInlinedAtIdxEntry(Scope,
+ InlinedAt, 0);
+
+ return Result;
+}
+
+/// getAsMDNode - This method converts the compressed DebugLoc node into a
+/// DILocation compatible MDNode.
+MDNode *DebugLoc::getAsMDNode(const LLVMContext &Ctx) const {
+ if (isUnknown()) return 0;
+
+ MDNode *Scope, *IA;
+ getScopeAndInlinedAt(Scope, IA, Ctx);
+ assert(Scope && "If scope is null, this should be isUnknown()");
+
+ LLVMContext &Ctx2 = Scope->getContext();
+ const Type *Int32 = Type::getInt32Ty(Ctx2);
+ Value *Elts[] = {
+ ConstantInt::get(Int32, getLine()), ConstantInt::get(Int32, getCol()),
+ Scope, IA
+ };
+ return MDNode::get(Ctx2, &Elts[0], 4);
+}
+
+/// getFromDILocation - Translate the DILocation quad into a DebugLoc.
+DebugLoc DebugLoc::getFromDILocation(MDNode *N) {
+ if (N == 0 || N->getNumOperands() != 4) return DebugLoc();
+
+ MDNode *Scope = dyn_cast_or_null<MDNode>(N->getOperand(2));
+ if (Scope == 0) return DebugLoc();
+
+ unsigned LineNo = 0, ColNo = 0;
+ if (ConstantInt *Line = dyn_cast_or_null<ConstantInt>(N->getOperand(0)))
+ LineNo = Line->getZExtValue();
+ if (ConstantInt *Col = dyn_cast_or_null<ConstantInt>(N->getOperand(1)))
+ ColNo = Col->getZExtValue();
+
+ return get(LineNo, ColNo, Scope, dyn_cast_or_null<MDNode>(N->getOperand(3)));
+}
+
+//===----------------------------------------------------------------------===//
+// LLVMContextImpl Implementation
+//===----------------------------------------------------------------------===//
+
+int LLVMContextImpl::getOrAddScopeRecordIdxEntry(MDNode *Scope,
+ int ExistingIdx) {
+ // If we already have an entry for this scope, return it.
+ int &Idx = ScopeRecordIdx[Scope];
+ if (Idx) return Idx;
+
+ // If we don't have an entry, but ExistingIdx is specified, use it.
+ if (ExistingIdx)
+ return Idx = ExistingIdx;
+
+ // Otherwise add a new entry.
+
+ // Start out ScopeRecords with a minimal reasonable size to avoid
+ // excessive reallocation starting out.
+ if (ScopeRecords.empty())
+ ScopeRecords.reserve(128);
+
+ // Index is biased by 1 for index.
+ Idx = ScopeRecords.size()+1;
+ ScopeRecords.push_back(DebugRecVH(Scope, this, Idx));
+ return Idx;
+}
+
+int LLVMContextImpl::getOrAddScopeInlinedAtIdxEntry(MDNode *Scope, MDNode *IA,
+ int ExistingIdx) {
+ // If we already have an entry, return it.
+ int &Idx = ScopeInlinedAtIdx[std::make_pair(Scope, IA)];
+ if (Idx) return Idx;
+
+ // If we don't have an entry, but ExistingIdx is specified, use it.
+ if (ExistingIdx)
+ return Idx = ExistingIdx;
+
+ // Start out ScopeInlinedAtRecords with a minimal reasonable size to avoid
+ // excessive reallocation starting out.
+ if (ScopeInlinedAtRecords.empty())
+ ScopeInlinedAtRecords.reserve(128);
+
+ // Index is biased by 1 and negated.
+ Idx = -ScopeInlinedAtRecords.size()-1;
+ ScopeInlinedAtRecords.push_back(std::make_pair(DebugRecVH(Scope, this, Idx),
+ DebugRecVH(IA, this, Idx)));
+ return Idx;
+}
+
+
+//===----------------------------------------------------------------------===//
+// DebugRecVH Implementation
+//===----------------------------------------------------------------------===//
+
+/// deleted - The MDNode this is pointing to got deleted, so this pointer needs
+/// to drop to null and we need remove our entry from the DenseMap.
+void DebugRecVH::deleted() {
+ // If this is a non-canonical reference, just drop the value to null, we know
+ // it doesn't have a map entry.
+ if (Idx == 0) {
+ setValPtr(0);
+ return;
+ }
+
+ MDNode *Cur = get();
+
+ // If the index is positive, it is an entry in ScopeRecords.
+ if (Idx > 0) {
+ assert(Ctx->ScopeRecordIdx[Cur] == Idx && "Mapping out of date!");
+ Ctx->ScopeRecordIdx.erase(Cur);
+ // Reset this VH to null and we're done.
+ setValPtr(0);
+ Idx = 0;
+ return;
+ }
+
+ // Otherwise, it is an entry in ScopeInlinedAtRecords, we don't know if it
+ // is the scope or the inlined-at record entry.
+ assert(unsigned(-Idx-1) < Ctx->ScopeInlinedAtRecords.size());
+ std::pair<DebugRecVH, DebugRecVH> &Entry = Ctx->ScopeInlinedAtRecords[-Idx-1];
+ assert((this == &Entry.first || this == &Entry.second) &&
+ "Mapping out of date!");
+
+ MDNode *OldScope = Entry.first.get();
+ MDNode *OldInlinedAt = Entry.second.get();
+ assert(OldScope != 0 && OldInlinedAt != 0 &&
+ "Entry should be non-canonical if either val dropped to null");
+
+ // Otherwise, we do have an entry in it, nuke it and we're done.
+ assert(Ctx->ScopeInlinedAtIdx[std::make_pair(OldScope, OldInlinedAt)] == Idx&&
+ "Mapping out of date");
+ Ctx->ScopeInlinedAtIdx.erase(std::make_pair(OldScope, OldInlinedAt));
+
+ // Reset this VH to null. Drop both 'Idx' values to null to indicate that
+ // we're in non-canonical form now.
+ setValPtr(0);
+ Entry.first.Idx = Entry.second.Idx = 0;
+}
+
+void DebugRecVH::allUsesReplacedWith(Value *NewVa) {
+ // If being replaced with a non-mdnode value (e.g. undef) handle this as if
+ // the mdnode got deleted.
+ MDNode *NewVal = dyn_cast<MDNode>(NewVa);
+ if (NewVal == 0) return deleted();
+
+ // If this is a non-canonical reference, just change it, we know it already
+ // doesn't have a map entry.
+ if (Idx == 0) {
+ setValPtr(NewVa);
+ return;
+ }
+
+ MDNode *OldVal = get();
+ assert(OldVal != NewVa && "Node replaced with self?");
+
+ // If the index is positive, it is an entry in ScopeRecords.
+ if (Idx > 0) {
+ assert(Ctx->ScopeRecordIdx[OldVal] == Idx && "Mapping out of date!");
+ Ctx->ScopeRecordIdx.erase(OldVal);
+ setValPtr(NewVal);
+
+ int NewEntry = Ctx->getOrAddScopeRecordIdxEntry(NewVal, Idx);
+
+ // If NewVal already has an entry, this becomes a non-canonical reference,
+ // just drop Idx to 0 to signify this.
+ if (NewEntry != Idx)
+ Idx = 0;
+ return;
+ }
+
+ // Otherwise, it is an entry in ScopeInlinedAtRecords, we don't know if it
+ // is the scope or the inlined-at record entry.
+ assert(unsigned(-Idx-1) < Ctx->ScopeInlinedAtRecords.size());
+ std::pair<DebugRecVH, DebugRecVH> &Entry = Ctx->ScopeInlinedAtRecords[-Idx-1];
+ assert((this == &Entry.first || this == &Entry.second) &&
+ "Mapping out of date!");
+
+ MDNode *OldScope = Entry.first.get();
+ MDNode *OldInlinedAt = Entry.second.get();
+ assert(OldScope != 0 && OldInlinedAt != 0 &&
+ "Entry should be non-canonical if either val dropped to null");
+
+ // Otherwise, we do have an entry in it, nuke it and we're done.
+ assert(Ctx->ScopeInlinedAtIdx[std::make_pair(OldScope, OldInlinedAt)] == Idx&&
+ "Mapping out of date");
+ Ctx->ScopeInlinedAtIdx.erase(std::make_pair(OldScope, OldInlinedAt));
+
+ // Reset this VH to the new value.
+ setValPtr(NewVal);
+
+ int NewIdx = Ctx->getOrAddScopeInlinedAtIdxEntry(Entry.first.get(),
+ Entry.second.get(), Idx);
+ // If NewVal already has an entry, this becomes a non-canonical reference,
+ // just drop Idx to 0 to signify this.
+ if (NewIdx != Idx) {
+ std::pair<DebugRecVH, DebugRecVH> &Entry=Ctx->ScopeInlinedAtRecords[-Idx-1];
+ Entry.first.Idx = Entry.second.Idx = 0;
+ }
+}
diff --git a/lib/VMCore/Dominators.cpp b/lib/VMCore/Dominators.cpp
index 3441750..10a866f 100644
--- a/lib/VMCore/Dominators.cpp
+++ b/lib/VMCore/Dominators.cpp
@@ -30,9 +30,9 @@ using namespace llvm;
// Always verify dominfo if expensive checking is enabled.
#ifdef XDEBUG
-bool VerifyDomInfo = true;
+static bool VerifyDomInfo = true;
#else
-bool VerifyDomInfo = false;
+static bool VerifyDomInfo = false;
#endif
static cl::opt<bool,true>
VerifyDomInfoX("verify-dom-info", cl::location(VerifyDomInfo),
@@ -119,7 +119,7 @@ void DominanceFrontier::verifyAnalysis() const {
assert(!compare(OtherDF) && "Invalid DominanceFrontier info!");
}
-// NewBB is split and now it has one successor. Update dominace frontier to
+// NewBB is split and now it has one successor. Update dominance frontier to
// reflect this change.
void DominanceFrontier::splitBlock(BasicBlock *NewBB) {
assert(NewBB->getTerminator()->getNumSuccessors() == 1
@@ -129,7 +129,7 @@ void DominanceFrontier::splitBlock(BasicBlock *NewBB) {
SmallVector<BasicBlock*, 8> PredBlocks;
for (pred_iterator PI = pred_begin(NewBB), PE = pred_end(NewBB);
PI != PE; ++PI)
- PredBlocks.push_back(*PI);
+ PredBlocks.push_back(*PI);
if (PredBlocks.empty())
// If NewBB does not have any predecessors then it is a entry block.
diff --git a/lib/VMCore/Function.cpp b/lib/VMCore/Function.cpp
index dbc283e..8f94efc 100644
--- a/lib/VMCore/Function.cpp
+++ b/lib/VMCore/Function.cpp
@@ -16,6 +16,7 @@
#include "llvm/IntrinsicInst.h"
#include "llvm/LLVMContext.h"
#include "llvm/CodeGen/ValueTypes.h"
+#include "llvm/Support/CallSite.h"
#include "llvm/Support/LeakDetector.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/StringPool.h"
@@ -400,13 +401,16 @@ Function *Intrinsic::getDeclaration(Module *M, ID id, const Type **Tys,
#include "llvm/Intrinsics.gen"
#undef GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN
- /// hasAddressTaken - returns true if there are any uses of this function
- /// other than direct calls or invokes to it.
-bool Function::hasAddressTaken() const {
- for (Value::use_const_iterator I = use_begin(), E = use_end(); I != E; ++I) {
- if (I.getOperandNo() != 0 ||
- (!isa<CallInst>(*I) && !isa<InvokeInst>(*I)))
- return true;
+/// hasAddressTaken - returns true if there are any uses of this function
+/// other than direct calls or invokes to it.
+bool Function::hasAddressTaken(const User* *PutOffender) const {
+ for (Value::const_use_iterator I = use_begin(), E = use_end(); I != E; ++I) {
+ const User *U = *I;
+ if (!isa<CallInst>(U) && !isa<InvokeInst>(U))
+ return PutOffender ? (*PutOffender = U, true) : true;
+ ImmutableCallSite CS(cast<Instruction>(U));
+ if (!CS.isCallee(I))
+ return PutOffender ? (*PutOffender = U, true) : true;
}
return false;
}
diff --git a/lib/VMCore/Globals.cpp b/lib/VMCore/Globals.cpp
index 489ec65..b758eb8 100644
--- a/lib/VMCore/Globals.cpp
+++ b/lib/VMCore/Globals.cpp
@@ -61,8 +61,8 @@ void GlobalValue::Dematerialize() {
/// that want to check to see if a global is unused, but don't want to deal
/// with potentially dead constants hanging off of the globals.
void GlobalValue::removeDeadConstantUsers() const {
- Value::use_const_iterator I = use_begin(), E = use_end();
- Value::use_const_iterator LastNonDeadUser = E;
+ Value::const_use_iterator I = use_begin(), E = use_end();
+ Value::const_use_iterator LastNonDeadUser = E;
while (I != E) {
if (const Constant *User = dyn_cast<Constant>(*I)) {
if (!removeDeadUsersOfConstant(User)) {
diff --git a/lib/VMCore/IRBuilder.cpp b/lib/VMCore/IRBuilder.cpp
index 9f2786e..c1b783c 100644
--- a/lib/VMCore/IRBuilder.cpp
+++ b/lib/VMCore/IRBuilder.cpp
@@ -32,19 +32,6 @@ Value *IRBuilderBase::CreateGlobalString(const char *Str, const Twine &Name) {
return GV;
}
-/// SetCurrentDebugLocation - Set location information used by debugging
-/// information.
-void IRBuilderBase::SetCurrentDebugLocation(MDNode *L) {
- if (DbgMDKind == 0)
- DbgMDKind = Context.getMDKindID("dbg");
- CurDbgLocation = L;
-}
-
-void IRBuilderBase::SetInstDebugLocation(Instruction *I) const {
- if (CurDbgLocation)
- I->setMetadata(DbgMDKind, CurDbgLocation);
-}
-
const Type *IRBuilderBase::getCurrentFunctionReturnType() const {
assert(BB && BB->getParent() && "No current function!");
return BB->getParent()->getReturnType();
diff --git a/lib/VMCore/InlineAsm.cpp b/lib/VMCore/InlineAsm.cpp
index 6355834..0d2eca9 100644
--- a/lib/VMCore/InlineAsm.cpp
+++ b/lib/VMCore/InlineAsm.cpp
@@ -12,6 +12,8 @@
//===----------------------------------------------------------------------===//
#include "llvm/InlineAsm.h"
+#include "ConstantsContext.h"
+#include "LLVMContextImpl.h"
#include "llvm/DerivedTypes.h"
#include <algorithm>
#include <cctype>
@@ -23,28 +25,29 @@ InlineAsm::~InlineAsm() {
}
-// NOTE: when memoizing the function type, we have to be careful to handle the
-// case when the type gets refined.
-
InlineAsm *InlineAsm::get(const FunctionType *Ty, StringRef AsmString,
StringRef Constraints, bool hasSideEffects,
bool isAlignStack) {
- // FIXME: memoize!
- return new InlineAsm(Ty, AsmString, Constraints, hasSideEffects,
- isAlignStack);
+ InlineAsmKeyType Key(AsmString, Constraints, hasSideEffects, isAlignStack);
+ LLVMContextImpl *pImpl = Ty->getContext().pImpl;
+ return pImpl->InlineAsms.getOrCreate(PointerType::getUnqual(Ty), Key);
}
-InlineAsm::InlineAsm(const FunctionType *Ty, StringRef asmString,
- StringRef constraints, bool hasSideEffects,
+InlineAsm::InlineAsm(const PointerType *Ty, const std::string &asmString,
+ const std::string &constraints, bool hasSideEffects,
bool isAlignStack)
- : Value(PointerType::getUnqual(Ty),
- Value::InlineAsmVal),
+ : Value(Ty, Value::InlineAsmVal),
AsmString(asmString),
Constraints(constraints), HasSideEffects(hasSideEffects),
IsAlignStack(isAlignStack) {
// Do various checks on the constraint string and type.
- assert(Verify(Ty, constraints) && "Function type not legal for constraints!");
+ assert(Verify(getFunctionType(), constraints) &&
+ "Function type not legal for constraints!");
+}
+
+void InlineAsm::destroyConstant() {
+ delete this;
}
const FunctionType *InlineAsm::getFunctionType() const {
diff --git a/lib/VMCore/Instruction.cpp b/lib/VMCore/Instruction.cpp
index 3fabfd0..a37fe07 100644
--- a/lib/VMCore/Instruction.cpp
+++ b/lib/VMCore/Instruction.cpp
@@ -283,7 +283,7 @@ bool Instruction::isSameOperationAs(const Instruction *I) const {
/// specified block. Note that PHI nodes are considered to evaluate their
/// operands in the corresponding predecessor block.
bool Instruction::isUsedOutsideOfBlock(const BasicBlock *BB) const {
- for (use_const_iterator UI = use_begin(), E = use_end(); UI != E; ++UI) {
+ for (const_use_iterator UI = use_begin(), E = use_end(); UI != E; ++UI) {
// PHI nodes uses values in the corresponding predecessor block. For other
// instructions, just check to see whether the parent of the use matches up.
const PHINode *PN = dyn_cast<PHINode>(*UI);
diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp
index 8f4763f..d5c89c9 100644
--- a/lib/VMCore/Instructions.cpp
+++ b/lib/VMCore/Instructions.cpp
@@ -30,76 +30,12 @@ using namespace llvm;
// CallSite Class
//===----------------------------------------------------------------------===//
-#define CALLSITE_DELEGATE_GETTER(METHOD) \
- Instruction *II(getInstruction()); \
- return isCall() \
- ? cast<CallInst>(II)->METHOD \
- : cast<InvokeInst>(II)->METHOD
-
-#define CALLSITE_DELEGATE_SETTER(METHOD) \
- Instruction *II(getInstruction()); \
- if (isCall()) \
- cast<CallInst>(II)->METHOD; \
- else \
- cast<InvokeInst>(II)->METHOD
-
-CallSite::CallSite(Instruction *C) {
- assert((isa<CallInst>(C) || isa<InvokeInst>(C)) && "Not a call!");
- I.setPointer(C);
- I.setInt(isa<CallInst>(C));
-}
-CallingConv::ID CallSite::getCallingConv() const {
- CALLSITE_DELEGATE_GETTER(getCallingConv());
-}
-void CallSite::setCallingConv(CallingConv::ID CC) {
- CALLSITE_DELEGATE_SETTER(setCallingConv(CC));
-}
-const AttrListPtr &CallSite::getAttributes() const {
- CALLSITE_DELEGATE_GETTER(getAttributes());
-}
-void CallSite::setAttributes(const AttrListPtr &PAL) {
- CALLSITE_DELEGATE_SETTER(setAttributes(PAL));
-}
-bool CallSite::paramHasAttr(uint16_t i, Attributes attr) const {
- CALLSITE_DELEGATE_GETTER(paramHasAttr(i, attr));
-}
-uint16_t CallSite::getParamAlignment(uint16_t i) const {
- CALLSITE_DELEGATE_GETTER(getParamAlignment(i));
-}
-bool CallSite::doesNotAccessMemory() const {
- CALLSITE_DELEGATE_GETTER(doesNotAccessMemory());
-}
-void CallSite::setDoesNotAccessMemory(bool doesNotAccessMemory) {
- CALLSITE_DELEGATE_SETTER(setDoesNotAccessMemory(doesNotAccessMemory));
-}
-bool CallSite::onlyReadsMemory() const {
- CALLSITE_DELEGATE_GETTER(onlyReadsMemory());
-}
-void CallSite::setOnlyReadsMemory(bool onlyReadsMemory) {
- CALLSITE_DELEGATE_SETTER(setOnlyReadsMemory(onlyReadsMemory));
+User::op_iterator CallSite::getCallee() const {
+ Instruction *II(getInstruction());
+ return isCall()
+ ? cast<CallInst>(II)->op_begin()
+ : cast<InvokeInst>(II)->op_end() - 3; // Skip BB, BB, Function
}
-bool CallSite::doesNotReturn() const {
- CALLSITE_DELEGATE_GETTER(doesNotReturn());
-}
-void CallSite::setDoesNotReturn(bool doesNotReturn) {
- CALLSITE_DELEGATE_SETTER(setDoesNotReturn(doesNotReturn));
-}
-bool CallSite::doesNotThrow() const {
- CALLSITE_DELEGATE_GETTER(doesNotThrow());
-}
-void CallSite::setDoesNotThrow(bool doesNotThrow) {
- CALLSITE_DELEGATE_SETTER(setDoesNotThrow(doesNotThrow));
-}
-
-bool CallSite::hasArgument(const Value *Arg) const {
- for (arg_iterator AI = this->arg_begin(), E = this->arg_end(); AI != E; ++AI)
- if (AI->get() == Arg)
- return true;
- return false;
-}
-
-#undef CALLSITE_DELEGATE_GETTER
-#undef CALLSITE_DELEGATE_SETTER
//===----------------------------------------------------------------------===//
// TerminatorInst Class
@@ -611,24 +547,24 @@ Instruction* CallInst::CreateFree(Value* Source, BasicBlock *InsertAtEnd) {
void InvokeInst::init(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException,
Value* const *Args, unsigned NumArgs) {
assert(NumOperands == 3+NumArgs && "NumOperands not set up?");
- Use *OL = OperandList;
- OL[0] = Fn;
- OL[1] = IfNormal;
- OL[2] = IfException;
+ Op<-3>() = Fn;
+ Op<-2>() = IfNormal;
+ Op<-1>() = IfException;
const FunctionType *FTy =
cast<FunctionType>(cast<PointerType>(Fn->getType())->getElementType());
FTy = FTy; // silence warning.
assert(((NumArgs == FTy->getNumParams()) ||
(FTy->isVarArg() && NumArgs > FTy->getNumParams())) &&
- "Calling a function with bad signature");
+ "Invoking a function with bad signature");
+ Use *OL = OperandList;
for (unsigned i = 0, e = NumArgs; i != e; i++) {
assert((i >= FTy->getNumParams() ||
FTy->getParamType(i) == Args[i]->getType()) &&
"Invoking a function with a bad signature!");
- OL[i+3] = Args[i];
+ OL[i] = Args[i];
}
}
@@ -2047,7 +1983,7 @@ unsigned CastInst::isEliminableCastPair(
// FPEXT < FloatPt n/a FloatPt n/a
// PTRTOINT n/a Pointer n/a Integral Unsigned
// INTTOPTR n/a Integral Unsigned Pointer n/a
- // BITCONVERT = FirstClass n/a FirstClass n/a
+ // BITCAST = FirstClass n/a FirstClass 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",
diff --git a/lib/VMCore/IntrinsicInst.cpp b/lib/VMCore/IntrinsicInst.cpp
index d8f015a..c37d5b0 100644
--- a/lib/VMCore/IntrinsicInst.cpp
+++ b/lib/VMCore/IntrinsicInst.cpp
@@ -24,8 +24,7 @@
#include "llvm/IntrinsicInst.h"
#include "llvm/Constants.h"
#include "llvm/GlobalVariable.h"
-#include "llvm/Analysis/ValueTracking.h"
-#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/Metadata.h"
using namespace llvm;
//===----------------------------------------------------------------------===//
diff --git a/lib/VMCore/LLVMContext.cpp b/lib/VMCore/LLVMContext.cpp
index 5a8ea5c..4d61363 100644
--- a/lib/VMCore/LLVMContext.cpp
+++ b/lib/VMCore/LLVMContext.cpp
@@ -17,6 +17,7 @@
#include "llvm/Constants.h"
#include "llvm/Instruction.h"
#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/SourceMgr.h"
#include "LLVMContextImpl.h"
using namespace llvm;
@@ -26,19 +27,104 @@ LLVMContext& llvm::getGlobalContext() {
return *GlobalContext;
}
-LLVMContext::LLVMContext() : pImpl(new LLVMContextImpl(*this)) { }
+LLVMContext::LLVMContext() : pImpl(new LLVMContextImpl(*this)) {
+ // Create the first metadata kind, which is always 'dbg'.
+ unsigned DbgID = getMDKindID("dbg");
+ assert(DbgID == MD_dbg && "dbg kind id drifted"); (void)DbgID;
+}
LLVMContext::~LLVMContext() { delete pImpl; }
-GetElementPtrConstantExpr::GetElementPtrConstantExpr
- (Constant *C,
- const std::vector<Constant*> &IdxList,
- const Type *DestTy)
- : ConstantExpr(DestTy, Instruction::GetElementPtr,
- OperandTraits<GetElementPtrConstantExpr>::op_end(this)
- - (IdxList.size()+1),
- IdxList.size()+1) {
- OperandList[0] = C;
- for (unsigned i = 0, E = IdxList.size(); i != E; ++i)
- OperandList[i+1] = IdxList[i];
+//===----------------------------------------------------------------------===//
+// Recoverable Backend Errors
+//===----------------------------------------------------------------------===//
+
+void LLVMContext::setInlineAsmDiagnosticHandler(void *DiagHandler,
+ void *DiagContext) {
+ pImpl->InlineAsmDiagHandler = DiagHandler;
+ pImpl->InlineAsmDiagContext = DiagContext;
+}
+
+/// getInlineAsmDiagnosticHandler - Return the diagnostic handler set by
+/// setInlineAsmDiagnosticHandler.
+void *LLVMContext::getInlineAsmDiagnosticHandler() const {
+ return pImpl->InlineAsmDiagHandler;
+}
+
+/// getInlineAsmDiagnosticContext - Return the diagnostic context set by
+/// setInlineAsmDiagnosticHandler.
+void *LLVMContext::getInlineAsmDiagnosticContext() const {
+ return pImpl->InlineAsmDiagContext;
+}
+
+void LLVMContext::emitError(StringRef ErrorStr) {
+ emitError(0U, ErrorStr);
+}
+
+void LLVMContext::emitError(const Instruction *I, StringRef ErrorStr) {
+ unsigned LocCookie = 0;
+ if (const MDNode *SrcLoc = I->getMetadata("srcloc")) {
+ if (SrcLoc->getNumOperands() != 0)
+ if (const ConstantInt *CI = dyn_cast<ConstantInt>(SrcLoc->getOperand(0)))
+ LocCookie = CI->getZExtValue();
+ }
+ return emitError(LocCookie, ErrorStr);
+}
+
+void LLVMContext::emitError(unsigned LocCookie, StringRef ErrorStr) {
+ // If there is no error handler installed, just print the error and exit.
+ if (pImpl->InlineAsmDiagHandler == 0) {
+ errs() << "error: " << ErrorStr << "\n";
+ exit(1);
+ }
+
+ // If we do have an error handler, we can report the error and keep going.
+ SMDiagnostic Diag("", "error: " + ErrorStr.str());
+
+ ((SourceMgr::DiagHandlerTy)(intptr_t)pImpl->InlineAsmDiagHandler)
+ (Diag, pImpl->InlineAsmDiagContext, LocCookie);
+
}
+//===----------------------------------------------------------------------===//
+// Metadata Kind Uniquing
+//===----------------------------------------------------------------------===//
+
+#ifndef NDEBUG
+/// isValidName - Return true if Name is a valid custom metadata handler name.
+static bool isValidName(StringRef MDName) {
+ if (MDName.empty())
+ return false;
+
+ if (!isalpha(MDName[0]))
+ return false;
+
+ for (StringRef::iterator I = MDName.begin() + 1, E = MDName.end(); I != E;
+ ++I) {
+ if (!isalnum(*I) && *I != '_' && *I != '-' && *I != '.')
+ return false;
+ }
+ return true;
+}
+#endif
+
+/// getMDKindID - Return a unique non-zero ID for the specified metadata kind.
+unsigned LLVMContext::getMDKindID(StringRef Name) const {
+ assert(isValidName(Name) && "Invalid MDNode name");
+
+ unsigned &Entry = pImpl->CustomMDKindNames[Name];
+
+ // If this is new, assign it its ID.
+ if (Entry == 0) Entry = pImpl->CustomMDKindNames.size();
+ return Entry;
+}
+
+/// getHandlerNames - Populate client supplied smallvector using custome
+/// metadata name and ID.
+void LLVMContext::getMDKindNames(SmallVectorImpl<StringRef> &Names) const {
+ Names.resize(pImpl->CustomMDKindNames.size()+1);
+ Names[0] = "";
+ for (StringMap<unsigned>::const_iterator I = pImpl->CustomMDKindNames.begin(),
+ E = pImpl->CustomMDKindNames.end(); I != E; ++I)
+ // MD Handlers are numbered from 1.
+ Names[I->second] = I->first();
+}
diff --git a/lib/VMCore/LLVMContextImpl.cpp b/lib/VMCore/LLVMContextImpl.cpp
new file mode 100644
index 0000000..9e41a08
--- /dev/null
+++ b/lib/VMCore/LLVMContextImpl.cpp
@@ -0,0 +1,107 @@
+//===-- LLVMContextImpl.cpp - Implement LLVMContextImpl -------------------===//
+//
+// 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 opaque LLVMContextImpl.
+//
+//===----------------------------------------------------------------------===//
+
+#include "LLVMContextImpl.h"
+#include <algorithm>
+using namespace llvm;
+
+LLVMContextImpl::LLVMContextImpl(LLVMContext &C)
+ : TheTrueVal(0), TheFalseVal(0),
+ VoidTy(C, Type::VoidTyID),
+ LabelTy(C, Type::LabelTyID),
+ FloatTy(C, Type::FloatTyID),
+ DoubleTy(C, Type::DoubleTyID),
+ MetadataTy(C, Type::MetadataTyID),
+ X86_FP80Ty(C, Type::X86_FP80TyID),
+ FP128Ty(C, Type::FP128TyID),
+ PPC_FP128Ty(C, Type::PPC_FP128TyID),
+ Int1Ty(C, 1),
+ Int8Ty(C, 8),
+ Int16Ty(C, 16),
+ Int32Ty(C, 32),
+ Int64Ty(C, 64),
+ AlwaysOpaqueTy(new OpaqueType(C)) {
+ InlineAsmDiagHandler = 0;
+ InlineAsmDiagContext = 0;
+
+ // Make sure the AlwaysOpaqueTy stays alive as long as the Context.
+ AlwaysOpaqueTy->addRef();
+ OpaqueTypes.insert(AlwaysOpaqueTy);
+}
+
+namespace {
+struct DropReferences {
+ // Takes the value_type of a ConstantUniqueMap's internal map, whose 'second'
+ // is a Constant*.
+ template<typename PairT>
+ void operator()(const PairT &P) {
+ P.second->dropAllReferences();
+ }
+};
+}
+
+LLVMContextImpl::~LLVMContextImpl() {
+ std::for_each(ExprConstants.map_begin(), ExprConstants.map_end(),
+ DropReferences());
+ std::for_each(ArrayConstants.map_begin(), ArrayConstants.map_end(),
+ DropReferences());
+ std::for_each(StructConstants.map_begin(), StructConstants.map_end(),
+ DropReferences());
+ std::for_each(UnionConstants.map_begin(), UnionConstants.map_end(),
+ DropReferences());
+ std::for_each(VectorConstants.map_begin(), VectorConstants.map_end(),
+ DropReferences());
+ ExprConstants.freeConstants();
+ ArrayConstants.freeConstants();
+ StructConstants.freeConstants();
+ UnionConstants.freeConstants();
+ VectorConstants.freeConstants();
+ AggZeroConstants.freeConstants();
+ NullPtrConstants.freeConstants();
+ UndefValueConstants.freeConstants();
+ InlineAsms.freeConstants();
+ for (IntMapTy::iterator I = IntConstants.begin(), E = IntConstants.end();
+ I != E; ++I) {
+ delete I->second;
+ }
+ for (FPMapTy::iterator I = FPConstants.begin(), E = FPConstants.end();
+ I != E; ++I) {
+ delete I->second;
+ }
+ AlwaysOpaqueTy->dropRef();
+ for (OpaqueTypesTy::iterator I = OpaqueTypes.begin(), E = OpaqueTypes.end();
+ I != E; ++I) {
+ (*I)->AbstractTypeUsers.clear();
+ delete *I;
+ }
+ // Destroy MDNodes. ~MDNode can move and remove nodes between the MDNodeSet
+ // and the NonUniquedMDNodes sets, so copy the values out first.
+ SmallVector<MDNode*, 8> MDNodes;
+ MDNodes.reserve(MDNodeSet.size() + NonUniquedMDNodes.size());
+ for (FoldingSetIterator<MDNode> I = MDNodeSet.begin(), E = MDNodeSet.end();
+ I != E; ++I) {
+ MDNodes.push_back(&*I);
+ }
+ MDNodes.append(NonUniquedMDNodes.begin(), NonUniquedMDNodes.end());
+ for (SmallVector<MDNode*, 8>::iterator I = MDNodes.begin(),
+ E = MDNodes.end(); I != E; ++I) {
+ (*I)->destroy();
+ }
+ assert(MDNodeSet.empty() && NonUniquedMDNodes.empty() &&
+ "Destroying all MDNodes didn't empty the Context's sets.");
+ // Destroy MDStrings.
+ for (StringMap<MDString*>::iterator I = MDStringCache.begin(),
+ E = MDStringCache.end(); I != E; ++I) {
+ delete I->second;
+ }
+}
diff --git a/lib/VMCore/LLVMContextImpl.h b/lib/VMCore/LLVMContextImpl.h
index 9887f28..4876f5d 100644
--- a/lib/VMCore/LLVMContextImpl.h
+++ b/lib/VMCore/LLVMContextImpl.h
@@ -1,4 +1,4 @@
-//===-- LLVMContextImpl.h - The LLVMContextImpl opaque class --------------===//
+//===-- LLVMContextImpl.h - The LLVMContextImpl opaque class ----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -19,9 +19,9 @@
#include "LeaksContext.h"
#include "TypesContext.h"
#include "llvm/LLVMContext.h"
-#include "llvm/Metadata.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
+#include "llvm/Metadata.h"
#include "llvm/Assembly/Writer.h"
#include "llvm/Support/ValueHandle.h"
#include "llvm/ADT/APFloat.h"
@@ -36,8 +36,6 @@ namespace llvm {
class ConstantInt;
class ConstantFP;
-class MDString;
-class MDNode;
class LLVMContext;
class Type;
class Value;
@@ -92,8 +90,33 @@ struct DenseMapAPFloatKeyInfo {
}
};
+/// DebugRecVH - This is a CallbackVH used to keep the Scope -> index maps
+/// up to date as MDNodes mutate. This class is implemented in DebugLoc.cpp.
+class DebugRecVH : public CallbackVH {
+ /// Ctx - This is the LLVM Context being referenced.
+ LLVMContextImpl *Ctx;
+
+ /// Idx - The index into either ScopeRecordIdx or ScopeInlinedAtRecords that
+ /// this reference lives in. If this is zero, then it represents a
+ /// non-canonical entry that has no DenseMap value. This can happen due to
+ /// RAUW.
+ int Idx;
+public:
+ DebugRecVH(MDNode *n, LLVMContextImpl *ctx, int idx)
+ : CallbackVH(n), Ctx(ctx), Idx(idx) {}
+
+ MDNode *get() const {
+ return cast_or_null<MDNode>(getValPtr());
+ }
+
+ virtual void deleted();
+ virtual void allUsesReplacedWith(Value *VNew);
+};
+
class LLVMContextImpl {
public:
+ void *InlineAsmDiagHandler, *InlineAsmDiagContext;
+
typedef DenseMap<DenseMapAPIntKeyInfo::KeyTy, ConstantInt*,
DenseMapAPIntKeyInfo> IntMapTy;
IntMapTy IntConstants;
@@ -105,6 +128,11 @@ public:
StringMap<MDString*> MDStringCache;
FoldingSet<MDNode> MDNodeSet;
+ // MDNodes may be uniqued or not uniqued. When they're not uniqued, they
+ // aren't in the MDNodeSet, but they're still shared between objects, so no
+ // one object can destroy them. This set allows us to at least destroy them
+ // on Context destruction.
+ SmallPtrSet<MDNode*, 1> NonUniquedMDNodes;
ConstantUniqueMap<char, Type, ConstantAggregateZero> AggZeroConstants;
@@ -125,11 +153,12 @@ public:
VectorConstantsTy VectorConstants;
ConstantUniqueMap<char, PointerType, ConstantPointerNull> NullPtrConstants;
-
ConstantUniqueMap<char, Type, UndefValue> UndefValueConstants;
DenseMap<std::pair<Function*, BasicBlock*> , BlockAddress*> BlockAddresses;
ConstantUniqueMap<ExprMapKeyType, Type, ConstantExpr> ExprConstants;
+
+ ConstantUniqueMap<InlineAsmKeyType, PointerType, InlineAsm> InlineAsms;
ConstantInt *TheTrueVal;
ConstantInt *TheFalseVal;
@@ -190,68 +219,29 @@ public:
/// context.
DenseMap<const Instruction *, MDMapTy> MetadataStore;
+ /// ScopeRecordIdx - This is the index in ScopeRecords for an MDNode scope
+ /// entry with no "inlined at" element.
+ DenseMap<MDNode*, int> ScopeRecordIdx;
- LLVMContextImpl(LLVMContext &C) : TheTrueVal(0), TheFalseVal(0),
- VoidTy(C, Type::VoidTyID),
- LabelTy(C, Type::LabelTyID),
- FloatTy(C, Type::FloatTyID),
- DoubleTy(C, Type::DoubleTyID),
- MetadataTy(C, Type::MetadataTyID),
- X86_FP80Ty(C, Type::X86_FP80TyID),
- FP128Ty(C, Type::FP128TyID),
- PPC_FP128Ty(C, Type::PPC_FP128TyID),
- Int1Ty(C, 1),
- Int8Ty(C, 8),
- Int16Ty(C, 16),
- Int32Ty(C, 32),
- Int64Ty(C, 64),
- AlwaysOpaqueTy(new OpaqueType(C)) {
- // Make sure the AlwaysOpaqueTy stays alive as long as the Context.
- AlwaysOpaqueTy->addRef();
- OpaqueTypes.insert(AlwaysOpaqueTy);
- }
-
- ~LLVMContextImpl() {
- ExprConstants.freeConstants();
- ArrayConstants.freeConstants();
- StructConstants.freeConstants();
- VectorConstants.freeConstants();
- AggZeroConstants.freeConstants();
- NullPtrConstants.freeConstants();
- UndefValueConstants.freeConstants();
- for (IntMapTy::iterator I = IntConstants.begin(), E = IntConstants.end();
- I != E; ++I) {
- if (I->second->use_empty())
- delete I->second;
- }
- for (FPMapTy::iterator I = FPConstants.begin(), E = FPConstants.end();
- I != E; ++I) {
- if (I->second->use_empty())
- delete I->second;
- }
- AlwaysOpaqueTy->dropRef();
- for (OpaqueTypesTy::iterator I = OpaqueTypes.begin(), E = OpaqueTypes.end();
- I != E; ++I) {
- (*I)->AbstractTypeUsers.clear();
- delete *I;
- }
- // Destroy MDNode operands first.
- for (FoldingSetIterator<MDNode> I = MDNodeSet.begin(), E = MDNodeSet.end();
- I != E;) {
- MDNode *N = &(*I);
- ++I;
- N->replaceAllOperandsWithNull();
- }
- while (!MDNodeSet.empty()) {
- MDNode *N = &(*MDNodeSet.begin());
- N->destroy();
- }
- // Destroy MDStrings.
- for (StringMap<MDString*>::iterator I = MDStringCache.begin(),
- E = MDStringCache.end(); I != E; ++I) {
- delete I->second;
- }
- }
+ /// ScopeRecords - These are the actual mdnodes (in a value handle) for an
+ /// index. The ValueHandle ensures that ScopeRecordIdx stays up to date if
+ /// the MDNode is RAUW'd.
+ std::vector<DebugRecVH> ScopeRecords;
+
+ /// ScopeInlinedAtIdx - This is the index in ScopeInlinedAtRecords for an
+ /// scope/inlined-at pair.
+ DenseMap<std::pair<MDNode*, MDNode*>, int> ScopeInlinedAtIdx;
+
+ /// ScopeInlinedAtRecords - These are the actual mdnodes (in value handles)
+ /// for an index. The ValueHandle ensures that ScopeINlinedAtIdx stays up
+ /// to date.
+ std::vector<std::pair<DebugRecVH, DebugRecVH> > ScopeInlinedAtRecords;
+
+ int getOrAddScopeRecordIdxEntry(MDNode *N, int ExistingIdx);
+ int getOrAddScopeInlinedAtIdxEntry(MDNode *Scope, MDNode *IA,int ExistingIdx);
+
+ LLVMContextImpl(LLVMContext &C);
+ ~LLVMContextImpl();
};
}
diff --git a/lib/VMCore/LeaksContext.h b/lib/VMCore/LeaksContext.h
index abff090..b9e59d4 100644
--- a/lib/VMCore/LeaksContext.h
+++ b/lib/VMCore/LeaksContext.h
@@ -14,7 +14,8 @@
#include "llvm/Value.h"
#include "llvm/ADT/SmallPtrSet.h"
-using namespace llvm;
+
+namespace llvm {
template <class T>
struct PrinterTrait {
@@ -87,3 +88,5 @@ private:
const T* Cache;
const char* Name;
};
+
+}
diff --git a/lib/VMCore/Makefile b/lib/VMCore/Makefile
index 4395ecf..03a4fc7 100644
--- a/lib/VMCore/Makefile
+++ b/lib/VMCore/Makefile
@@ -1,4 +1,4 @@
-##===- lib/VMCore/Makefile ------------------------------*- Makefile -*-===##
+##===- lib/VMCore/Makefile ---------------------------------*- Makefile -*-===##
#
# The LLVM Compiler Infrastructure
#
diff --git a/lib/VMCore/Metadata.cpp b/lib/VMCore/Metadata.cpp
index a08c454..72de032 100644
--- a/lib/VMCore/Metadata.cpp
+++ b/lib/VMCore/Metadata.cpp
@@ -39,15 +39,6 @@ MDString *MDString::get(LLVMContext &Context, StringRef Str) {
return S;
}
-MDString *MDString::get(LLVMContext &Context, const char *Str) {
- LLVMContextImpl *pImpl = Context.pImpl;
- StringMapEntry<MDString *> &Entry =
- pImpl->MDStringCache.GetOrCreateValue(Str ? StringRef(Str) : StringRef());
- MDString *&S = Entry.getValue();
- if (!S) S = new MDString(Context, Entry.getKey());
- return S;
-}
-
//===----------------------------------------------------------------------===//
// MDNodeOperand implementation.
//
@@ -110,8 +101,10 @@ MDNode::MDNode(LLVMContext &C, Value *const *Vals, unsigned NumVals,
MDNode::~MDNode() {
assert((getSubclassDataFromValue() & DestroyFlag) != 0 &&
"Not being destroyed through destroy()?");
- if (!isNotUniqued()) {
- LLVMContextImpl *pImpl = getType()->getContext().pImpl;
+ LLVMContextImpl *pImpl = getType()->getContext().pImpl;
+ if (isNotUniqued()) {
+ pImpl->NonUniquedMDNodes.erase(this);
+ } else {
pImpl->MDNodeSet.RemoveNode(this);
}
@@ -189,19 +182,6 @@ MDNode *MDNode::getMDNode(LLVMContext &Context, Value *const *Vals,
unsigned NumVals, FunctionLocalness FL,
bool Insert) {
LLVMContextImpl *pImpl = Context.pImpl;
- FoldingSetNodeID ID;
- for (unsigned i = 0; i != NumVals; ++i)
- ID.AddPointer(Vals[i]);
-
- void *InsertPoint;
- MDNode *N = NULL;
-
- if ((N = pImpl->MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint)))
- return N;
-
- if (!Insert)
- return NULL;
-
bool isFunctionLocal = false;
switch (FL) {
case FL_Unknown:
@@ -223,6 +203,20 @@ MDNode *MDNode::getMDNode(LLVMContext &Context, Value *const *Vals,
break;
}
+ FoldingSetNodeID ID;
+ for (unsigned i = 0; i != NumVals; ++i)
+ ID.AddPointer(Vals[i]);
+ ID.AddBoolean(isFunctionLocal);
+
+ void *InsertPoint;
+ MDNode *N = NULL;
+
+ if ((N = pImpl->MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint)))
+ return N;
+
+ if (!Insert)
+ return NULL;
+
// Coallocate space for the node and Operands together, then placement new.
void *Ptr = malloc(sizeof(MDNode)+NumVals*sizeof(MDNodeOperand));
N = new (Ptr) MDNode(Context, Vals, NumVals, isFunctionLocal);
@@ -255,14 +249,13 @@ Value *MDNode::getOperand(unsigned i) const {
void MDNode::Profile(FoldingSetNodeID &ID) const {
for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
ID.AddPointer(getOperand(i));
+ ID.AddBoolean(isFunctionLocal());
}
-// replaceAllOperandsWithNull - This is used while destroying llvm context to
-// gracefully delete all nodes. This method replaces all operands with null.
-void MDNode::replaceAllOperandsWithNull() {
- for (MDNodeOperand *Op = getOperandPtr(this, 0), *E = Op+NumOperands;
- Op != E; ++Op)
- replaceOperand(Op, 0);
+void MDNode::setIsNotUniqued() {
+ setValueSubclassData(getSubclassDataFromValue() | NotUniquedBit);
+ LLVMContextImpl *pImpl = getType()->getContext().pImpl;
+ pImpl->NonUniquedMDNodes.insert(this);
}
// Replace value from this node's operand list.
@@ -419,50 +412,6 @@ StringRef NamedMDNode::getName() const {
}
//===----------------------------------------------------------------------===//
-// LLVMContext MDKind naming implementation.
-//
-
-#ifndef NDEBUG
-/// isValidName - Return true if Name is a valid custom metadata handler name.
-static bool isValidName(StringRef MDName) {
- if (MDName.empty())
- return false;
-
- if (!isalpha(MDName[0]))
- return false;
-
- for (StringRef::iterator I = MDName.begin() + 1, E = MDName.end(); I != E;
- ++I) {
- if (!isalnum(*I) && *I != '_' && *I != '-' && *I != '.')
- return false;
- }
- return true;
-}
-#endif
-
-/// getMDKindID - Return a unique non-zero ID for the specified metadata kind.
-unsigned LLVMContext::getMDKindID(StringRef Name) const {
- assert(isValidName(Name) && "Invalid MDNode name");
-
- unsigned &Entry = pImpl->CustomMDKindNames[Name];
-
- // If this is new, assign it its ID.
- if (Entry == 0) Entry = pImpl->CustomMDKindNames.size();
- return Entry;
-}
-
-/// getHandlerNames - Populate client supplied smallvector using custome
-/// metadata name and ID.
-void LLVMContext::getMDKindNames(SmallVectorImpl<StringRef> &Names) const {
- Names.resize(pImpl->CustomMDKindNames.size()+1);
- Names[0] = "";
- for (StringMap<unsigned>::const_iterator I = pImpl->CustomMDKindNames.begin(),
- E = pImpl->CustomMDKindNames.end(); I != E; ++I)
- // MD Handlers are numbered from 1.
- Names[I->second] = I->first();
-}
-
-//===----------------------------------------------------------------------===//
// Instruction Metadata method implementations.
//
@@ -475,18 +424,29 @@ MDNode *Instruction::getMetadataImpl(const char *Kind) const {
return getMetadataImpl(getContext().getMDKindID(Kind));
}
+void Instruction::setDbgMetadata(MDNode *Node) {
+ DbgLoc = DebugLoc::getFromDILocation(Node);
+}
+
/// setMetadata - Set the metadata of of the specified kind to the specified
/// node. This updates/replaces metadata if already present, or removes it if
/// Node is null.
void Instruction::setMetadata(unsigned KindID, MDNode *Node) {
if (Node == 0 && !hasMetadata()) return;
+ // Handle 'dbg' as a special case since it is not stored in the hash table.
+ if (KindID == LLVMContext::MD_dbg) {
+ DbgLoc = DebugLoc::getFromDILocation(Node);
+ return;
+ }
+
// Handle the case when we're adding/updating metadata on an instruction.
if (Node) {
LLVMContextImpl::MDMapTy &Info = getContext().pImpl->MetadataStore[this];
- assert(!Info.empty() == hasMetadata() && "HasMetadata bit is wonked");
+ assert(!Info.empty() == hasMetadataHashEntry() &&
+ "HasMetadata bit is wonked");
if (Info.empty()) {
- setHasMetadata(true);
+ setHasMetadataHashEntry(true);
} else {
// Handle replacement of an existing value.
for (unsigned i = 0, e = Info.size(); i != e; ++i)
@@ -502,18 +462,19 @@ void Instruction::setMetadata(unsigned KindID, MDNode *Node) {
}
// Otherwise, we're removing metadata from an instruction.
- assert(hasMetadata() && getContext().pImpl->MetadataStore.count(this) &&
+ assert(hasMetadataHashEntry() &&
+ getContext().pImpl->MetadataStore.count(this) &&
"HasMetadata bit out of date!");
LLVMContextImpl::MDMapTy &Info = getContext().pImpl->MetadataStore[this];
// Common case is removing the only entry.
if (Info.size() == 1 && Info[0].first == KindID) {
getContext().pImpl->MetadataStore.erase(this);
- setHasMetadata(false);
+ setHasMetadataHashEntry(false);
return;
}
- // Handle replacement of an existing value.
+ // Handle removal of an existing value.
for (unsigned i = 0, e = Info.size(); i != e; ++i)
if (Info[i].first == KindID) {
Info[i] = Info.back();
@@ -525,8 +486,14 @@ void Instruction::setMetadata(unsigned KindID, MDNode *Node) {
}
MDNode *Instruction::getMetadataImpl(unsigned KindID) const {
+ // Handle 'dbg' as a special case since it is not stored in the hash table.
+ if (KindID == LLVMContext::MD_dbg)
+ return DbgLoc.getAsMDNode(getContext());
+
+ if (!hasMetadataHashEntry()) return 0;
+
LLVMContextImpl::MDMapTy &Info = getContext().pImpl->MetadataStore[this];
- assert(hasMetadata() && !Info.empty() && "Shouldn't have called this");
+ assert(!Info.empty() && "bit out of sync with hash table");
for (LLVMContextImpl::MDMapTy::iterator I = Info.begin(), E = Info.end();
I != E; ++I)
@@ -536,14 +503,23 @@ MDNode *Instruction::getMetadataImpl(unsigned KindID) const {
}
void Instruction::getAllMetadataImpl(SmallVectorImpl<std::pair<unsigned,
- MDNode*> > &Result)const {
- assert(hasMetadata() && getContext().pImpl->MetadataStore.count(this) &&
+ MDNode*> > &Result) const {
+ Result.clear();
+
+ // Handle 'dbg' as a special case since it is not stored in the hash table.
+ if (!DbgLoc.isUnknown()) {
+ Result.push_back(std::make_pair((unsigned)LLVMContext::MD_dbg,
+ DbgLoc.getAsMDNode(getContext())));
+ if (!hasMetadataHashEntry()) return;
+ }
+
+ assert(hasMetadataHashEntry() &&
+ getContext().pImpl->MetadataStore.count(this) &&
"Shouldn't have called this");
const LLVMContextImpl::MDMapTy &Info =
getContext().pImpl->MetadataStore.find(this)->second;
assert(!Info.empty() && "Shouldn't have called this");
- Result.clear();
Result.append(Info.begin(), Info.end());
// Sort the resulting array so it is stable.
@@ -551,10 +527,32 @@ void Instruction::getAllMetadataImpl(SmallVectorImpl<std::pair<unsigned,
array_pod_sort(Result.begin(), Result.end());
}
+void Instruction::
+getAllMetadataOtherThanDebugLocImpl(SmallVectorImpl<std::pair<unsigned,
+ MDNode*> > &Result) const {
+ Result.clear();
+ assert(hasMetadataHashEntry() &&
+ getContext().pImpl->MetadataStore.count(this) &&
+ "Shouldn't have called this");
+ const LLVMContextImpl::MDMapTy &Info =
+ getContext().pImpl->MetadataStore.find(this)->second;
+ assert(!Info.empty() && "Shouldn't have called this");
+
+ Result.append(Info.begin(), Info.end());
+
+ // Sort the resulting array so it is stable.
+ if (Result.size() > 1)
+ array_pod_sort(Result.begin(), Result.end());
+}
+
+
/// removeAllMetadata - Remove all metadata from this instruction.
void Instruction::removeAllMetadata() {
assert(hasMetadata() && "Caller should check");
- getContext().pImpl->MetadataStore.erase(this);
- setHasMetadata(false);
+ DbgLoc = DebugLoc();
+ if (hasMetadataHashEntry()) {
+ getContext().pImpl->MetadataStore.erase(this);
+ setHasMetadataHashEntry(false);
+ }
}
diff --git a/lib/VMCore/Module.cpp b/lib/VMCore/Module.cpp
index 001bb00..94840f0 100644
--- a/lib/VMCore/Module.cpp
+++ b/lib/VMCore/Module.cpp
@@ -82,7 +82,7 @@ Module::Endianness Module::getEndianness() const {
while (!temp.empty()) {
StringRef token = DataLayout;
- tie(token, temp) = getToken(DataLayout, "-");
+ tie(token, temp) = getToken(temp, "-");
if (token[0] == 'e') {
ret = LittleEndian;
diff --git a/lib/VMCore/Pass.cpp b/lib/VMCore/Pass.cpp
index a782e5a..a60877d 100644
--- a/lib/VMCore/Pass.cpp
+++ b/lib/VMCore/Pass.cpp
@@ -18,6 +18,7 @@
#include "llvm/Module.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringMap.h"
+#include "llvm/Assembly/PrintModulePass.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/PassNameParser.h"
@@ -42,6 +43,11 @@ Pass::~Pass() {
// Force out-of-line virtual method.
ModulePass::~ModulePass() { }
+Pass *ModulePass::createPrinterPass(raw_ostream &O,
+ const std::string &Banner) const {
+ return createPrintModulePass(&O, false, Banner);
+}
+
PassManagerType ModulePass::getPotentialPassManagerType() const {
return PMT_ModulePassManager;
}
@@ -113,6 +119,11 @@ void ImmutablePass::initializePass() {
// FunctionPass Implementation
//
+Pass *FunctionPass::createPrinterPass(raw_ostream &O,
+ const std::string &Banner) const {
+ return createPrintFunctionPass(Banner, &O);
+}
+
// run - On a module, we run this pass by initializing, runOnFunction'ing once
// for every function in the module, then by finalizing.
//
@@ -155,6 +166,13 @@ PassManagerType FunctionPass::getPotentialPassManagerType() const {
// BasicBlockPass Implementation
//
+Pass *BasicBlockPass::createPrinterPass(raw_ostream &O,
+ const std::string &Banner) const {
+
+ llvm_unreachable("BasicBlockPass printing unsupported.");
+ return 0;
+}
+
// To run this pass on a function, we simply call runOnBasicBlock once for each
// function.
//
@@ -276,13 +294,8 @@ public:
static std::vector<PassRegistrationListener*> *Listeners = 0;
static sys::SmartMutex<true> ListenersLock;
-// FIXME: This should use ManagedStatic to manage the pass registrar.
-// Unfortunately, we can't do this, because passes are registered with static
-// ctors, and having llvm_shutdown clear this map prevents successful
-// ressurection after llvm_shutdown is run.
+static PassRegistrar *PassRegistrarObj = 0;
static PassRegistrar *getPassRegistrar() {
- static PassRegistrar *PassRegistrarObj = 0;
-
// Use double-checked locking to safely initialize the registrar when
// we're running in multithreaded mode.
PassRegistrar* tmp = PassRegistrarObj;
@@ -305,6 +318,23 @@ static PassRegistrar *getPassRegistrar() {
return PassRegistrarObj;
}
+namespace {
+
+// FIXME: We use ManagedCleanup to erase the pass registrar on shutdown.
+// Unfortunately, passes are registered with static ctors, and having
+// llvm_shutdown clear this map prevents successful ressurection after
+// llvm_shutdown is run. Ideally we should find a solution so that we don't
+// leak the map, AND can still resurrect after shutdown.
+void cleanupPassRegistrar(void*) {
+ if (PassRegistrarObj) {
+ delete PassRegistrarObj;
+ PassRegistrarObj = 0;
+ }
+}
+ManagedCleanup<&cleanupPassRegistrar> registrarCleanup ATTRIBUTE_USED;
+
+}
+
// getPassInfo - Return the PassInfo data structure that corresponds to this
// pass...
const PassInfo *Pass::getPassInfo() const {
diff --git a/lib/VMCore/PassManager.cpp b/lib/VMCore/PassManager.cpp
index c4dfe14..b28fdeb 100644
--- a/lib/VMCore/PassManager.cpp
+++ b/lib/VMCore/PassManager.cpp
@@ -13,6 +13,7 @@
#include "llvm/PassManagers.h"
+#include "llvm/Assembly/PrintModulePass.h"
#include "llvm/Assembly/Writer.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
@@ -20,6 +21,7 @@
#include "llvm/Module.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/PassNameParser.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/System/Mutex.h"
#include "llvm/System/Threading.h"
@@ -55,6 +57,57 @@ PassDebugging("debug-pass", cl::Hidden,
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"));
+
+static PassOptionList
+PrintAfter("print-after",
+ llvm::cl::desc("Print IR after specified passes"));
+
+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(Pass *P,
+ PassOptionList &PassesToPrint) {
+ for (unsigned i = 0, ie = PassesToPrint.size(); i < ie; ++i) {
+ const llvm::PassInfo *PassInf = PassesToPrint[i];
+ if (PassInf && P->getPassInfo())
+ if (PassInf->getPassArgument() ==
+ P->getPassInfo()->getPassArgument()) {
+ return true;
+ }
+ }
+ return false;
+}
+
+
+/// This is a utility to check whether a pass should have IR dumped
+/// before it.
+static bool ShouldPrintBeforePass(Pass *P) {
+ return PrintBeforeAll || ShouldPrintBeforeOrAfterPass(P, PrintBefore);
+}
+
+/// This is a utility to check whether a pass should have IR dumped
+/// after it.
+static bool ShouldPrintAfterPass(Pass *P) {
+ return PrintAfterAll || ShouldPrintBeforeOrAfterPass(P, PrintAfter);
+}
+
} // End of llvm namespace
/// isPassDebuggingExecutionsOrMore - Return true if -debug-pass=Executions
@@ -182,6 +235,11 @@ public:
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();
@@ -252,6 +310,11 @@ public:
}
}
+ /// 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);
@@ -331,6 +394,11 @@ public:
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);
@@ -378,17 +446,19 @@ namespace {
static ManagedStatic<sys::SmartMutex<true> > TimingInfoMutex;
class TimingInfo {
- std::map<Pass*, Timer> TimingData;
+ 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...
- TimingData.clear();
+ // 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.
}
@@ -397,18 +467,15 @@ public:
// null. It may be called multiple times.
static void createTheTimeInfo();
- /// passStarted - This method creates a timer for the given pass if it doesn't
- /// already have one, and starts the timer.
- Timer *passStarted(Pass *P) {
+ /// 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);
- std::map<Pass*, Timer>::iterator I = TimingData.find(P);
- if (I == TimingData.end())
- I=TimingData.insert(std::make_pair(P, Timer(P->getPassName(), TG))).first;
- Timer *T = &I->second;
- T->startTimer();
+ Timer *&T = TimingData[P];
+ if (T == 0)
+ T = new Timer(P->getPassName(), TG);
return T;
}
};
@@ -704,11 +771,8 @@ void PMDataManager::verifyPreservedAnalysis(Pass *P) {
E = PreservedSet.end(); I != E; ++I) {
AnalysisID AID = *I;
if (Pass *AP = findAnalysisPass(AID, true)) {
-
- Timer *T = 0;
- if (TheTimeInfo) T = TheTimeInfo->passStarted(AP);
+ TimeRegion PassTimer(getPassTimer(AP));
AP->verifyAnalysis();
- if (T) T->stopTimer();
}
}
}
@@ -792,10 +856,9 @@ void PMDataManager::freePass(Pass *P, StringRef Msg,
{
// If the pass crashes releasing memory, remember this.
PassManagerPrettyStackEntry X(P);
-
- Timer *T = StartPassTimer(P);
+ TimeRegion PassTimer(getPassTimer(P));
+
P->releaseMemory();
- StopPassTimer(P, T);
}
if (const PassInfo *PI = P->getPassInfo()) {
@@ -1128,10 +1191,9 @@ bool BBPassManager::runOnFunction(Function &F) {
{
// If the pass crashes, remember this.
PassManagerPrettyStackEntry X(BP, *I);
-
- Timer *T = StartPassTimer(BP);
+ TimeRegion PassTimer(getPassTimer(BP));
+
LocalChanged |= BP->runOnBasicBlock(*I);
- StopPassTimer(BP, T);
}
Changed |= LocalChanged;
@@ -1214,7 +1276,14 @@ FunctionPassManager::~FunctionPassManager() {
/// 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) {
+ if (ShouldPrintBeforePass(P))
+ add(P->createPrinterPass(dbgs(), std::string("*** IR Dump Before ")
+ + P->getPassName() + " ***"));
FPM->add(P);
+
+ if (ShouldPrintAfterPass(P))
+ add(P->createPrinterPass(dbgs(), std::string("*** IR Dump After ")
+ + P->getPassName() + " ***"));
}
/// run - Execute all of the passes scheduled for execution. Keep
@@ -1224,9 +1293,8 @@ void FunctionPassManager::add(Pass *P) {
bool FunctionPassManager::run(Function &F) {
if (F.isMaterializable()) {
std::string errstr;
- if (F.Materialize(&errstr)) {
- llvm_report_error("Error reading bitcode file: " + errstr);
- }
+ if (F.Materialize(&errstr))
+ report_fatal_error("Error reading bitcode file: " + Twine(errstr));
}
return FPM->run(F);
}
@@ -1345,10 +1413,9 @@ bool FPPassManager::runOnFunction(Function &F) {
{
PassManagerPrettyStackEntry X(FP, F);
+ TimeRegion PassTimer(getPassTimer(FP));
- Timer *T = StartPassTimer(FP);
LocalChanged |= FP->runOnFunction(F);
- StopPassTimer(FP, T);
}
Changed |= LocalChanged;
@@ -1420,9 +1487,9 @@ MPPassManager::runOnModule(Module &M) {
{
PassManagerPrettyStackEntry X(MP, M);
- Timer *T = StartPassTimer(MP);
+ TimeRegion PassTimer(getPassTimer(MP));
+
LocalChanged |= MP->runOnModule(M);
- StopPassTimer(MP, T);
}
Changed |= LocalChanged;
@@ -1526,7 +1593,15 @@ PassManager::~PassManager() {
/// 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) {
+ if (ShouldPrintBeforePass(P))
+ add(P->createPrinterPass(dbgs(), std::string("*** IR Dump Before ")
+ + P->getPassName() + " ***"));
+
PM->add(P);
+
+ if (ShouldPrintAfterPass(P))
+ add(P->createPrinterPass(dbgs(), std::string("*** IR Dump After ")
+ + P->getPassName() + " ***"));
}
/// run - Execute all of the passes scheduled for execution. Keep track of
@@ -1559,17 +1634,12 @@ void TimingInfo::createTheTimeInfo() {
}
/// If TimingInfo is enabled then start pass timer.
-Timer *llvm::StartPassTimer(Pass *P) {
+Timer *llvm::getPassTimer(Pass *P) {
if (TheTimeInfo)
- return TheTimeInfo->passStarted(P);
+ return TheTimeInfo->getPassTimer(P);
return 0;
}
-/// If TimingInfo is enabled then stop pass timer.
-void llvm::StopPassTimer(Pass *P, Timer *T) {
- if (T) T->stopTimer();
-}
-
//===----------------------------------------------------------------------===//
// PMStack implementation
//
diff --git a/lib/VMCore/PrintModulePass.cpp b/lib/VMCore/PrintModulePass.cpp
index f0f6e7a..2d69dce 100644
--- a/lib/VMCore/PrintModulePass.cpp
+++ b/lib/VMCore/PrintModulePass.cpp
@@ -23,21 +23,22 @@ using namespace llvm;
namespace {
class PrintModulePass : public ModulePass {
+ std::string Banner;
raw_ostream *Out; // raw_ostream to print on
bool DeleteStream; // Delete the ostream in our dtor?
public:
static char ID;
PrintModulePass() : ModulePass(&ID), Out(&dbgs()),
DeleteStream(false) {}
- PrintModulePass(raw_ostream *o, bool DS)
- : ModulePass(&ID), Out(o), DeleteStream(DS) {}
+ PrintModulePass(const std::string &B, raw_ostream *o, bool DS)
+ : ModulePass(&ID), Banner(B), Out(o), DeleteStream(DS) {}
~PrintModulePass() {
if (DeleteStream) delete Out;
}
bool runOnModule(Module &M) {
- (*Out) << M;
+ (*Out) << Banner << M;
return false;
}
@@ -85,8 +86,9 @@ Y("print-function","Print function to stderr");
/// createPrintModulePass - Create and return a pass that writes the
/// module to the specified raw_ostream.
ModulePass *llvm::createPrintModulePass(llvm::raw_ostream *OS,
- bool DeleteStream) {
- return new PrintModulePass(OS, DeleteStream);
+ bool DeleteStream,
+ const std::string &Banner) {
+ return new PrintModulePass(Banner, OS, DeleteStream);
}
/// createPrintFunctionPass - Create and return a pass that prints
diff --git a/lib/VMCore/Type.cpp b/lib/VMCore/Type.cpp
index 9b2c2ca..845b523 100644
--- a/lib/VMCore/Type.cpp
+++ b/lib/VMCore/Type.cpp
@@ -57,6 +57,11 @@ void AbstractTypeUser::setType(Value *V, const Type *NewTy) {
/// need for a std::vector to be used in the Type class itself.
/// @brief Type destruction function
void Type::destroy() const {
+ // Nothing calls getForwardedType from here on.
+ if (ForwardType && ForwardType->isAbstract()) {
+ ForwardType->dropRef();
+ ForwardType = NULL;
+ }
// Structures and Functions allocate their contained types past the end of
// the type object itself. These need to be destroyed differently than the
@@ -254,10 +259,12 @@ const Type *Type::getForwardedTypeInternal() const {
// Yes, it is forwarded again. First thing, add the reference to the new
// forward type.
if (RealForwardedType->isAbstract())
- cast<DerivedType>(RealForwardedType)->addRef();
+ RealForwardedType->addRef();
// Now drop the old reference. This could cause ForwardType to get deleted.
- cast<DerivedType>(ForwardType)->dropRef();
+ // ForwardType must be abstract because only abstract types can have their own
+ // ForwardTypes.
+ ForwardType->dropRef();
// Return the updated type.
ForwardType = RealForwardedType;
@@ -373,6 +380,10 @@ const Type *Type::getPPC_FP128Ty(LLVMContext &C) {
return &C.pImpl->PPC_FP128Ty;
}
+const IntegerType *Type::getIntNTy(LLVMContext &C, unsigned N) {
+ return IntegerType::get(C, N);
+}
+
const IntegerType *Type::getInt1Ty(LLVMContext &C) {
return &C.pImpl->Int1Ty;
}
@@ -413,6 +424,10 @@ const PointerType *Type::getPPC_FP128PtrTy(LLVMContext &C, unsigned AS) {
return getPPC_FP128Ty(C)->getPointerTo(AS);
}
+const PointerType *Type::getIntNPtrTy(LLVMContext &C, unsigned N, unsigned AS) {
+ return getIntNTy(C, N)->getPointerTo(AS);
+}
+
const PointerType *Type::getInt1PtrTy(LLVMContext &C, unsigned AS) {
return getInt1Ty(C)->getPointerTo(AS);
}
@@ -1142,8 +1157,8 @@ void DerivedType::unlockedRefineAbstractTypeTo(const Type *NewType) {
// Any PATypeHolders referring to this type will now automatically forward to
// the type we are resolved to.
ForwardType = NewType;
- if (NewType->isAbstract())
- cast<DerivedType>(NewType)->addRef();
+ if (ForwardType->isAbstract())
+ ForwardType->addRef();
// Add a self use of the current type so that we don't delete ourself until
// after the function exits.
diff --git a/lib/VMCore/TypeSymbolTable.cpp b/lib/VMCore/TypeSymbolTable.cpp
index b4daf0f..d68a44b 100644
--- a/lib/VMCore/TypeSymbolTable.cpp
+++ b/lib/VMCore/TypeSymbolTable.cpp
@@ -126,13 +126,15 @@ void TypeSymbolTable::refineAbstractType(const DerivedType *OldType,
// faster to remove them all in one pass.
//
for (iterator I = begin(), E = end(); I != E; ++I) {
- if (I->second == (Type*)OldType) { // FIXME when Types aren't const.
+ // FIXME when Types aren't const.
+ if (I->second == const_cast<DerivedType *>(OldType)) {
#if DEBUG_ABSTYPE
dbgs() << "Removing type " << OldType->getDescription() << "\n";
#endif
OldType->removeAbstractTypeUser(this);
- I->second = (Type*)NewType; // TODO FIXME when types aren't const
+ // TODO FIXME when types aren't const
+ I->second = const_cast<Type *>(NewType);
if (NewType->isAbstract()) {
#if DEBUG_ABSTYPE
dbgs() << "Added type " << NewType->getDescription() << "\n";
diff --git a/lib/VMCore/Value.cpp b/lib/VMCore/Value.cpp
index a36d262..645dd5a 100644
--- a/lib/VMCore/Value.cpp
+++ b/lib/VMCore/Value.cpp
@@ -86,7 +86,7 @@ Value::~Value() {
/// hasNUses - Return true if this Value has exactly N users.
///
bool Value::hasNUses(unsigned N) const {
- use_const_iterator UI = use_begin(), E = use_end();
+ const_use_iterator UI = use_begin(), E = use_end();
for (; N; --N, ++UI)
if (UI == E) return false; // Too few.
@@ -97,7 +97,7 @@ bool Value::hasNUses(unsigned N) const {
/// logically equivalent to getNumUses() >= N.
///
bool Value::hasNUsesOrMore(unsigned N) const {
- use_const_iterator UI = use_begin(), E = use_end();
+ const_use_iterator UI = use_begin(), E = use_end();
for (; N; --N, ++UI)
if (UI == E) return false; // Too few.
@@ -108,7 +108,7 @@ bool Value::hasNUsesOrMore(unsigned N) const {
/// isUsedInBasicBlock - Return true if this value is used in the specified
/// basic block.
bool Value::isUsedInBasicBlock(const BasicBlock *BB) const {
- for (use_const_iterator I = use_begin(), E = use_end(); I != E; ++I) {
+ for (const_use_iterator I = use_begin(), E = use_end(); I != E; ++I) {
const Instruction *User = dyn_cast<Instruction>(*I);
if (User && User->getParent() == BB)
return true;
diff --git a/lib/VMCore/ValueSymbolTable.cpp b/lib/VMCore/ValueSymbolTable.cpp
index d30a9d6..449d61a 100644
--- a/lib/VMCore/ValueSymbolTable.cpp
+++ b/lib/VMCore/ValueSymbolTable.cpp
@@ -55,9 +55,7 @@ void ValueSymbolTable::reinsertValue(Value* V) {
raw_svector_ostream(UniqueName) << ++LastUnique;
// Try insert the vmap entry with this suffix.
- ValueName &NewName =
- vmap.GetOrCreateValue(StringRef(UniqueName.data(),
- UniqueName.size()));
+ ValueName &NewName = vmap.GetOrCreateValue(UniqueName);
if (NewName.getValue() == 0) {
// Newly inserted name. Success!
NewName.setValue(V);
@@ -88,7 +86,7 @@ ValueName *ValueSymbolTable::createValueName(StringRef Name, Value *V) {
}
// Otherwise, there is a naming conflict. Rename this value.
- SmallString<128> UniqueName(Name.begin(), Name.end());
+ SmallString<256> UniqueName(Name.begin(), Name.end());
while (1) {
// Trim any suffix off and append the next number.
@@ -96,9 +94,7 @@ ValueName *ValueSymbolTable::createValueName(StringRef Name, Value *V) {
raw_svector_ostream(UniqueName) << ++LastUnique;
// Try insert the vmap entry with this suffix.
- ValueName &NewName =
- vmap.GetOrCreateValue(StringRef(UniqueName.data(),
- UniqueName.size()));
+ ValueName &NewName = vmap.GetOrCreateValue(UniqueName);
if (NewName.getValue() == 0) {
// Newly inserted name. Success!
NewName.setValue(V);
diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp
index 721e96a..daf74bf 100644
--- a/lib/VMCore/Verifier.cpp
+++ b/lib/VMCore/Verifier.cpp
@@ -93,7 +93,7 @@ namespace { // Anonymous namespace for class
}
if (Broken)
- llvm_report_error("Broken module, no Basic Block terminator!");
+ report_fatal_error("Broken module, no Basic Block terminator!");
return false;
}
@@ -676,17 +676,13 @@ void Verifier::visitFunction(Function &F) {
"blockaddress may not be used with the entry block!", Entry);
}
}
-
+
// If this function is actually an intrinsic, verify that it is only used in
// direct call/invokes, never having its "address taken".
if (F.getIntrinsicID()) {
- for (Value::use_iterator UI = F.use_begin(), E = F.use_end(); UI != E;++UI){
- User *U = cast<User>(UI);
- if ((isa<CallInst>(U) || isa<InvokeInst>(U)) && UI.getOperandNo() == 0)
- continue; // Direct calls/invokes are ok.
-
+ const User *U;
+ if (F.hasAddressTaken(&U))
Assert1(0, "Invalid user of intrinsic instruction!", U);
- }
}
}
@@ -1483,7 +1479,7 @@ void Verifier::visitInstruction(Instruction &I) {
"Instruction does not dominate all uses!", Op, &I);
}
} else if (isa<InlineAsm>(I.getOperand(i))) {
- Assert1(i == 0 && (isa<CallInst>(I) || isa<InvokeInst>(I)),
+ Assert1((i == 0 && isa<CallInst>(I)) || (i + 3 == e && isa<InvokeInst>(I)),
"Cannot take the address of an inline asm!", &I);
}
}
@@ -1623,10 +1619,6 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) {
MDNode *MD = cast<MDNode>(CI.getOperand(1));
Assert1(MD->getNumOperands() == 1,
"invalid llvm.dbg.declare intrinsic call 2", &CI);
- if (MD->getOperand(0))
- if (Constant *C = dyn_cast<Constant>(MD->getOperand(0)))
- Assert1(C && !isa<ConstantPointerNull>(C),
- "invalid llvm.dbg.declare intrinsic call 3", &CI);
} break;
case Intrinsic::memcpy:
case Intrinsic::memmove:
@@ -1687,13 +1679,11 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) {
/// parameters beginning with NumRets.
///
static std::string IntrinsicParam(unsigned ArgNo, unsigned NumRets) {
- if (ArgNo < NumRets) {
- if (NumRets == 1)
- return "Intrinsic result type";
- else
- return "Intrinsic result type #" + utostr(ArgNo);
- } else
+ if (ArgNo >= NumRets)
return "Intrinsic parameter #" + utostr(ArgNo - NumRets);
+ if (NumRets == 1)
+ return "Intrinsic result type";
+ return "Intrinsic result type #" + utostr(ArgNo);
}
bool Verifier::PerformTypeCheck(Intrinsic::ID ID, Function *F, const Type *Ty,
@@ -1710,9 +1700,13 @@ bool Verifier::PerformTypeCheck(Intrinsic::ID ID, Function *F, const Type *Ty,
const Type *RetTy = FTy->getReturnType();
const StructType *ST = dyn_cast<StructType>(RetTy);
- unsigned NumRets = 1;
- if (ST)
- NumRets = ST->getNumElements();
+ unsigned NumRetVals;
+ if (RetTy->isVoidTy())
+ NumRetVals = 0;
+ else if (ST)
+ NumRetVals = ST->getNumElements();
+ else
+ NumRetVals = 1;
if (VT < 0) {
int Match = ~VT;
@@ -1724,7 +1718,7 @@ bool Verifier::PerformTypeCheck(Intrinsic::ID ID, Function *F, const Type *Ty,
TruncatedElementVectorType)) != 0) {
const IntegerType *IEltTy = dyn_cast<IntegerType>(EltTy);
if (!VTy || !IEltTy) {
- CheckFailed(IntrinsicParam(ArgNo, NumRets) + " is not "
+ CheckFailed(IntrinsicParam(ArgNo, NumRetVals) + " is not "
"an integral vector type.", F);
return false;
}
@@ -1732,7 +1726,7 @@ bool Verifier::PerformTypeCheck(Intrinsic::ID ID, Function *F, const Type *Ty,
// the type being matched against.
if ((Match & ExtendedElementVectorType) != 0) {
if ((IEltTy->getBitWidth() & 1) != 0) {
- CheckFailed(IntrinsicParam(ArgNo, NumRets) + " vector "
+ CheckFailed(IntrinsicParam(ArgNo, NumRetVals) + " vector "
"element bit-width is odd.", F);
return false;
}
@@ -1742,25 +1736,25 @@ bool Verifier::PerformTypeCheck(Intrinsic::ID ID, Function *F, const Type *Ty,
Match &= ~(ExtendedElementVectorType | TruncatedElementVectorType);
}
- if (Match <= static_cast<int>(NumRets - 1)) {
+ if (Match <= static_cast<int>(NumRetVals - 1)) {
if (ST)
RetTy = ST->getElementType(Match);
if (Ty != RetTy) {
- CheckFailed(IntrinsicParam(ArgNo, NumRets) + " does not "
+ CheckFailed(IntrinsicParam(ArgNo, NumRetVals) + " does not "
"match return type.", F);
return false;
}
} else {
- if (Ty != FTy->getParamType(Match - NumRets)) {
- CheckFailed(IntrinsicParam(ArgNo, NumRets) + " does not "
- "match parameter %" + utostr(Match - NumRets) + ".", F);
+ if (Ty != FTy->getParamType(Match - NumRetVals)) {
+ CheckFailed(IntrinsicParam(ArgNo, NumRetVals) + " does not "
+ "match parameter %" + utostr(Match - NumRetVals) + ".", F);
return false;
}
}
} else if (VT == MVT::iAny) {
if (!EltTy->isIntegerTy()) {
- CheckFailed(IntrinsicParam(ArgNo, NumRets) + " is not "
+ CheckFailed(IntrinsicParam(ArgNo, NumRetVals) + " is not "
"an integer type.", F);
return false;
}
@@ -1785,7 +1779,7 @@ bool Verifier::PerformTypeCheck(Intrinsic::ID ID, Function *F, const Type *Ty,
}
} else if (VT == MVT::fAny) {
if (!EltTy->isFloatingPointTy()) {
- CheckFailed(IntrinsicParam(ArgNo, NumRets) + " is not "
+ CheckFailed(IntrinsicParam(ArgNo, NumRetVals) + " is not "
"a floating-point type.", F);
return false;
}
@@ -1798,13 +1792,14 @@ bool Verifier::PerformTypeCheck(Intrinsic::ID ID, Function *F, const Type *Ty,
Suffix += EVT::getEVT(EltTy).getEVTString();
} else if (VT == MVT::vAny) {
if (!VTy) {
- CheckFailed(IntrinsicParam(ArgNo, NumRets) + " is not a vector type.", F);
+ CheckFailed(IntrinsicParam(ArgNo, NumRetVals) + " is not a vector type.",
+ F);
return false;
}
Suffix += ".v" + utostr(NumElts) + EVT::getEVT(EltTy).getEVTString();
} else if (VT == MVT::iPTR) {
if (!Ty->isPointerTy()) {
- CheckFailed(IntrinsicParam(ArgNo, NumRets) + " is not a "
+ CheckFailed(IntrinsicParam(ArgNo, NumRetVals) + " is not a "
"pointer and a pointer is required.", F);
return false;
}
@@ -1816,7 +1811,7 @@ bool Verifier::PerformTypeCheck(Intrinsic::ID ID, Function *F, const Type *Ty,
Suffix += ".p" + utostr(PTyp->getAddressSpace()) +
EVT::getEVT(PTyp->getElementType()).getEVTString();
} else {
- CheckFailed(IntrinsicParam(ArgNo, NumRets) + " is not a "
+ CheckFailed(IntrinsicParam(ArgNo, NumRetVals) + " is not a "
"pointer and a pointer is required.", F);
return false;
}
@@ -1836,10 +1831,10 @@ bool Verifier::PerformTypeCheck(Intrinsic::ID ID, Function *F, const Type *Ty,
}
} else if (EVT((MVT::SimpleValueType)VT).getTypeForEVT(Ty->getContext()) !=
EltTy) {
- CheckFailed(IntrinsicParam(ArgNo, NumRets) + " is wrong!", F);
+ CheckFailed(IntrinsicParam(ArgNo, NumRetVals) + " is wrong!", F);
return false;
} else if (EltTy != Ty) {
- CheckFailed(IntrinsicParam(ArgNo, NumRets) + " is a vector "
+ CheckFailed(IntrinsicParam(ArgNo, NumRetVals) + " is a vector "
"and a scalar is required.", F);
return false;
}
@@ -1851,10 +1846,10 @@ bool Verifier::PerformTypeCheck(Intrinsic::ID ID, Function *F, const Type *Ty,
/// Intrinsics.gen. This implements a little state machine that verifies the
/// prototype of intrinsics.
void Verifier::VerifyIntrinsicPrototype(Intrinsic::ID ID, Function *F,
- unsigned RetNum,
- unsigned ParamNum, ...) {
+ unsigned NumRetVals,
+ unsigned NumParams, ...) {
va_list VA;
- va_start(VA, ParamNum);
+ va_start(VA, NumParams);
const FunctionType *FTy = F->getFunctionType();
// For overloaded intrinsics, the Suffix of the function name must match the
@@ -1862,7 +1857,7 @@ void Verifier::VerifyIntrinsicPrototype(Intrinsic::ID ID, Function *F,
// suffix, to be checked at the end.
std::string Suffix;
- if (FTy->getNumParams() + FTy->isVarArg() != ParamNum) {
+ if (FTy->getNumParams() + FTy->isVarArg() != NumParams) {
CheckFailed("Intrinsic prototype has incorrect number of arguments!", F);
return;
}
@@ -1870,23 +1865,27 @@ void Verifier::VerifyIntrinsicPrototype(Intrinsic::ID ID, Function *F,
const Type *Ty = FTy->getReturnType();
const StructType *ST = dyn_cast<StructType>(Ty);
+ if (NumRetVals == 0 && !Ty->isVoidTy()) {
+ CheckFailed("Intrinsic should return void", F);
+ return;
+ }
+
// Verify the return types.
- if (ST && ST->getNumElements() != RetNum) {
+ if (ST && ST->getNumElements() != NumRetVals) {
CheckFailed("Intrinsic prototype has incorrect number of return types!", F);
return;
}
-
- for (unsigned ArgNo = 0; ArgNo < RetNum; ++ArgNo) {
+
+ for (unsigned ArgNo = 0; ArgNo != NumRetVals; ++ArgNo) {
int VT = va_arg(VA, int); // An MVT::SimpleValueType when non-negative.
if (ST) Ty = ST->getElementType(ArgNo);
-
if (!PerformTypeCheck(ID, F, Ty, VT, ArgNo, Suffix))
break;
}
// Verify the parameter types.
- for (unsigned ArgNo = 0; ArgNo < ParamNum; ++ArgNo) {
+ for (unsigned ArgNo = 0; ArgNo != NumParams; ++ArgNo) {
int VT = va_arg(VA, int); // An MVT::SimpleValueType when non-negative.
if (VT == MVT::isVoid && ArgNo > 0) {
@@ -1895,8 +1894,8 @@ void Verifier::VerifyIntrinsicPrototype(Intrinsic::ID ID, Function *F,
break;
}
- if (!PerformTypeCheck(ID, F, FTy->getParamType(ArgNo), VT, ArgNo + RetNum,
- Suffix))
+ if (!PerformTypeCheck(ID, F, FTy->getParamType(ArgNo), VT,
+ ArgNo + NumRetVals, Suffix))
break;
}
@@ -1934,7 +1933,9 @@ FunctionPass *llvm::createVerifierPass(VerifierFailureAction action) {
}
-// verifyFunction - Create
+/// verifyFunction - Check a function for errors, printing messages on stderr.
+/// Return true if the function is corrupt.
+///
bool llvm::verifyFunction(const Function &f, VerifierFailureAction action) {
Function &F = const_cast<Function&>(f);
assert(!F.isDeclaration() && "Cannot verify external functions");