summaryrefslogtreecommitdiffstats
path: root/lib/VMCore
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2012-08-15 19:34:23 +0000
committerdim <dim@FreeBSD.org>2012-08-15 19:34:23 +0000
commit721c201bd55ffb73cb2ba8d39e0570fa38c44e15 (patch)
treeeacfc83d988e4b9d11114387ae7dc41243f2a363 /lib/VMCore
parent2b2816e083a455f7a656ae88b0fd059d1688bb36 (diff)
downloadFreeBSD-src-721c201bd55ffb73cb2ba8d39e0570fa38c44e15.zip
FreeBSD-src-721c201bd55ffb73cb2ba8d39e0570fa38c44e15.tar.gz
Vendor import of llvm trunk r161861:
http://llvm.org/svn/llvm-project/llvm/trunk@161861
Diffstat (limited to 'lib/VMCore')
-rw-r--r--lib/VMCore/AsmWriter.cpp80
-rw-r--r--lib/VMCore/Attributes.cpp32
-rw-r--r--lib/VMCore/AutoUpgrade.cpp219
-rw-r--r--lib/VMCore/CMakeLists.txt14
-rw-r--r--lib/VMCore/ConstantFold.cpp69
-rw-r--r--lib/VMCore/Constants.cpp315
-rw-r--r--lib/VMCore/Core.cpp21
-rw-r--r--lib/VMCore/DIBuilder.cpp1019
-rw-r--r--lib/VMCore/DebugInfo.cpp1168
-rw-r--r--lib/VMCore/DebugLoc.cpp42
-rw-r--r--lib/VMCore/Dominators.cpp83
-rw-r--r--lib/VMCore/Function.cpp243
-rw-r--r--lib/VMCore/GCOV.cpp28
-rw-r--r--lib/VMCore/Globals.cpp12
-rw-r--r--lib/VMCore/IRBuilder.cpp14
-rw-r--r--lib/VMCore/Instruction.cpp53
-rw-r--r--lib/VMCore/Instructions.cpp40
-rw-r--r--lib/VMCore/Metadata.cpp165
-rw-r--r--lib/VMCore/Module.cpp162
-rw-r--r--lib/VMCore/PassManager.cpp23
-rw-r--r--lib/VMCore/Type.cpp30
-rw-r--r--lib/VMCore/TypeFinder.cpp148
-rw-r--r--lib/VMCore/Value.cpp9
-rw-r--r--lib/VMCore/ValueTypes.cpp8
-rw-r--r--lib/VMCore/Verifier.cpp488
25 files changed, 3684 insertions, 801 deletions
diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp
index 7b39efb..7ef1131 100644
--- a/lib/VMCore/AsmWriter.cpp
+++ b/lib/VMCore/AsmWriter.cpp
@@ -20,11 +20,13 @@
#include "llvm/LLVMContext.h"
#include "llvm/CallingConv.h"
#include "llvm/Constants.h"
+#include "llvm/DebugInfo.h"
#include "llvm/DerivedTypes.h"
#include "llvm/InlineAsm.h"
#include "llvm/IntrinsicInst.h"
#include "llvm/Operator.h"
#include "llvm/Module.h"
+#include "llvm/TypeFinder.h"
#include "llvm/ValueSymbolTable.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallString.h"
@@ -99,7 +101,11 @@ static void PrintLLVMName(raw_ostream &OS, StringRef Name, PrefixType Prefix) {
bool NeedsQuotes = isdigit(Name[0]);
if (!NeedsQuotes) {
for (unsigned i = 0, e = Name.size(); i != e; ++i) {
- char C = Name[i];
+ // By making this unsigned, the value passed in to isalnum will always be
+ // in the range 0-255. This is important when building with MSVC because
+ // its implementation will assert. This situation can arise when dealing
+ // with UTF-8 multibyte characters.
+ unsigned char C = Name[i];
if (!isalnum(C) && C != '-' && C != '.' && C != '_') {
NeedsQuotes = true;
break;
@@ -140,7 +146,7 @@ class TypePrinting {
public:
/// NamedTypes - The named types that are used by the current module.
- std::vector<StructType*> NamedTypes;
+ TypeFinder NamedTypes;
/// NumberedTypes - The numbered types, along with their value.
DenseMap<StructType*, unsigned> NumberedTypes;
@@ -159,7 +165,7 @@ public:
void TypePrinting::incorporateTypes(const Module &M) {
- M.findUsedStructTypes(NamedTypes);
+ NamedTypes.run(M, false);
// The list of struct types we got back includes all the struct types, split
// the unnamed ones out to a numbering and remove the anonymous structs.
@@ -708,8 +714,7 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV,
}
if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) {
- if (&CFP->getValueAPF().getSemantics() == &APFloat::IEEEhalf ||
- &CFP->getValueAPF().getSemantics() == &APFloat::IEEEsingle ||
+ if (&CFP->getValueAPF().getSemantics() == &APFloat::IEEEsingle ||
&CFP->getValueAPF().getSemantics() == &APFloat::IEEEdouble) {
// We would like to output the FP constant value in exponential notation,
// but we cannot do this if doing so will lose precision. Check here to
@@ -759,16 +764,20 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV,
return;
}
- // Some form of long double. These appear as a magic letter identifying
- // the type, then a fixed number of hex digits.
+ // Either half, or some form of long double.
+ // These appear as a magic letter identifying the type, then a
+ // fixed number of hex digits.
Out << "0x";
+ // Bit position, in the current word, of the next nibble to print.
+ int shiftcount;
+
if (&CFP->getValueAPF().getSemantics() == &APFloat::x87DoubleExtended) {
Out << 'K';
// api needed to prevent premature destruction
APInt api = CFP->getValueAPF().bitcastToAPInt();
const uint64_t* p = api.getRawData();
uint64_t word = p[1];
- int shiftcount=12;
+ shiftcount = 12;
int width = api.getBitWidth();
for (int j=0; j<width; j+=4, shiftcount-=4) {
unsigned int nibble = (word>>shiftcount) & 15;
@@ -784,17 +793,21 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV,
}
}
return;
- } else if (&CFP->getValueAPF().getSemantics() == &APFloat::IEEEquad)
+ } else if (&CFP->getValueAPF().getSemantics() == &APFloat::IEEEquad) {
+ shiftcount = 60;
Out << 'L';
- else if (&CFP->getValueAPF().getSemantics() == &APFloat::PPCDoubleDouble)
+ } else if (&CFP->getValueAPF().getSemantics() == &APFloat::PPCDoubleDouble) {
+ shiftcount = 60;
Out << 'M';
- else
+ } else if (&CFP->getValueAPF().getSemantics() == &APFloat::IEEEhalf) {
+ shiftcount = 12;
+ Out << 'H';
+ } else
llvm_unreachable("Unsupported floating point type");
// api needed to prevent premature destruction
APInt api = CFP->getValueAPF().bitcastToAPInt();
const uint64_t* p = api.getRawData();
uint64_t word = *p;
- int shiftcount=60;
int width = api.getBitWidth();
for (int j=0; j<width; j+=4, shiftcount-=4) {
unsigned int nibble = (word>>shiftcount) & 15;
@@ -1369,6 +1382,26 @@ static void PrintVisibility(GlobalValue::VisibilityTypes Vis,
}
}
+static void PrintThreadLocalModel(GlobalVariable::ThreadLocalMode TLM,
+ formatted_raw_ostream &Out) {
+ switch (TLM) {
+ case GlobalVariable::NotThreadLocal:
+ break;
+ case GlobalVariable::GeneralDynamicTLSModel:
+ Out << "thread_local ";
+ break;
+ case GlobalVariable::LocalDynamicTLSModel:
+ Out << "thread_local(localdynamic) ";
+ break;
+ case GlobalVariable::InitialExecTLSModel:
+ Out << "thread_local(initialexec) ";
+ break;
+ case GlobalVariable::LocalExecTLSModel:
+ Out << "thread_local(localexec) ";
+ break;
+ }
+}
+
void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
if (GV->isMaterializable())
Out << "; Materializable\n";
@@ -1381,8 +1414,8 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
PrintLinkage(GV->getLinkage(), Out);
PrintVisibility(GV->getVisibility(), Out);
+ PrintThreadLocalModel(GV->getThreadLocalMode(), Out);
- if (GV->isThreadLocal()) Out << "thread_local ";
if (unsigned AddressSpace = GV->getType()->getAddressSpace())
Out << "addrspace(" << AddressSpace << ") ";
if (GV->hasUnnamedAddr()) Out << "unnamed_addr ";
@@ -2004,19 +2037,22 @@ static void WriteMDNodeComment(const MDNode *Node,
formatted_raw_ostream &Out) {
if (Node->getNumOperands() < 1)
return;
- ConstantInt *CI = dyn_cast_or_null<ConstantInt>(Node->getOperand(0));
- if (!CI) return;
- APInt Val = CI->getValue();
- APInt Tag = Val & ~APInt(Val.getBitWidth(), LLVMDebugVersionMask);
- if (Val.ult(LLVMDebugVersion11))
+
+ Value *Op = Node->getOperand(0);
+ if (!Op || !isa<ConstantInt>(Op) || cast<ConstantInt>(Op)->getBitWidth() < 32)
+ return;
+
+ DIDescriptor Desc(Node);
+ if (Desc.getVersion() < LLVMDebugVersion11)
return;
+ unsigned Tag = Desc.getTag();
Out.PadToColumn(50);
- if (Tag == dwarf::DW_TAG_user_base)
+ if (dwarf::TagString(Tag)) {
+ Out << "; ";
+ Desc.print(Out);
+ } else if (Tag == dwarf::DW_TAG_user_base) {
Out << "; [ DW_TAG_user_base ]";
- else if (Tag.isIntN(32)) {
- if (const char *TagName = dwarf::TagString(Tag.getZExtValue()))
- Out << "; [ " << TagName << " ]";
}
}
diff --git a/lib/VMCore/Attributes.cpp b/lib/VMCore/Attributes.cpp
index c05132b..c8219eb 100644
--- a/lib/VMCore/Attributes.cpp
+++ b/lib/VMCore/Attributes.cpp
@@ -88,6 +88,9 @@ std::string Attribute::getAsString(Attributes Attrs) {
Result += utostr(Attribute::getAlignmentFromAttrs(Attrs));
Result += " ";
}
+ if (Attrs & Attribute::IANSDialect)
+ Result += "ia_nsdialect ";
+
// Trim the trailing space.
assert(!Result.empty() && "Unknown attribute!");
Result.erase(Result.end()-1);
@@ -131,8 +134,8 @@ class AttributeListImpl : public FoldingSetNode {
public:
SmallVector<AttributeWithIndex, 4> Attrs;
- AttributeListImpl(const AttributeWithIndex *Attr, unsigned NumAttrs)
- : Attrs(Attr, Attr+NumAttrs) {
+ AttributeListImpl(ArrayRef<AttributeWithIndex> attrs)
+ : Attrs(attrs.begin(), attrs.end()) {
RefCount = 0;
}
@@ -150,13 +153,12 @@ public:
}
void Profile(FoldingSetNodeID &ID) const {
- Profile(ID, Attrs.data(), Attrs.size());
+ Profile(ID, Attrs);
}
- static void Profile(FoldingSetNodeID &ID, const AttributeWithIndex *Attr,
- unsigned NumAttrs) {
- for (unsigned i = 0; i != NumAttrs; ++i) {
- ID.AddInteger(Attr[i].Attrs.Raw());
- ID.AddInteger(Attr[i].Index);
+ static void Profile(FoldingSetNodeID &ID, ArrayRef<AttributeWithIndex> Attrs){
+ for (unsigned i = 0, e = Attrs.size(); i != e; ++i) {
+ ID.AddInteger(Attrs[i].Attrs.Raw());
+ ID.AddInteger(Attrs[i].Index);
}
}
};
@@ -168,13 +170,13 @@ AttributeListImpl::~AttributeListImpl() {
}
-AttrListPtr AttrListPtr::get(const AttributeWithIndex *Attrs, unsigned NumAttrs) {
+AttrListPtr AttrListPtr::get(ArrayRef<AttributeWithIndex> Attrs) {
// If there are no attributes then return a null AttributesList pointer.
- if (NumAttrs == 0)
+ if (Attrs.empty())
return AttrListPtr();
#ifndef NDEBUG
- for (unsigned i = 0; i != NumAttrs; ++i) {
+ for (unsigned i = 0, e = Attrs.size(); i != e; ++i) {
assert(Attrs[i].Attrs != Attribute::None &&
"Pointless attribute!");
assert((!i || Attrs[i-1].Index < Attrs[i].Index) &&
@@ -184,7 +186,7 @@ AttrListPtr AttrListPtr::get(const AttributeWithIndex *Attrs, unsigned NumAttrs)
// Otherwise, build a key to look up the existing attributes.
FoldingSetNodeID ID;
- AttributeListImpl::Profile(ID, Attrs, NumAttrs);
+ AttributeListImpl::Profile(ID, Attrs);
void *InsertPos;
sys::SmartScopedLock<true> Lock(*ALMutex);
@@ -195,7 +197,7 @@ AttrListPtr AttrListPtr::get(const AttributeWithIndex *Attrs, unsigned NumAttrs)
// If we didn't find any existing attributes of the same shape then
// create a new one and insert it.
if (!PAL) {
- PAL = new AttributeListImpl(Attrs, NumAttrs);
+ PAL = new AttributeListImpl(Attrs);
AttributesLists->InsertNode(PAL, InsertPos);
}
@@ -308,7 +310,7 @@ AttrListPtr AttrListPtr::addAttr(unsigned Idx, Attributes Attrs) const {
OldAttrList.begin()+i, OldAttrList.end());
}
- return get(NewAttrList.data(), NewAttrList.size());
+ return get(NewAttrList);
}
AttrListPtr AttrListPtr::removeAttr(unsigned Idx, Attributes Attrs) const {
@@ -343,7 +345,7 @@ AttrListPtr AttrListPtr::removeAttr(unsigned Idx, Attributes Attrs) const {
NewAttrList.insert(NewAttrList.end(),
OldAttrList.begin()+i, OldAttrList.end());
- return get(NewAttrList.data(), NewAttrList.size());
+ return get(NewAttrList);
}
void AttrListPtr::dump() const {
diff --git a/lib/VMCore/AutoUpgrade.cpp b/lib/VMCore/AutoUpgrade.cpp
index 2e16372..094ca75 100644
--- a/lib/VMCore/AutoUpgrade.cpp
+++ b/lib/VMCore/AutoUpgrade.cpp
@@ -14,17 +14,32 @@
#include "llvm/AutoUpgrade.h"
#include "llvm/Constants.h"
#include "llvm/Function.h"
+#include "llvm/IRBuilder.h"
#include "llvm/Instruction.h"
+#include "llvm/IntrinsicInst.h"
#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
-#include "llvm/IntrinsicInst.h"
-#include "llvm/Support/CallSite.h"
#include "llvm/Support/CFG.h"
+#include "llvm/Support/CallSite.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/IRBuilder.h"
#include <cstring>
using namespace llvm;
+// Upgrade the declarations of the SSE4.1 functions whose arguments have
+// changed their type from v4f32 to v2i64.
+static bool UpgradeSSE41Function(Function* F, Intrinsic::ID IID,
+ Function *&NewFn) {
+ // Check whether this is an old version of the function, which received
+ // v4f32 arguments.
+ Type *Arg0Type = F->getFunctionType()->getParamType(0);
+ if (Arg0Type != VectorType::get(Type::getFloatTy(F->getContext()), 4))
+ return false;
+
+ // Yes, it's old, replace it with new version.
+ F->setName(F->getName() + ".old");
+ NewFn = Intrinsic::getDeclaration(F->getParent(), IID);
+ return true;
+}
static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
assert(F && "Illegal to upgrade a non-existent Function.");
@@ -37,6 +52,27 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
switch (Name[0]) {
default: break;
+ case 'a': {
+ if (Name.startswith("arm.neon.vclz")) {
+ Type* args[2] = {
+ F->arg_begin()->getType(),
+ Type::getInt1Ty(F->getContext())
+ };
+ // Can't use Intrinsic::getDeclaration here as it adds a ".i1" to
+ // the end of the name. Change name from llvm.arm.neon.vclz.* to
+ // llvm.ctlz.*
+ FunctionType* fType = FunctionType::get(F->getReturnType(), args, false);
+ NewFn = Function::Create(fType, F->getLinkage(),
+ "llvm.ctlz." + Name.substr(14), F->getParent());
+ return true;
+ }
+ if (Name.startswith("arm.neon.vcnt")) {
+ NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::ctpop,
+ F->arg_begin()->getType());
+ return true;
+ }
+ break;
+ }
case 'c': {
if (Name.startswith("ctlz.") && F->arg_size() == 1) {
F->setName(Name + ".old");
@@ -57,17 +93,49 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
Name.startswith("x86.sse2.pcmpgt.") ||
Name.startswith("x86.avx2.pcmpeq.") ||
Name.startswith("x86.avx2.pcmpgt.") ||
- Name.startswith("x86.avx.vpermil.")) {
+ Name.startswith("x86.avx.vpermil.") ||
+ Name == "x86.avx.movnt.dq.256" ||
+ Name == "x86.avx.movnt.pd.256" ||
+ Name == "x86.avx.movnt.ps.256" ||
+ (Name.startswith("x86.xop.vpcom") && F->arg_size() == 2)) {
NewFn = 0;
return true;
}
+ // SSE4.1 ptest functions may have an old signature.
+ if (Name.startswith("x86.sse41.ptest")) {
+ if (Name == "x86.sse41.ptestc")
+ return UpgradeSSE41Function(F, Intrinsic::x86_sse41_ptestc, NewFn);
+ if (Name == "x86.sse41.ptestz")
+ return UpgradeSSE41Function(F, Intrinsic::x86_sse41_ptestz, NewFn);
+ if (Name == "x86.sse41.ptestnzc")
+ return UpgradeSSE41Function(F, Intrinsic::x86_sse41_ptestnzc, NewFn);
+ }
+ // frcz.ss/sd may need to have an argument dropped
+ if (Name.startswith("x86.xop.vfrcz.ss") && F->arg_size() == 2) {
+ F->setName(Name + ".old");
+ NewFn = Intrinsic::getDeclaration(F->getParent(),
+ Intrinsic::x86_xop_vfrcz_ss);
+ return true;
+ }
+ if (Name.startswith("x86.xop.vfrcz.sd") && F->arg_size() == 2) {
+ F->setName(Name + ".old");
+ NewFn = Intrinsic::getDeclaration(F->getParent(),
+ Intrinsic::x86_xop_vfrcz_sd);
+ return true;
+ }
+ // Fix the FMA4 intrinsics to remove the 4
+ if (Name.startswith("x86.fma4.")) {
+ F->setName("llvm.x86.fma" + Name.substr(8));
+ NewFn = F;
+ return true;
+ }
break;
}
}
- // This may not belong here. This function is effectively being overloaded
- // to both detect an intrinsic which needs upgrading, and to provide the
- // upgraded form of the intrinsic. We should perhaps have two separate
+ // This may not belong here. This function is effectively being overloaded
+ // to both detect an intrinsic which needs upgrading, and to provide the
+ // upgraded form of the intrinsic. We should perhaps have two separate
// functions for this.
return false;
}
@@ -89,8 +157,8 @@ bool llvm::UpgradeGlobalVariable(GlobalVariable *GV) {
return false;
}
-// UpgradeIntrinsicCall - Upgrade a call to an old intrinsic to be a call the
-// upgraded intrinsic. All argument and return casting must be provided in
+// UpgradeIntrinsicCall - Upgrade a call to an old intrinsic to be a call the
+// upgraded intrinsic. All argument and return casting must be provided in
// order to seamlessly integrate with existing context.
void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
Function *F = CI->getCalledFunction();
@@ -118,15 +186,85 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
"pcmpgt");
// need to sign extend since icmp returns vector of i1
Rep = Builder.CreateSExt(Rep, CI->getType(), "");
+ } else if (Name == "llvm.x86.avx.movnt.dq.256" ||
+ Name == "llvm.x86.avx.movnt.ps.256" ||
+ Name == "llvm.x86.avx.movnt.pd.256") {
+ IRBuilder<> Builder(C);
+ Builder.SetInsertPoint(CI->getParent(), CI);
+
+ Module *M = F->getParent();
+ SmallVector<Value *, 1> Elts;
+ Elts.push_back(ConstantInt::get(Type::getInt32Ty(C), 1));
+ MDNode *Node = MDNode::get(C, Elts);
+
+ Value *Arg0 = CI->getArgOperand(0);
+ Value *Arg1 = CI->getArgOperand(1);
+
+ // Convert the type of the pointer to a pointer to the stored type.
+ Value *BC = Builder.CreateBitCast(Arg0,
+ PointerType::getUnqual(Arg1->getType()),
+ "cast");
+ StoreInst *SI = Builder.CreateStore(Arg1, BC);
+ SI->setMetadata(M->getMDKindID("nontemporal"), Node);
+ SI->setAlignment(16);
+
+ // Remove intrinsic.
+ CI->eraseFromParent();
+ return;
+ } else if (Name.startswith("llvm.x86.xop.vpcom")) {
+ Intrinsic::ID intID;
+ if (Name.endswith("ub"))
+ intID = Intrinsic::x86_xop_vpcomub;
+ else if (Name.endswith("uw"))
+ intID = Intrinsic::x86_xop_vpcomuw;
+ else if (Name.endswith("ud"))
+ intID = Intrinsic::x86_xop_vpcomud;
+ else if (Name.endswith("uq"))
+ intID = Intrinsic::x86_xop_vpcomuq;
+ else if (Name.endswith("b"))
+ intID = Intrinsic::x86_xop_vpcomb;
+ else if (Name.endswith("w"))
+ intID = Intrinsic::x86_xop_vpcomw;
+ else if (Name.endswith("d"))
+ intID = Intrinsic::x86_xop_vpcomd;
+ else if (Name.endswith("q"))
+ intID = Intrinsic::x86_xop_vpcomq;
+ else
+ llvm_unreachable("Unknown suffix");
+
+ Name = Name.substr(18); // strip off "llvm.x86.xop.vpcom"
+ unsigned Imm;
+ if (Name.startswith("lt"))
+ Imm = 0;
+ else if (Name.startswith("le"))
+ Imm = 1;
+ else if (Name.startswith("gt"))
+ Imm = 2;
+ else if (Name.startswith("ge"))
+ Imm = 3;
+ else if (Name.startswith("eq"))
+ Imm = 4;
+ else if (Name.startswith("ne"))
+ Imm = 5;
+ else if (Name.startswith("true"))
+ Imm = 6;
+ else if (Name.startswith("false"))
+ Imm = 7;
+ else
+ llvm_unreachable("Unknown condition");
+
+ Function *VPCOM = Intrinsic::getDeclaration(F->getParent(), intID);
+ Rep = Builder.CreateCall3(VPCOM, CI->getArgOperand(0),
+ CI->getArgOperand(1), Builder.getInt8(Imm));
} else {
bool PD128 = false, PD256 = false, PS128 = false, PS256 = false;
- if (Name.startswith("llvm.x86.avx.vpermil.pd.256"))
+ if (Name == "llvm.x86.avx.vpermil.pd.256")
PD256 = true;
- else if (Name.startswith("llvm.x86.avx.vpermil.pd"))
+ else if (Name == "llvm.x86.avx.vpermil.pd")
PD128 = true;
- else if (Name.startswith("llvm.x86.avx.vpermil.ps.256"))
+ else if (Name == "llvm.x86.avx.vpermil.ps.256")
PS256 = true;
- else if (Name.startswith("llvm.x86.avx.vpermil.ps"))
+ else if (Name == "llvm.x86.avx.vpermil.ps")
PS128 = true;
if (PD256 || PD128 || PS256 || PS128) {
@@ -162,6 +300,9 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
return;
}
+ std::string Name = CI->getName().str();
+ CI->setName(Name + ".old");
+
switch (NewFn->getIntrinsicID()) {
default:
llvm_unreachable("Unknown function for CallInst upgrade.");
@@ -170,12 +311,60 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
case Intrinsic::cttz:
assert(CI->getNumArgOperands() == 1 &&
"Mismatch between function args and call args");
- StringRef Name = CI->getName();
- CI->setName(Name + ".old");
CI->replaceAllUsesWith(Builder.CreateCall2(NewFn, CI->getArgOperand(0),
Builder.getFalse(), Name));
CI->eraseFromParent();
return;
+
+ case Intrinsic::arm_neon_vclz: {
+ // Change name from llvm.arm.neon.vclz.* to llvm.ctlz.*
+ CI->replaceAllUsesWith(Builder.CreateCall2(NewFn, CI->getArgOperand(0),
+ Builder.getFalse(),
+ "llvm.ctlz." + Name.substr(14)));
+ CI->eraseFromParent();
+ return;
+ }
+ case Intrinsic::ctpop: {
+ CI->replaceAllUsesWith(Builder.CreateCall(NewFn, CI->getArgOperand(0)));
+ CI->eraseFromParent();
+ return;
+ }
+
+ case Intrinsic::x86_xop_vfrcz_ss:
+ case Intrinsic::x86_xop_vfrcz_sd:
+ CI->replaceAllUsesWith(Builder.CreateCall(NewFn, CI->getArgOperand(1),
+ Name));
+ CI->eraseFromParent();
+ return;
+
+ case Intrinsic::x86_sse41_ptestc:
+ case Intrinsic::x86_sse41_ptestz:
+ case Intrinsic::x86_sse41_ptestnzc: {
+ // The arguments for these intrinsics used to be v4f32, and changed
+ // to v2i64. This is purely a nop, since those are bitwise intrinsics.
+ // So, the only thing required is a bitcast for both arguments.
+ // First, check the arguments have the old type.
+ Value *Arg0 = CI->getArgOperand(0);
+ if (Arg0->getType() != VectorType::get(Type::getFloatTy(C), 4))
+ return;
+
+ // Old intrinsic, add bitcasts
+ Value *Arg1 = CI->getArgOperand(1);
+
+ Value *BC0 =
+ Builder.CreateBitCast(Arg0,
+ VectorType::get(Type::getInt64Ty(C), 2),
+ "cast");
+ Value *BC1 =
+ Builder.CreateBitCast(Arg1,
+ VectorType::get(Type::getInt64Ty(C), 2),
+ "cast");
+
+ CallInst* NewCall = Builder.CreateCall2(NewFn, BC0, BC1, Name);
+ CI->replaceAllUsesWith(NewCall);
+ CI->eraseFromParent();
+ return;
+ }
}
}
diff --git a/lib/VMCore/CMakeLists.txt b/lib/VMCore/CMakeLists.txt
index e1efcda..6a20be6 100644
--- a/lib/VMCore/CMakeLists.txt
+++ b/lib/VMCore/CMakeLists.txt
@@ -8,7 +8,9 @@ add_llvm_library(LLVMCore
ConstantFold.cpp
Constants.cpp
Core.cpp
+ DebugInfo.cpp
DebugLoc.cpp
+ DIBuilder.cpp
Dominators.cpp
Function.cpp
GCOV.cpp
@@ -29,6 +31,7 @@ add_llvm_library(LLVMCore
PassRegistry.cpp
PrintModulePass.cpp
Type.cpp
+ TypeFinder.cpp
Use.cpp
User.cpp
Value.cpp
@@ -36,3 +39,14 @@ add_llvm_library(LLVMCore
ValueTypes.cpp
Verifier.cpp
)
+
+# Workaround: It takes over 20 minutes to compile with msvc10.
+# FIXME: Suppressing optimizations to core libraries would not be good thing.
+if( MSVC_VERSION EQUAL 1600 )
+set_property(
+ SOURCE Function.cpp
+ PROPERTY COMPILE_FLAGS "/Og-"
+ )
+endif()
+
+add_dependencies(LLVMCore intrinsics_gen)
diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp
index b743287..8e82876 100644
--- a/lib/VMCore/ConstantFold.cpp
+++ b/lib/VMCore/ConstantFold.cpp
@@ -55,13 +55,12 @@ static Constant *BitCastConstantVector(Constant *CV, VectorType *DstTy) {
Type *DstEltTy = DstTy->getElementType();
- // Check to verify that all elements of the input are simple.
SmallVector<Constant*, 16> Result;
+ Type *Ty = IntegerType::get(CV->getContext(), 32);
for (unsigned i = 0; i != NumElts; ++i) {
- Constant *C = CV->getAggregateElement(i);
- if (C == 0) return 0;
+ Constant *C =
+ ConstantExpr::getExtractElement(CV, ConstantInt::get(Ty, i));
C = ConstantExpr::getBitCast(C, DstEltTy);
- if (isa<ConstantExpr>(C)) return 0;
Result.push_back(C);
}
@@ -553,9 +552,12 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, Constant *V,
SmallVector<Constant*, 16> res;
VectorType *DestVecTy = cast<VectorType>(DestTy);
Type *DstEltTy = DestVecTy->getElementType();
- for (unsigned i = 0, e = V->getType()->getVectorNumElements(); i != e; ++i)
- res.push_back(ConstantExpr::getCast(opc,
- V->getAggregateElement(i), DstEltTy));
+ Type *Ty = IntegerType::get(V->getContext(), 32);
+ for (unsigned i = 0, e = V->getType()->getVectorNumElements(); i != e; ++i) {
+ Constant *C =
+ ConstantExpr::getExtractElement(V, ConstantInt::get(Ty, i));
+ res.push_back(ConstantExpr::getCast(opc, C, DstEltTy));
+ }
return ConstantVector::get(res);
}
@@ -696,12 +698,13 @@ Constant *llvm::ConstantFoldSelectInstruction(Constant *Cond,
// If the condition is a vector constant, fold the result elementwise.
if (ConstantVector *CondV = dyn_cast<ConstantVector>(Cond)) {
SmallVector<Constant*, 16> Result;
+ Type *Ty = IntegerType::get(CondV->getContext(), 32);
for (unsigned i = 0, e = V1->getType()->getVectorNumElements(); i != e;++i){
ConstantInt *Cond = dyn_cast<ConstantInt>(CondV->getOperand(i));
if (Cond == 0) break;
- Constant *Res = (Cond->getZExtValue() ? V2 : V1)->getAggregateElement(i);
- if (Res == 0) break;
+ Constant *V = Cond->isNullValue() ? V2 : V1;
+ Constant *Res = ConstantExpr::getExtractElement(V, ConstantInt::get(Ty, i));
Result.push_back(Res);
}
@@ -721,12 +724,12 @@ Constant *llvm::ConstantFoldSelectInstruction(Constant *Cond,
if (ConstantExpr *TrueVal = dyn_cast<ConstantExpr>(V1)) {
if (TrueVal->getOpcode() == Instruction::Select)
if (TrueVal->getOperand(0) == Cond)
- return ConstantExpr::getSelect(Cond, TrueVal->getOperand(1), V2);
+ return ConstantExpr::getSelect(Cond, TrueVal->getOperand(1), V2);
}
if (ConstantExpr *FalseVal = dyn_cast<ConstantExpr>(V2)) {
if (FalseVal->getOpcode() == Instruction::Select)
if (FalseVal->getOperand(0) == Cond)
- return ConstantExpr::getSelect(Cond, V1, FalseVal->getOperand(2));
+ return ConstantExpr::getSelect(Cond, V1, FalseVal->getOperand(2));
}
return 0;
@@ -760,16 +763,16 @@ Constant *llvm::ConstantFoldInsertElementInstruction(Constant *Val,
const APInt &IdxVal = CIdx->getValue();
SmallVector<Constant*, 16> Result;
+ Type *Ty = IntegerType::get(Val->getContext(), 32);
for (unsigned i = 0, e = Val->getType()->getVectorNumElements(); i != e; ++i){
if (i == IdxVal) {
Result.push_back(Elt);
continue;
}
- if (Constant *C = Val->getAggregateElement(i))
- Result.push_back(C);
- else
- return 0;
+ Constant *C =
+ ConstantExpr::getExtractElement(Val, ConstantInt::get(Ty, i));
+ Result.push_back(C);
}
return ConstantVector::get(Result);
@@ -801,11 +804,15 @@ Constant *llvm::ConstantFoldShuffleVectorInstruction(Constant *V1,
Constant *InElt;
if (unsigned(Elt) >= SrcNumElts*2)
InElt = UndefValue::get(EltTy);
- else if (unsigned(Elt) >= SrcNumElts)
- InElt = V2->getAggregateElement(Elt - SrcNumElts);
- else
- InElt = V1->getAggregateElement(Elt);
- if (InElt == 0) return 0;
+ else if (unsigned(Elt) >= SrcNumElts) {
+ Type *Ty = IntegerType::get(V2->getContext(), 32);
+ InElt =
+ ConstantExpr::getExtractElement(V2,
+ ConstantInt::get(Ty, Elt - SrcNumElts));
+ } else {
+ Type *Ty = IntegerType::get(V1->getContext(), 32);
+ InElt = ConstantExpr::getExtractElement(V1, ConstantInt::get(Ty, Elt));
+ }
Result.push_back(InElt);
}
@@ -1130,16 +1137,17 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode,
} else if (VectorType *VTy = dyn_cast<VectorType>(C1->getType())) {
// Perform elementwise folding.
SmallVector<Constant*, 16> Result;
+ Type *Ty = IntegerType::get(VTy->getContext(), 32);
for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) {
- Constant *LHS = C1->getAggregateElement(i);
- Constant *RHS = C2->getAggregateElement(i);
- if (LHS == 0 || RHS == 0) break;
+ Constant *LHS =
+ ConstantExpr::getExtractElement(C1, ConstantInt::get(Ty, i));
+ Constant *RHS =
+ ConstantExpr::getExtractElement(C2, ConstantInt::get(Ty, i));
Result.push_back(ConstantExpr::get(Opcode, LHS, RHS));
}
- if (Result.size() == VTy->getNumElements())
- return ConstantVector::get(Result);
+ return ConstantVector::get(Result);
}
if (ConstantExpr *CE1 = dyn_cast<ConstantExpr>(C1)) {
@@ -1697,17 +1705,18 @@ Constant *llvm::ConstantFoldCompareInstruction(unsigned short pred,
// If we can constant fold the comparison of each element, constant fold
// the whole vector comparison.
SmallVector<Constant*, 4> ResElts;
+ Type *Ty = IntegerType::get(C1->getContext(), 32);
// Compare the elements, producing an i1 result or constant expr.
for (unsigned i = 0, e = C1->getType()->getVectorNumElements(); i != e;++i){
- Constant *C1E = C1->getAggregateElement(i);
- Constant *C2E = C2->getAggregateElement(i);
- if (C1E == 0 || C2E == 0) break;
+ Constant *C1E =
+ ConstantExpr::getExtractElement(C1, ConstantInt::get(Ty, i));
+ Constant *C2E =
+ ConstantExpr::getExtractElement(C2, ConstantInt::get(Ty, i));
ResElts.push_back(ConstantExpr::getCompare(pred, C1E, C2E));
}
- if (ResElts.size() == C1->getType()->getVectorNumElements())
- return ConstantVector::get(ResElts);
+ return ConstantVector::get(ResElts);
}
if (C1->getType()->isFloatingPointTy()) {
diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp
index 6dbc144..a4e21e1 100644
--- a/lib/VMCore/Constants.cpp
+++ b/lib/VMCore/Constants.cpp
@@ -46,7 +46,7 @@ bool Constant::isNegativeZeroValue() const {
// Floating point values have an explicit -0.0 value.
if (const ConstantFP *CFP = dyn_cast<ConstantFP>(this))
return CFP->isZero() && CFP->isNegative();
-
+
// Otherwise, just use +0.0.
return isNullValue();
}
@@ -55,7 +55,7 @@ bool Constant::isNullValue() const {
// 0 is null.
if (const ConstantInt *CI = dyn_cast<ConstantInt>(this))
return CI->isZero();
-
+
// +0.0 is null.
if (const ConstantFP *CFP = dyn_cast<ConstantFP>(this))
return CFP->isZero() && !CFP->isNegative();
@@ -161,19 +161,19 @@ Constant *Constant::getAllOnesValue(Type *Ty) {
Constant *Constant::getAggregateElement(unsigned Elt) const {
if (const ConstantStruct *CS = dyn_cast<ConstantStruct>(this))
return Elt < CS->getNumOperands() ? CS->getOperand(Elt) : 0;
-
+
if (const ConstantArray *CA = dyn_cast<ConstantArray>(this))
return Elt < CA->getNumOperands() ? CA->getOperand(Elt) : 0;
-
+
if (const ConstantVector *CV = dyn_cast<ConstantVector>(this))
return Elt < CV->getNumOperands() ? CV->getOperand(Elt) : 0;
-
+
if (const ConstantAggregateZero *CAZ =dyn_cast<ConstantAggregateZero>(this))
return CAZ->getElementValue(Elt);
-
+
if (const UndefValue *UV = dyn_cast<UndefValue>(this))
return UV->getElementValue(Elt);
-
+
if (const ConstantDataSequential *CDS =dyn_cast<ConstantDataSequential>(this))
return Elt < CDS->getNumElements() ? CDS->getElementAsConstant(Elt) : 0;
return 0;
@@ -222,10 +222,10 @@ bool Constant::canTrap() const {
// The only thing that could possibly trap are constant exprs.
const ConstantExpr *CE = dyn_cast<ConstantExpr>(this);
if (!CE) return false;
-
- // ConstantExpr traps if any operands can trap.
+
+ // ConstantExpr traps if any operands can trap.
for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
- if (CE->getOperand(i)->canTrap())
+ if (CE->getOperand(i)->canTrap())
return true;
// Otherwise, only specific operations can trap.
@@ -252,7 +252,7 @@ bool Constant::isConstantUsed() const {
const Constant *UC = dyn_cast<Constant>(*UI);
if (UC == 0 || isa<GlobalValue>(UC))
return true;
-
+
if (UC->isConstantUsed())
return true;
}
@@ -302,12 +302,12 @@ Constant::PossibleRelocationsTy Constant::getRelocationInfo() const {
cast<BlockAddress>(RHS->getOperand(0))->getFunction())
return NoRelocation;
}
-
+
PossibleRelocationsTy Result = NoRelocation;
for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
Result = std::max(Result,
cast<Constant>(getOperand(i))->getRelocationInfo());
-
+
return Result;
}
@@ -316,14 +316,14 @@ Constant::PossibleRelocationsTy Constant::getRelocationInfo() const {
/// constantexpr.
static bool removeDeadUsersOfConstant(const Constant *C) {
if (isa<GlobalValue>(C)) return false; // Cannot remove this
-
+
while (!C->use_empty()) {
const Constant *User = dyn_cast<Constant>(C->use_back());
if (!User) return false; // Non-constant usage;
if (!removeDeadUsersOfConstant(User))
return false; // Constant wasn't dead
}
-
+
const_cast<Constant*>(C)->destroyConstant();
return true;
}
@@ -343,7 +343,7 @@ void Constant::removeDeadConstantUsers() const {
++I;
continue;
}
-
+
if (!removeDeadUsersOfConstant(User)) {
// If the constant wasn't dead, remember that this was the last live use
// and move on to the next constant.
@@ -351,7 +351,7 @@ void Constant::removeDeadConstantUsers() const {
++I;
continue;
}
-
+
// If the constant was dead, then the iterator is invalidated.
if (LastNonDeadUser == E) {
I = use_begin();
@@ -485,7 +485,7 @@ static const fltSemantics *TypeToFloatSemantics(Type *Ty) {
return &APFloat::x87DoubleExtended;
else if (Ty->isFP128Ty())
return &APFloat::IEEEquad;
-
+
assert(Ty->isPPC_FP128Ty() && "Unknown FP format");
return &APFloat::PPCDoubleDouble;
}
@@ -497,7 +497,7 @@ void ConstantFP::anchor() { }
/// 2.0/1.0 etc, that are known-valid both as double and as the target format.
Constant *ConstantFP::get(Type *Ty, double V) {
LLVMContext &Context = Ty->getContext();
-
+
APFloat FV(V);
bool ignored;
FV.convert(*TypeToFloatSemantics(Ty->getScalarType()),
@@ -550,11 +550,11 @@ Constant *ConstantFP::getZeroValueForNegation(Type *Ty) {
// ConstantFP accessors.
ConstantFP* ConstantFP::get(LLVMContext &Context, const APFloat& V) {
DenseMapAPFloatKeyInfo::KeyTy Key(V);
-
+
LLVMContextImpl* pImpl = Context.pImpl;
-
+
ConstantFP *&Slot = pImpl->FPConstants[Key];
-
+
if (!Slot) {
Type *Ty;
if (&V.getSemantics() == &APFloat::IEEEhalf)
@@ -574,7 +574,7 @@ ConstantFP* ConstantFP::get(LLVMContext &Context, const APFloat& V) {
}
Slot = new ConstantFP(Ty, V);
}
-
+
return Slot;
}
@@ -695,7 +695,7 @@ Constant *ConstantArray::get(ArrayType *Ty, ArrayRef<Constant*> V) {
"Wrong type in array element initializer");
}
LLVMContextImpl *pImpl = Ty->getContext().pImpl;
-
+
// If this is an all-zero array, return a ConstantAggregateZero object. If
// all undef, return an UndefValue, if "all simple", then return a
// ConstantDataArray.
@@ -751,7 +751,7 @@ Constant *ConstantArray::get(ArrayType *Ty, ArrayRef<Constant*> V) {
return ConstantDataArray::get(C->getContext(), Elts);
}
}
-
+
if (ConstantFP *CFP = dyn_cast<ConstantFP>(C)) {
if (CFP->getType()->isFloatTy()) {
SmallVector<float, 16> Elts;
@@ -788,7 +788,7 @@ StructType *ConstantStruct::getTypeForElements(LLVMContext &Context,
SmallVector<Type*, 16> EltTypes(VecSize);
for (unsigned i = 0; i != VecSize; ++i)
EltTypes[i] = V[i]->getType();
-
+
return StructType::get(Context, EltTypes, Packed);
}
@@ -833,12 +833,12 @@ Constant *ConstantStruct::get(StructType *ST, ArrayRef<Constant*> V) {
isUndef = false;
}
}
- }
+ }
if (isZero)
return ConstantAggregateZero::get(ST);
if (isUndef)
return UndefValue::get(ST);
-
+
return ST->getContext().pImpl->StructConstants.getOrCreate(ST, V);
}
@@ -881,12 +881,12 @@ Constant *ConstantVector::get(ArrayRef<Constant*> V) {
break;
}
}
-
+
if (isZero)
return ConstantAggregateZero::get(T);
if (isUndef)
return UndefValue::get(T);
-
+
// Check to see if all of the elements are ConstantFP or ConstantInt and if
// the element type is compatible with ConstantDataVector. If so, use it.
if (ConstantDataSequential::isElementTypeCompatible(C->getType())) {
@@ -932,7 +932,7 @@ Constant *ConstantVector::get(ArrayRef<Constant*> V) {
return ConstantDataVector::get(C->getContext(), Elts);
}
}
-
+
if (ConstantFP *CFP = dyn_cast<ConstantFP>(C)) {
if (CFP->getType()->isFloatTy()) {
SmallVector<float, 16> Elts;
@@ -955,7 +955,7 @@ Constant *ConstantVector::get(ArrayRef<Constant*> V) {
}
}
}
-
+
// Otherwise, the element type isn't compatible with ConstantDataVector, or
// the operand list constants a ConstantExpr or something else strange.
return pImpl->VectorConstants.getOrCreate(T, V);
@@ -967,7 +967,7 @@ Constant *ConstantVector::getSplat(unsigned NumElts, Constant *V) {
if ((isa<ConstantFP>(V) || isa<ConstantInt>(V)) &&
ConstantDataSequential::isElementTypeCompatible(V->getType()))
return ConstantDataVector::getSplat(NumElts, V);
-
+
SmallVector<Constant*, 32> Elts(NumElts, V);
return get(Elts);
}
@@ -1039,7 +1039,7 @@ ConstantExpr::getWithOperandReplaced(unsigned OpNo, Constant *Op) const {
SmallVector<Constant*, 8> NewOps;
for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
NewOps.push_back(i == OpNo ? Op : getOperand(i));
-
+
return getWithOperands(NewOps);
}
@@ -1052,7 +1052,7 @@ getWithOperands(ArrayRef<Constant*> Ops, Type *Ty) const {
bool AnyChange = Ty != getType();
for (unsigned i = 0; i != Ops.size(); ++i)
AnyChange |= Ops[i] != getOperand(i);
-
+
if (!AnyChange) // No operands changed, return self.
return const_cast<ConstantExpr*>(this);
@@ -1177,7 +1177,7 @@ ConstantAggregateZero *ConstantAggregateZero::get(Type *Ty) {
ConstantAggregateZero *&Entry = Ty->getContext().pImpl->CAZConstants[Ty];
if (Entry == 0)
Entry = new ConstantAggregateZero(Ty);
-
+
return Entry;
}
@@ -1232,7 +1232,7 @@ ConstantPointerNull *ConstantPointerNull::get(PointerType *Ty) {
ConstantPointerNull *&Entry = Ty->getContext().pImpl->CPNConstants[Ty];
if (Entry == 0)
Entry = new ConstantPointerNull(Ty);
-
+
return Entry;
}
@@ -1252,7 +1252,7 @@ UndefValue *UndefValue::get(Type *Ty) {
UndefValue *&Entry = Ty->getContext().pImpl->UVConstants[Ty];
if (Entry == 0)
Entry = new UndefValue(Ty);
-
+
return Entry;
}
@@ -1277,7 +1277,7 @@ BlockAddress *BlockAddress::get(Function *F, BasicBlock *BB) {
F->getContext().pImpl->BlockAddresses[std::make_pair(F, BB)];
if (BA == 0)
BA = new BlockAddress(F, BB);
-
+
assert(BA->getFunction() == F && "Basic block moved between functions");
return BA;
}
@@ -1305,19 +1305,19 @@ void BlockAddress::replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) {
// case, we have to remove the map entry.
Function *NewF = getFunction();
BasicBlock *NewBB = getBasicBlock();
-
+
if (U == &Op<0>())
NewF = cast<Function>(To);
else
NewBB = cast<BasicBlock>(To);
-
+
// See if the 'new' entry already exists, if not, just update this in place
// and return early.
BlockAddress *&NewBA =
getContext().pImpl->BlockAddresses[std::make_pair(NewF, NewBB)];
if (NewBA == 0) {
getBasicBlock()->AdjustBlockAddressRefCount(-1);
-
+
// Remove the old entry, this can't cause the map to rehash (just a
// tombstone will get added).
getContext().pImpl->BlockAddresses.erase(std::make_pair(getFunction(),
@@ -1331,10 +1331,10 @@ void BlockAddress::replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) {
// Otherwise, I do need to replace this with an existing value.
assert(NewBA != this && "I didn't contain From!");
-
+
// Everyone using this now uses the replacement.
replaceAllUsesWith(NewBA);
-
+
destroyConstant();
}
@@ -1355,10 +1355,10 @@ static inline Constant *getFoldedCast(
// Look up the constant in the table first to ensure uniqueness
std::vector<Constant*> argVec(1, C);
ExprMapKeyType Key(opc, argVec);
-
+
return pImpl->ExprConstants.getOrCreate(Ty, Key);
}
-
+
Constant *ConstantExpr::getCast(unsigned oc, Constant *C, Type *Ty) {
Instruction::CastOps opc = Instruction::CastOps(oc);
assert(Instruction::isCast(opc) && "opcode out of range");
@@ -1381,7 +1381,7 @@ Constant *ConstantExpr::getCast(unsigned oc, Constant *C, Type *Ty) {
case Instruction::IntToPtr: return getIntToPtr(C, Ty);
case Instruction::BitCast: return getBitCast(C, Ty);
}
-}
+}
Constant *ConstantExpr::getZExtOrBitCast(Constant *C, Type *Ty) {
if (C->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits())
@@ -1572,11 +1572,11 @@ Constant *ConstantExpr::getIntToPtr(Constant *C, Type *DstTy) {
Constant *ConstantExpr::getBitCast(Constant *C, Type *DstTy) {
assert(CastInst::castIsValid(Instruction::BitCast, C, DstTy) &&
"Invalid constantexpr bitcast!");
-
+
// It is common to ask for a bitcast of a value to its own type, handle this
// speedily.
if (C->getType() == DstTy) return C;
-
+
return getFoldedCast(Instruction::BitCast, C, DstTy);
}
@@ -1588,7 +1588,7 @@ Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2,
"Invalid opcode in binary constant expression");
assert(C1->getType() == C2->getType() &&
"Operand types in binary constant expression should match");
-
+
#ifndef NDEBUG
switch (Opcode) {
case Instruction::Add:
@@ -1649,11 +1649,11 @@ Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2,
if (Constant *FC = ConstantFoldBinaryInstruction(Opcode, C1, C2))
return FC; // Fold a few common cases.
-
+
std::vector<Constant*> argVec(1, C1);
argVec.push_back(C2);
ExprMapKeyType Key(Opcode, argVec, 0, Flags);
-
+
LLVMContextImpl *pImpl = C1->getContext().pImpl;
return pImpl->ExprConstants.getOrCreate(C1->getType(), Key);
}
@@ -1703,7 +1703,7 @@ Constant *ConstantExpr::getOffsetOf(Type* Ty, Constant *FieldNo) {
Constant *ConstantExpr::getCompare(unsigned short Predicate,
Constant *C1, Constant *C2) {
assert(C1->getType() == C2->getType() && "Op types should be identical!");
-
+
switch (Predicate) {
default: llvm_unreachable("Invalid CmpInst predicate");
case CmpInst::FCMP_FALSE: case CmpInst::FCMP_OEQ: case CmpInst::FCMP_OGT:
@@ -1713,7 +1713,7 @@ Constant *ConstantExpr::getCompare(unsigned short Predicate,
case CmpInst::FCMP_ULT: case CmpInst::FCMP_ULE: case CmpInst::FCMP_UNE:
case CmpInst::FCMP_TRUE:
return getFCmp(Predicate, C1, C2);
-
+
case CmpInst::ICMP_EQ: case CmpInst::ICMP_NE: case CmpInst::ICMP_UGT:
case CmpInst::ICMP_UGE: case CmpInst::ICMP_ULT: case CmpInst::ICMP_ULE:
case CmpInst::ICMP_SGT: case CmpInst::ICMP_SGE: case CmpInst::ICMP_SLT:
@@ -1732,7 +1732,7 @@ Constant *ConstantExpr::getSelect(Constant *C, Constant *V1, Constant *V2) {
argVec[1] = V1;
argVec[2] = V2;
ExprMapKeyType Key(Instruction::Select, argVec);
-
+
LLVMContextImpl *pImpl = C->getContext().pImpl;
return pImpl->ExprConstants.getOrCreate(V1->getType(), Key);
}
@@ -1747,7 +1747,7 @@ Constant *ConstantExpr::getGetElementPtr(Constant *C, ArrayRef<Value *> Idxs,
assert(Ty && "GEP indices invalid!");
unsigned AS = C->getType()->getPointerAddressSpace();
Type *ReqTy = Ty->getPointerTo(AS);
-
+
assert(C->getType()->isPointerTy() &&
"Non-pointer type for constant GetElementPtr expression");
// Look up the constant in the table first to ensure uniqueness
@@ -1758,7 +1758,7 @@ Constant *ConstantExpr::getGetElementPtr(Constant *C, ArrayRef<Value *> Idxs,
ArgVec.push_back(cast<Constant>(Idxs[i]));
const ExprMapKeyType Key(Instruction::GetElementPtr, ArgVec, 0,
InBounds ? GEPOperator::IsInBounds : 0);
-
+
LLVMContextImpl *pImpl = C->getContext().pImpl;
return pImpl->ExprConstants.getOrCreate(ReqTy, Key);
}
@@ -1815,15 +1815,15 @@ Constant *ConstantExpr::getExtractElement(Constant *Val, Constant *Idx) {
"Tried to create extractelement operation on non-vector type!");
assert(Idx->getType()->isIntegerTy(32) &&
"Extractelement index must be i32 type!");
-
+
if (Constant *FC = ConstantFoldExtractElementInstruction(Val, Idx))
return FC; // Fold a few common cases.
-
+
// Look up the constant in the table first to ensure uniqueness
std::vector<Constant*> ArgVec(1, Val);
ArgVec.push_back(Idx);
const ExprMapKeyType Key(Instruction::ExtractElement,ArgVec);
-
+
LLVMContextImpl *pImpl = Val->getContext().pImpl;
Type *ReqTy = Val->getType()->getVectorElementType();
return pImpl->ExprConstants.getOrCreate(ReqTy, Key);
@@ -1845,7 +1845,7 @@ Constant *ConstantExpr::getInsertElement(Constant *Val, Constant *Elt,
ArgVec.push_back(Elt);
ArgVec.push_back(Idx);
const ExprMapKeyType Key(Instruction::InsertElement,ArgVec);
-
+
LLVMContextImpl *pImpl = Val->getContext().pImpl;
return pImpl->ExprConstants.getOrCreate(Val->getType(), Key);
}
@@ -1867,7 +1867,7 @@ Constant *ConstantExpr::getShuffleVector(Constant *V1, Constant *V2,
ArgVec.push_back(V2);
ArgVec.push_back(Mask);
const ExprMapKeyType Key(Instruction::ShuffleVector,ArgVec);
-
+
LLVMContextImpl *pImpl = ShufTy->getContext().pImpl;
return pImpl->ExprConstants.getOrCreate(ShufTy, Key);
}
@@ -1892,7 +1892,7 @@ Constant *ConstantExpr::getExtractValue(Constant *Agg,
Type *ReqTy = ExtractValueInst::getIndexedType(Agg->getType(), Idxs);
(void)ReqTy;
assert(ReqTy && "extractvalue indices invalid!");
-
+
assert(Agg->getType()->isFirstClassType() &&
"Non-first-class type for constant extractvalue expression");
Constant *FC = ConstantFoldExtractValueInstruction(Agg, Idxs);
@@ -2007,6 +2007,47 @@ Constant *ConstantExpr::getAShr(Constant *C1, Constant *C2, bool isExact) {
isExact ? PossiblyExactOperator::IsExact : 0);
}
+/// getBinOpIdentity - Return the identity for the given binary operation,
+/// i.e. a constant C such that X op C = X and C op X = X for every X. It
+/// returns null if the operator doesn't have an identity.
+Constant *ConstantExpr::getBinOpIdentity(unsigned Opcode, Type *Ty) {
+ switch (Opcode) {
+ default:
+ // Doesn't have an identity.
+ return 0;
+
+ case Instruction::Add:
+ case Instruction::Or:
+ case Instruction::Xor:
+ return Constant::getNullValue(Ty);
+
+ case Instruction::Mul:
+ return ConstantInt::get(Ty, 1);
+
+ case Instruction::And:
+ return Constant::getAllOnesValue(Ty);
+ }
+}
+
+/// getBinOpAbsorber - Return the absorbing element for the given binary
+/// operation, i.e. a constant C such that X op C = C and C op X = C for
+/// every X. For example, this returns zero for integer multiplication.
+/// It returns null if the operator doesn't have an absorbing element.
+Constant *ConstantExpr::getBinOpAbsorber(unsigned Opcode, Type *Ty) {
+ switch (Opcode) {
+ default:
+ // Doesn't have an absorber.
+ return 0;
+
+ case Instruction::Or:
+ return Constant::getAllOnesValue(Ty);
+
+ case Instruction::And:
+ case Instruction::Mul:
+ return Constant::getNullValue(Ty);
+ }
+}
+
// destroyConstant - Remove the constant from the constant table...
//
void ConstantExpr::destroyConstant() {
@@ -2107,7 +2148,7 @@ Constant *ConstantDataSequential::getImpl(StringRef Elements, Type *Ty) {
// Do a lookup to see if we have already formed one of these.
StringMap<ConstantDataSequential*>::MapEntryTy &Slot =
Ty->getContext().pImpl->CDSConstants.GetOrCreateValue(Elements);
-
+
// The bucket can point to a linked list of different CDS's that have the same
// body but different types. For example, 0,0,0,1 could be a 4 element array
// of i8, or a 1-element array of i32. They'll both end up in the same
@@ -2117,7 +2158,7 @@ Constant *ConstantDataSequential::getImpl(StringRef Elements, Type *Ty) {
Entry = &Node->Next, Node = *Entry)
if (Node->getType() == Ty)
return Node;
-
+
// Okay, we didn't get a hit. Create a node of the right class, link it in,
// and return it.
if (isa<ArrayType>(Ty))
@@ -2131,7 +2172,7 @@ void ConstantDataSequential::destroyConstant() {
// Remove the constant from the StringMap.
StringMap<ConstantDataSequential*> &CDSConstants =
getType()->getContext().pImpl->CDSConstants;
-
+
StringMap<ConstantDataSequential*>::iterator Slot =
CDSConstants.find(getRawDataValues());
@@ -2158,11 +2199,11 @@ void ConstantDataSequential::destroyConstant() {
}
}
}
-
+
// If we were part of a list, make sure that we don't delete the list that is
// still owned by the uniquing map.
Next = 0;
-
+
// Finally, actually delete it.
destroyConstantImpl();
}
@@ -2172,27 +2213,33 @@ void ConstantDataSequential::destroyConstant() {
/// can return a ConstantAggregateZero object.
Constant *ConstantDataArray::get(LLVMContext &Context, ArrayRef<uint8_t> Elts) {
Type *Ty = ArrayType::get(Type::getInt8Ty(Context), Elts.size());
- return getImpl(StringRef((char*)Elts.data(), Elts.size()*1), Ty);
+ const char *Data = reinterpret_cast<const char *>(Elts.data());
+ return getImpl(StringRef(const_cast<char *>(Data), Elts.size()*1), Ty);
}
Constant *ConstantDataArray::get(LLVMContext &Context, ArrayRef<uint16_t> Elts){
Type *Ty = ArrayType::get(Type::getInt16Ty(Context), Elts.size());
- return getImpl(StringRef((char*)Elts.data(), Elts.size()*2), Ty);
+ const char *Data = reinterpret_cast<const char *>(Elts.data());
+ return getImpl(StringRef(const_cast<char *>(Data), Elts.size()*2), Ty);
}
Constant *ConstantDataArray::get(LLVMContext &Context, ArrayRef<uint32_t> Elts){
Type *Ty = ArrayType::get(Type::getInt32Ty(Context), Elts.size());
- return getImpl(StringRef((char*)Elts.data(), Elts.size()*4), Ty);
+ const char *Data = reinterpret_cast<const char *>(Elts.data());
+ return getImpl(StringRef(const_cast<char *>(Data), Elts.size()*4), Ty);
}
Constant *ConstantDataArray::get(LLVMContext &Context, ArrayRef<uint64_t> Elts){
Type *Ty = ArrayType::get(Type::getInt64Ty(Context), Elts.size());
- return getImpl(StringRef((char*)Elts.data(), Elts.size()*8), Ty);
+ const char *Data = reinterpret_cast<const char *>(Elts.data());
+ return getImpl(StringRef(const_cast<char *>(Data), Elts.size()*8), Ty);
}
Constant *ConstantDataArray::get(LLVMContext &Context, ArrayRef<float> Elts) {
Type *Ty = ArrayType::get(Type::getFloatTy(Context), Elts.size());
- return getImpl(StringRef((char*)Elts.data(), Elts.size()*4), Ty);
+ const char *Data = reinterpret_cast<const char *>(Elts.data());
+ return getImpl(StringRef(const_cast<char *>(Data), Elts.size()*4), Ty);
}
Constant *ConstantDataArray::get(LLVMContext &Context, ArrayRef<double> Elts) {
Type *Ty = ArrayType::get(Type::getDoubleTy(Context), Elts.size());
- return getImpl(StringRef((char*)Elts.data(), Elts.size()*8), Ty);
+ const char *Data = reinterpret_cast<const char *>(Elts.data());
+ return getImpl(StringRef(const_cast<char *>(Data), Elts.size()*8), Ty);
}
/// getString - This method constructs a CDS and initializes it with a text
@@ -2202,9 +2249,12 @@ Constant *ConstantDataArray::get(LLVMContext &Context, ArrayRef<double> Elts) {
/// to disable this behavior.
Constant *ConstantDataArray::getString(LLVMContext &Context,
StringRef Str, bool AddNull) {
- if (!AddNull)
- return get(Context, ArrayRef<uint8_t>((uint8_t*)Str.data(), Str.size()));
-
+ if (!AddNull) {
+ const uint8_t *Data = reinterpret_cast<const uint8_t *>(Str.data());
+ return get(Context, ArrayRef<uint8_t>(const_cast<uint8_t *>(Data),
+ Str.size()));
+ }
+
SmallVector<uint8_t, 64> ElementVals;
ElementVals.append(Str.begin(), Str.end());
ElementVals.push_back(0);
@@ -2216,27 +2266,33 @@ Constant *ConstantDataArray::getString(LLVMContext &Context,
/// can return a ConstantAggregateZero object.
Constant *ConstantDataVector::get(LLVMContext &Context, ArrayRef<uint8_t> Elts){
Type *Ty = VectorType::get(Type::getInt8Ty(Context), Elts.size());
- return getImpl(StringRef((char*)Elts.data(), Elts.size()*1), Ty);
+ const char *Data = reinterpret_cast<const char *>(Elts.data());
+ return getImpl(StringRef(const_cast<char *>(Data), Elts.size()*1), Ty);
}
Constant *ConstantDataVector::get(LLVMContext &Context, ArrayRef<uint16_t> Elts){
Type *Ty = VectorType::get(Type::getInt16Ty(Context), Elts.size());
- return getImpl(StringRef((char*)Elts.data(), Elts.size()*2), Ty);
+ const char *Data = reinterpret_cast<const char *>(Elts.data());
+ return getImpl(StringRef(const_cast<char *>(Data), Elts.size()*2), Ty);
}
Constant *ConstantDataVector::get(LLVMContext &Context, ArrayRef<uint32_t> Elts){
Type *Ty = VectorType::get(Type::getInt32Ty(Context), Elts.size());
- return getImpl(StringRef((char*)Elts.data(), Elts.size()*4), Ty);
+ const char *Data = reinterpret_cast<const char *>(Elts.data());
+ return getImpl(StringRef(const_cast<char *>(Data), Elts.size()*4), Ty);
}
Constant *ConstantDataVector::get(LLVMContext &Context, ArrayRef<uint64_t> Elts){
Type *Ty = VectorType::get(Type::getInt64Ty(Context), Elts.size());
- return getImpl(StringRef((char*)Elts.data(), Elts.size()*8), Ty);
+ const char *Data = reinterpret_cast<const char *>(Elts.data());
+ return getImpl(StringRef(const_cast<char *>(Data), Elts.size()*8), Ty);
}
Constant *ConstantDataVector::get(LLVMContext &Context, ArrayRef<float> Elts) {
Type *Ty = VectorType::get(Type::getFloatTy(Context), Elts.size());
- return getImpl(StringRef((char*)Elts.data(), Elts.size()*4), Ty);
+ const char *Data = reinterpret_cast<const char *>(Elts.data());
+ return getImpl(StringRef(const_cast<char *>(Data), Elts.size()*4), Ty);
}
Constant *ConstantDataVector::get(LLVMContext &Context, ArrayRef<double> Elts) {
Type *Ty = VectorType::get(Type::getDoubleTy(Context), Elts.size());
- return getImpl(StringRef((char*)Elts.data(), Elts.size()*8), Ty);
+ const char *Data = reinterpret_cast<const char *>(Elts.data());
+ return getImpl(StringRef(const_cast<char *>(Data), Elts.size()*8), Ty);
}
Constant *ConstantDataVector::getSplat(unsigned NumElts, Constant *V) {
@@ -2281,15 +2337,19 @@ uint64_t ConstantDataSequential::getElementAsInteger(unsigned Elt) const {
assert(isa<IntegerType>(getElementType()) &&
"Accessor can only be used when element is an integer");
const char *EltPtr = getElementPointer(Elt);
-
+
// The data is stored in host byte order, make sure to cast back to the right
// type to load with the right endianness.
switch (getElementType()->getIntegerBitWidth()) {
default: llvm_unreachable("Invalid bitwidth for CDS");
- case 8: return *(uint8_t*)EltPtr;
- case 16: return *(uint16_t*)EltPtr;
- case 32: return *(uint32_t*)EltPtr;
- case 64: return *(uint64_t*)EltPtr;
+ case 8:
+ return *const_cast<uint8_t *>(reinterpret_cast<const uint8_t *>(EltPtr));
+ case 16:
+ return *const_cast<uint16_t *>(reinterpret_cast<const uint16_t *>(EltPtr));
+ case 32:
+ return *const_cast<uint32_t *>(reinterpret_cast<const uint32_t *>(EltPtr));
+ case 64:
+ return *const_cast<uint64_t *>(reinterpret_cast<const uint64_t *>(EltPtr));
}
}
@@ -2301,8 +2361,14 @@ APFloat ConstantDataSequential::getElementAsAPFloat(unsigned Elt) const {
switch (getElementType()->getTypeID()) {
default:
llvm_unreachable("Accessor can only be used when element is float/double!");
- case Type::FloatTyID: return APFloat(*(float*)EltPtr);
- case Type::DoubleTyID: return APFloat(*(double*)EltPtr);
+ case Type::FloatTyID: {
+ const float *FloatPrt = reinterpret_cast<const float *>(EltPtr);
+ return APFloat(*const_cast<float *>(FloatPrt));
+ }
+ case Type::DoubleTyID: {
+ const double *DoublePtr = reinterpret_cast<const double *>(EltPtr);
+ return APFloat(*const_cast<double *>(DoublePtr));
+ }
}
}
@@ -2311,7 +2377,8 @@ APFloat ConstantDataSequential::getElementAsAPFloat(unsigned Elt) const {
float ConstantDataSequential::getElementAsFloat(unsigned Elt) const {
assert(getElementType()->isFloatTy() &&
"Accessor can only be used when element is a 'float'");
- return *(float*)getElementPointer(Elt);
+ const float *EltPtr = reinterpret_cast<const float *>(getElementPointer(Elt));
+ return *const_cast<float *>(EltPtr);
}
/// getElementAsDouble - If this is an sequential container of doubles, return
@@ -2319,7 +2386,9 @@ float ConstantDataSequential::getElementAsFloat(unsigned Elt) const {
double ConstantDataSequential::getElementAsDouble(unsigned Elt) const {
assert(getElementType()->isDoubleTy() &&
"Accessor can only be used when element is a 'float'");
- return *(double*)getElementPointer(Elt);
+ const double *EltPtr =
+ reinterpret_cast<const double *>(getElementPointer(Elt));
+ return *const_cast<double *>(EltPtr);
}
/// getElementAsConstant - Return a Constant for a specified index's element.
@@ -2328,7 +2397,7 @@ double ConstantDataSequential::getElementAsDouble(unsigned Elt) const {
Constant *ConstantDataSequential::getElementAsConstant(unsigned Elt) const {
if (getElementType()->isFloatTy() || getElementType()->isDoubleTy())
return ConstantFP::get(getContext(), getElementAsAPFloat(Elt));
-
+
return ConstantInt::get(getElementType(), getElementAsInteger(Elt));
}
@@ -2342,12 +2411,12 @@ bool ConstantDataSequential::isString() const {
bool ConstantDataSequential::isCString() const {
if (!isString())
return false;
-
+
StringRef Str = getAsString();
-
+
// The last value must be nul.
if (Str.back() != 0) return false;
-
+
// Other elements must be non-nul.
return Str.drop_back().find(0) == StringRef::npos;
}
@@ -2356,13 +2425,13 @@ bool ConstantDataSequential::isCString() const {
/// elements have the same value, return that value. Otherwise return NULL.
Constant *ConstantDataVector::getSplatValue() const {
const char *Base = getRawDataValues().data();
-
+
// Compare elements 1+ to the 0'th element.
unsigned EltSize = getElementByteSize();
for (unsigned i = 1, e = getNumElements(); i != e; ++i)
if (memcmp(Base, Base+i*EltSize, EltSize))
return 0;
-
+
// If they're all the same, return the 0th one as a representative.
return getElementAsConstant(0);
}
@@ -2393,10 +2462,10 @@ void ConstantArray::replaceUsesOfWithOnConstant(Value *From, Value *To,
Lookup.first = cast<ArrayType>(getType());
Values.reserve(getNumOperands()); // Build replacement array.
- // Fill values with the modified operands of the constant array. Also,
+ // Fill values with the modified operands of the constant array. Also,
// compute whether this turns into an all-zeros array.
unsigned NumUpdated = 0;
-
+
// Keep track of whether all the values in the array are "ToC".
bool AllSame = true;
for (Use *O = OperandList, *E = OperandList+getNumOperands(); O != E; ++O) {
@@ -2408,7 +2477,7 @@ void ConstantArray::replaceUsesOfWithOnConstant(Value *From, Value *To,
Values.push_back(Val);
AllSame &= Val == ToC;
}
-
+
Constant *Replacement = 0;
if (AllSame && ToC->isNullValue()) {
Replacement = ConstantAggregateZero::get(getType());
@@ -2419,7 +2488,7 @@ void ConstantArray::replaceUsesOfWithOnConstant(Value *From, Value *To,
Lookup.second = makeArrayRef(Values);
LLVMContextImpl::ArrayConstantsTy::MapTy::iterator I =
pImpl->ArrayConstants.find(Lookup);
-
+
if (I != pImpl->ArrayConstants.map_end()) {
Replacement = I->first;
} else {
@@ -2428,7 +2497,7 @@ void ConstantArray::replaceUsesOfWithOnConstant(Value *From, Value *To,
// old with the new, then deleting the old... just update the current one
// in place!
pImpl->ArrayConstants.remove(this);
-
+
// Update to the new value. Optimize for the case when we have a single
// operand that we're changing, but handle bulk updates efficiently.
if (NumUpdated == 1) {
@@ -2445,13 +2514,13 @@ void ConstantArray::replaceUsesOfWithOnConstant(Value *From, Value *To,
return;
}
}
-
+
// Otherwise, I do need to replace this with an existing value.
assert(Replacement != this && "I didn't contain From!");
-
+
// Everyone using this now uses the replacement.
replaceAllUsesWith(Replacement);
-
+
// Delete the old constant!
destroyConstant();
}
@@ -2468,8 +2537,8 @@ void ConstantStruct::replaceUsesOfWithOnConstant(Value *From, Value *To,
LLVMContextImpl::StructConstantsTy::LookupKey Lookup;
Lookup.first = cast<StructType>(getType());
Values.reserve(getNumOperands()); // Build replacement struct.
-
- // Fill values with the modified operands of the constant struct. Also,
+
+ // Fill values with the modified operands of the constant struct. Also,
// compute whether this turns into an all-zeros struct.
bool isAllZeros = false;
bool isAllUndef = false;
@@ -2492,9 +2561,9 @@ void ConstantStruct::replaceUsesOfWithOnConstant(Value *From, Value *To,
Values.push_back(cast<Constant>(O->get()));
}
Values[OperandToUpdate] = ToC;
-
+
LLVMContextImpl *pImpl = getContext().pImpl;
-
+
Constant *Replacement = 0;
if (isAllZeros) {
Replacement = ConstantAggregateZero::get(getType());
@@ -2505,7 +2574,7 @@ void ConstantStruct::replaceUsesOfWithOnConstant(Value *From, Value *To,
Lookup.second = makeArrayRef(Values);
LLVMContextImpl::StructConstantsTy::MapTy::iterator I =
pImpl->StructConstants.find(Lookup);
-
+
if (I != pImpl->StructConstants.map_end()) {
Replacement = I->first;
} else {
@@ -2514,19 +2583,19 @@ void ConstantStruct::replaceUsesOfWithOnConstant(Value *From, Value *To,
// old with the new, then deleting the old... just update the current one
// in place!
pImpl->StructConstants.remove(this);
-
+
// Update to the new value.
setOperand(OperandToUpdate, ToC);
pImpl->StructConstants.insert(this);
return;
}
}
-
+
assert(Replacement != this && "I didn't contain From!");
-
+
// Everyone using this now uses the replacement.
replaceAllUsesWith(Replacement);
-
+
// Delete the old constant!
destroyConstant();
}
@@ -2534,7 +2603,7 @@ void ConstantStruct::replaceUsesOfWithOnConstant(Value *From, Value *To,
void ConstantVector::replaceUsesOfWithOnConstant(Value *From, Value *To,
Use *U) {
assert(isa<Constant>(To) && "Cannot make Constant refer to non-constant!");
-
+
SmallVector<Constant*, 8> Values;
Values.reserve(getNumOperands()); // Build replacement array...
for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
@@ -2542,13 +2611,13 @@ void ConstantVector::replaceUsesOfWithOnConstant(Value *From, Value *To,
if (Val == From) Val = cast<Constant>(To);
Values.push_back(Val);
}
-
+
Constant *Replacement = get(Values);
assert(Replacement != this && "I didn't contain From!");
-
+
// Everyone using this now uses the replacement.
replaceAllUsesWith(Replacement);
-
+
// Delete the old constant!
destroyConstant();
}
@@ -2557,19 +2626,19 @@ void ConstantExpr::replaceUsesOfWithOnConstant(Value *From, Value *ToV,
Use *U) {
assert(isa<Constant>(ToV) && "Cannot make Constant refer to non-constant!");
Constant *To = cast<Constant>(ToV);
-
+
SmallVector<Constant*, 8> NewOps;
for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
Constant *Op = getOperand(i);
NewOps.push_back(Op == From ? To : Op);
}
-
+
Constant *Replacement = getWithOperands(NewOps);
assert(Replacement != this && "I didn't contain From!");
-
+
// Everyone using this now uses the replacement.
replaceAllUsesWith(Replacement);
-
+
// Delete the old constant!
destroyConstant();
}
diff --git a/lib/VMCore/Core.cpp b/lib/VMCore/Core.cpp
index a9cca22..972db3c 100644
--- a/lib/VMCore/Core.cpp
+++ b/lib/VMCore/Core.cpp
@@ -115,6 +115,25 @@ void LLVMDumpModule(LLVMModuleRef M) {
unwrap(M)->dump();
}
+LLVMBool LLVMPrintModuleToFile(LLVMModuleRef M, const char *Filename,
+ char **ErrorMessage) {
+ std::string error;
+ raw_fd_ostream dest(Filename, error);
+ if (!error.empty()) {
+ *ErrorMessage = strdup(error.c_str());
+ return true;
+ }
+
+ unwrap(M)->print(dest, NULL);
+
+ if (!error.empty()) {
+ *ErrorMessage = strdup(error.c_str());
+ return true;
+ }
+ dest.flush();
+ return false;
+}
+
/*--.. Operations on inline assembler ......................................--*/
void LLVMSetModuleInlineAsm(LLVMModuleRef M, const char *Asm) {
unwrap(M)->setModuleInlineAsm(StringRef(Asm));
@@ -1191,7 +1210,7 @@ LLVMValueRef LLVMAddGlobalInAddressSpace(LLVMModuleRef M, LLVMTypeRef Ty,
unsigned AddressSpace) {
return wrap(new GlobalVariable(*unwrap(M), unwrap(Ty), false,
GlobalValue::ExternalLinkage, 0, Name, 0,
- false, AddressSpace));
+ GlobalVariable::NotThreadLocal, AddressSpace));
}
LLVMValueRef LLVMGetNamedGlobal(LLVMModuleRef M, const char *Name) {
diff --git a/lib/VMCore/DIBuilder.cpp b/lib/VMCore/DIBuilder.cpp
new file mode 100644
index 0000000..f5894e9
--- /dev/null
+++ b/lib/VMCore/DIBuilder.cpp
@@ -0,0 +1,1019 @@
+//===--- DIBuilder.cpp - Debug Information Builder ------------------------===//
+//
+// 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 DIBuilder.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DIBuilder.h"
+#include "llvm/Constants.h"
+#include "llvm/DebugInfo.h"
+#include "llvm/IntrinsicInst.h"
+#include "llvm/Module.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/Dwarf.h"
+
+using namespace llvm;
+using namespace llvm::dwarf;
+
+static Constant *GetTagConstant(LLVMContext &VMContext, unsigned Tag) {
+ assert((Tag & LLVMDebugVersionMask) == 0 &&
+ "Tag too large for debug encoding!");
+ return ConstantInt::get(Type::getInt32Ty(VMContext), Tag | LLVMDebugVersion);
+}
+
+DIBuilder::DIBuilder(Module &m)
+ : M(m), VMContext(M.getContext()), TheCU(0), TempEnumTypes(0),
+ TempRetainTypes(0), TempSubprograms(0), TempGVs(0), DeclareFn(0),
+ ValueFn(0)
+{}
+
+/// finalize - Construct any deferred debug info descriptors.
+void DIBuilder::finalize() {
+ DIArray Enums = getOrCreateArray(AllEnumTypes);
+ DIType(TempEnumTypes).replaceAllUsesWith(Enums);
+
+ DIArray RetainTypes = getOrCreateArray(AllRetainTypes);
+ DIType(TempRetainTypes).replaceAllUsesWith(RetainTypes);
+
+ DIArray SPs = getOrCreateArray(AllSubprograms);
+ DIType(TempSubprograms).replaceAllUsesWith(SPs);
+ for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) {
+ DISubprogram SP(SPs.getElement(i));
+ SmallVector<Value *, 4> Variables;
+ if (NamedMDNode *NMD = getFnSpecificMDNode(M, SP)) {
+ for (unsigned ii = 0, ee = NMD->getNumOperands(); ii != ee; ++ii)
+ Variables.push_back(NMD->getOperand(ii));
+ NMD->eraseFromParent();
+ }
+ if (MDNode *Temp = SP.getVariablesNodes()) {
+ DIArray AV = getOrCreateArray(Variables);
+ DIType(Temp).replaceAllUsesWith(AV);
+ }
+ }
+
+ DIArray GVs = getOrCreateArray(AllGVs);
+ DIType(TempGVs).replaceAllUsesWith(GVs);
+}
+
+/// getNonCompileUnitScope - If N is compile unit return NULL otherwise return
+/// N.
+static MDNode *getNonCompileUnitScope(MDNode *N) {
+ if (DIDescriptor(N).isCompileUnit())
+ return NULL;
+ return N;
+}
+
+/// createCompileUnit - A CompileUnit provides an anchor for all debugging
+/// information generated during this instance of compilation.
+void DIBuilder::createCompileUnit(unsigned Lang, StringRef Filename,
+ StringRef Directory, StringRef Producer,
+ bool isOptimized, StringRef Flags,
+ unsigned RunTimeVer) {
+ assert(((Lang <= dwarf::DW_LANG_Python && Lang >= dwarf::DW_LANG_C89) ||
+ (Lang <= dwarf::DW_LANG_hi_user && Lang >= dwarf::DW_LANG_lo_user)) &&
+ "Invalid Language tag");
+ assert(!Filename.empty() &&
+ "Unable to create compile unit without filename");
+ Value *TElts[] = { GetTagConstant(VMContext, DW_TAG_base_type) };
+ TempEnumTypes = MDNode::getTemporary(VMContext, TElts);
+ Value *THElts[] = { TempEnumTypes };
+ MDNode *EnumHolder = MDNode::get(VMContext, THElts);
+
+ TempRetainTypes = MDNode::getTemporary(VMContext, TElts);
+ Value *TRElts[] = { TempRetainTypes };
+ MDNode *RetainHolder = MDNode::get(VMContext, TRElts);
+
+ TempSubprograms = MDNode::getTemporary(VMContext, TElts);
+ Value *TSElts[] = { TempSubprograms };
+ MDNode *SPHolder = MDNode::get(VMContext, TSElts);
+
+ TempGVs = MDNode::getTemporary(VMContext, TElts);
+ Value *TVElts[] = { TempGVs };
+ MDNode *GVHolder = MDNode::get(VMContext, TVElts);
+
+ Value *Elts[] = {
+ GetTagConstant(VMContext, dwarf::DW_TAG_compile_unit),
+ Constant::getNullValue(Type::getInt32Ty(VMContext)),
+ ConstantInt::get(Type::getInt32Ty(VMContext), Lang),
+ MDString::get(VMContext, Filename),
+ MDString::get(VMContext, Directory),
+ MDString::get(VMContext, Producer),
+ // Deprecate isMain field.
+ ConstantInt::get(Type::getInt1Ty(VMContext), true), // isMain
+ ConstantInt::get(Type::getInt1Ty(VMContext), isOptimized),
+ MDString::get(VMContext, Flags),
+ ConstantInt::get(Type::getInt32Ty(VMContext), RunTimeVer),
+ EnumHolder,
+ RetainHolder,
+ SPHolder,
+ GVHolder
+ };
+ TheCU = DICompileUnit(MDNode::get(VMContext, Elts));
+
+ // Create a named metadata so that it is easier to find cu in a module.
+ NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.dbg.cu");
+ NMD->addOperand(TheCU);
+}
+
+/// createFile - Create a file descriptor to hold debugging information
+/// for a file.
+DIFile DIBuilder::createFile(StringRef Filename, StringRef Directory) {
+ assert(TheCU && "Unable to create DW_TAG_file_type without CompileUnit");
+ assert(!Filename.empty() && "Unable to create file without name");
+ Value *Elts[] = {
+ GetTagConstant(VMContext, dwarf::DW_TAG_file_type),
+ MDString::get(VMContext, Filename),
+ MDString::get(VMContext, Directory),
+ NULL // TheCU
+ };
+ return DIFile(MDNode::get(VMContext, Elts));
+}
+
+/// createEnumerator - Create a single enumerator value.
+DIEnumerator DIBuilder::createEnumerator(StringRef Name, uint64_t Val) {
+ assert(!Name.empty() && "Unable to create enumerator without name");
+ Value *Elts[] = {
+ GetTagConstant(VMContext, dwarf::DW_TAG_enumerator),
+ MDString::get(VMContext, Name),
+ ConstantInt::get(Type::getInt64Ty(VMContext), Val)
+ };
+ return DIEnumerator(MDNode::get(VMContext, Elts));
+}
+
+/// createNullPtrType - Create C++0x nullptr type.
+DIType DIBuilder::createNullPtrType(StringRef Name) {
+ assert(!Name.empty() && "Unable to create type without name");
+ // nullptr is encoded in DIBasicType format. Line number, filename,
+ // ,size, alignment, offset and flags are always empty here.
+ Value *Elts[] = {
+ GetTagConstant(VMContext, dwarf::DW_TAG_unspecified_type),
+ NULL, //TheCU,
+ MDString::get(VMContext, Name),
+ NULL, // Filename
+ ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Line
+ ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Size
+ ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Align
+ ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Offset
+ ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Flags;
+ ConstantInt::get(Type::getInt32Ty(VMContext), 0) // Encoding
+ };
+ return DIType(MDNode::get(VMContext, Elts));
+}
+
+/// createBasicType - Create debugging information entry for a basic
+/// type, e.g 'char'.
+DIType DIBuilder::createBasicType(StringRef Name, uint64_t SizeInBits,
+ uint64_t AlignInBits,
+ unsigned Encoding) {
+ assert(!Name.empty() && "Unable to create type without name");
+ // Basic types are encoded in DIBasicType format. Line number, filename,
+ // offset and flags are always empty here.
+ Value *Elts[] = {
+ GetTagConstant(VMContext, dwarf::DW_TAG_base_type),
+ NULL, //TheCU,
+ MDString::get(VMContext, Name),
+ NULL, // Filename
+ ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Line
+ ConstantInt::get(Type::getInt64Ty(VMContext), SizeInBits),
+ ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits),
+ ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Offset
+ ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Flags;
+ ConstantInt::get(Type::getInt32Ty(VMContext), Encoding)
+ };
+ return DIType(MDNode::get(VMContext, Elts));
+}
+
+/// createQualifiedType - Create debugging information entry for a qualified
+/// type, e.g. 'const int'.
+DIType DIBuilder::createQualifiedType(unsigned Tag, DIType FromTy) {
+ // Qualified types are encoded in DIDerivedType format.
+ Value *Elts[] = {
+ GetTagConstant(VMContext, Tag),
+ NULL, //TheCU,
+ MDString::get(VMContext, StringRef()), // Empty name.
+ NULL, // Filename
+ ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Line
+ ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Size
+ ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Align
+ ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Offset
+ ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Flags
+ FromTy
+ };
+ return DIType(MDNode::get(VMContext, Elts));
+}
+
+/// createPointerType - Create debugging information entry for a pointer.
+DIType DIBuilder::createPointerType(DIType PointeeTy, uint64_t SizeInBits,
+ uint64_t AlignInBits, StringRef Name) {
+ // Pointer types are encoded in DIDerivedType format.
+ Value *Elts[] = {
+ GetTagConstant(VMContext, dwarf::DW_TAG_pointer_type),
+ NULL, //TheCU,
+ MDString::get(VMContext, Name),
+ NULL, // Filename
+ ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Line
+ ConstantInt::get(Type::getInt64Ty(VMContext), SizeInBits),
+ ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits),
+ ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Offset
+ ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Flags
+ PointeeTy
+ };
+ return DIType(MDNode::get(VMContext, Elts));
+}
+
+/// createReferenceType - Create debugging information entry for a reference
+/// type.
+DIType DIBuilder::createReferenceType(unsigned Tag, DIType RTy) {
+ assert(RTy.Verify() && "Unable to create reference type");
+ // References are encoded in DIDerivedType format.
+ Value *Elts[] = {
+ GetTagConstant(VMContext, Tag),
+ NULL, // TheCU,
+ NULL, // Name
+ NULL, // Filename
+ ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Line
+ ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Size
+ ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Align
+ ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Offset
+ ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Flags
+ RTy
+ };
+ return DIType(MDNode::get(VMContext, Elts));
+}
+
+/// createTypedef - Create debugging information entry for a typedef.
+DIType DIBuilder::createTypedef(DIType Ty, StringRef Name, DIFile File,
+ unsigned LineNo, DIDescriptor Context) {
+ // typedefs are encoded in DIDerivedType format.
+ assert(Ty.Verify() && "Invalid typedef type!");
+ Value *Elts[] = {
+ GetTagConstant(VMContext, dwarf::DW_TAG_typedef),
+ getNonCompileUnitScope(Context),
+ MDString::get(VMContext, Name),
+ File,
+ ConstantInt::get(Type::getInt32Ty(VMContext), LineNo),
+ ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Size
+ ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Align
+ ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Offset
+ ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Flags
+ Ty
+ };
+ return DIType(MDNode::get(VMContext, Elts));
+}
+
+/// createFriend - Create debugging information entry for a 'friend'.
+DIType DIBuilder::createFriend(DIType Ty, DIType FriendTy) {
+ // typedefs are encoded in DIDerivedType format.
+ assert(Ty.Verify() && "Invalid type!");
+ assert(FriendTy.Verify() && "Invalid friend type!");
+ Value *Elts[] = {
+ GetTagConstant(VMContext, dwarf::DW_TAG_friend),
+ Ty,
+ NULL, // Name
+ Ty.getFile(),
+ ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Line
+ ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Size
+ ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Align
+ ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Offset
+ ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Flags
+ FriendTy
+ };
+ return DIType(MDNode::get(VMContext, Elts));
+}
+
+/// createInheritance - Create debugging information entry to establish
+/// inheritance relationship between two types.
+DIType DIBuilder::createInheritance(DIType Ty, DIType BaseTy,
+ uint64_t BaseOffset, unsigned Flags) {
+ assert(Ty.Verify() && "Unable to create inheritance");
+ // TAG_inheritance is encoded in DIDerivedType format.
+ Value *Elts[] = {
+ GetTagConstant(VMContext, dwarf::DW_TAG_inheritance),
+ Ty,
+ NULL, // Name
+ Ty.getFile(),
+ ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Line
+ ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Size
+ ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Align
+ ConstantInt::get(Type::getInt64Ty(VMContext), BaseOffset),
+ ConstantInt::get(Type::getInt32Ty(VMContext), Flags),
+ BaseTy
+ };
+ return DIType(MDNode::get(VMContext, Elts));
+}
+
+/// createMemberType - Create debugging information entry for a member.
+DIType DIBuilder::createMemberType(DIDescriptor Scope, StringRef Name,
+ DIFile File, unsigned LineNumber,
+ uint64_t SizeInBits, uint64_t AlignInBits,
+ uint64_t OffsetInBits, unsigned Flags,
+ DIType Ty) {
+ // TAG_member is encoded in DIDerivedType format.
+ Value *Elts[] = {
+ GetTagConstant(VMContext, dwarf::DW_TAG_member),
+ getNonCompileUnitScope(Scope),
+ MDString::get(VMContext, Name),
+ File,
+ ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber),
+ ConstantInt::get(Type::getInt64Ty(VMContext), SizeInBits),
+ ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits),
+ ConstantInt::get(Type::getInt64Ty(VMContext), OffsetInBits),
+ ConstantInt::get(Type::getInt32Ty(VMContext), Flags),
+ Ty
+ };
+ return DIType(MDNode::get(VMContext, Elts));
+}
+
+/// createObjCIVar - Create debugging information entry for Objective-C
+/// instance variable.
+DIType DIBuilder::createObjCIVar(StringRef Name,
+ DIFile File, unsigned LineNumber,
+ uint64_t SizeInBits, uint64_t AlignInBits,
+ uint64_t OffsetInBits, unsigned Flags,
+ DIType Ty, StringRef PropertyName,
+ StringRef GetterName, StringRef SetterName,
+ unsigned PropertyAttributes) {
+ // TAG_member is encoded in DIDerivedType format.
+ Value *Elts[] = {
+ GetTagConstant(VMContext, dwarf::DW_TAG_member),
+ getNonCompileUnitScope(File),
+ MDString::get(VMContext, Name),
+ File,
+ ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber),
+ ConstantInt::get(Type::getInt64Ty(VMContext), SizeInBits),
+ ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits),
+ ConstantInt::get(Type::getInt64Ty(VMContext), OffsetInBits),
+ ConstantInt::get(Type::getInt32Ty(VMContext), Flags),
+ Ty,
+ MDString::get(VMContext, PropertyName),
+ MDString::get(VMContext, GetterName),
+ MDString::get(VMContext, SetterName),
+ ConstantInt::get(Type::getInt32Ty(VMContext), PropertyAttributes)
+ };
+ return DIType(MDNode::get(VMContext, Elts));
+}
+
+/// createObjCIVar - Create debugging information entry for Objective-C
+/// instance variable.
+DIType DIBuilder::createObjCIVar(StringRef Name,
+ DIFile File, unsigned LineNumber,
+ uint64_t SizeInBits, uint64_t AlignInBits,
+ uint64_t OffsetInBits, unsigned Flags,
+ DIType Ty, MDNode *PropertyNode) {
+ // TAG_member is encoded in DIDerivedType format.
+ Value *Elts[] = {
+ GetTagConstant(VMContext, dwarf::DW_TAG_member),
+ getNonCompileUnitScope(File),
+ MDString::get(VMContext, Name),
+ File,
+ ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber),
+ ConstantInt::get(Type::getInt64Ty(VMContext), SizeInBits),
+ ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits),
+ ConstantInt::get(Type::getInt64Ty(VMContext), OffsetInBits),
+ ConstantInt::get(Type::getInt32Ty(VMContext), Flags),
+ Ty,
+ PropertyNode
+ };
+ return DIType(MDNode::get(VMContext, Elts));
+}
+
+/// createObjCProperty - Create debugging information entry for Objective-C
+/// property.
+DIObjCProperty DIBuilder::createObjCProperty(StringRef Name,
+ DIFile File, unsigned LineNumber,
+ StringRef GetterName,
+ StringRef SetterName,
+ unsigned PropertyAttributes,
+ DIType Ty) {
+ Value *Elts[] = {
+ GetTagConstant(VMContext, dwarf::DW_TAG_APPLE_property),
+ MDString::get(VMContext, Name),
+ File,
+ ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber),
+ MDString::get(VMContext, GetterName),
+ MDString::get(VMContext, SetterName),
+ ConstantInt::get(Type::getInt32Ty(VMContext), PropertyAttributes),
+ Ty
+ };
+ return DIObjCProperty(MDNode::get(VMContext, Elts));
+}
+
+/// createTemplateTypeParameter - Create debugging information for template
+/// type parameter.
+DITemplateTypeParameter
+DIBuilder::createTemplateTypeParameter(DIDescriptor Context, StringRef Name,
+ DIType Ty, MDNode *File, unsigned LineNo,
+ unsigned ColumnNo) {
+ Value *Elts[] = {
+ GetTagConstant(VMContext, dwarf::DW_TAG_template_type_parameter),
+ getNonCompileUnitScope(Context),
+ MDString::get(VMContext, Name),
+ Ty,
+ File,
+ ConstantInt::get(Type::getInt32Ty(VMContext), LineNo),
+ ConstantInt::get(Type::getInt32Ty(VMContext), ColumnNo)
+ };
+ return DITemplateTypeParameter(MDNode::get(VMContext, Elts));
+}
+
+/// createTemplateValueParameter - Create debugging information for template
+/// value parameter.
+DITemplateValueParameter
+DIBuilder::createTemplateValueParameter(DIDescriptor Context, StringRef Name,
+ DIType Ty, uint64_t Val,
+ MDNode *File, unsigned LineNo,
+ unsigned ColumnNo) {
+ Value *Elts[] = {
+ GetTagConstant(VMContext, dwarf::DW_TAG_template_value_parameter),
+ getNonCompileUnitScope(Context),
+ MDString::get(VMContext, Name),
+ Ty,
+ ConstantInt::get(Type::getInt64Ty(VMContext), Val),
+ File,
+ ConstantInt::get(Type::getInt32Ty(VMContext), LineNo),
+ ConstantInt::get(Type::getInt32Ty(VMContext), ColumnNo)
+ };
+ return DITemplateValueParameter(MDNode::get(VMContext, Elts));
+}
+
+/// createClassType - Create debugging information entry for a class.
+DIType DIBuilder::createClassType(DIDescriptor Context, StringRef Name,
+ DIFile File, unsigned LineNumber,
+ uint64_t SizeInBits, uint64_t AlignInBits,
+ uint64_t OffsetInBits, unsigned Flags,
+ DIType DerivedFrom, DIArray Elements,
+ MDNode *VTableHolder,
+ MDNode *TemplateParams) {
+ // TAG_class_type is encoded in DICompositeType format.
+ Value *Elts[] = {
+ GetTagConstant(VMContext, dwarf::DW_TAG_class_type),
+ getNonCompileUnitScope(Context),
+ MDString::get(VMContext, Name),
+ File,
+ ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber),
+ ConstantInt::get(Type::getInt64Ty(VMContext), SizeInBits),
+ ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits),
+ ConstantInt::get(Type::getInt32Ty(VMContext), OffsetInBits),
+ ConstantInt::get(Type::getInt32Ty(VMContext), Flags),
+ DerivedFrom,
+ Elements,
+ ConstantInt::get(Type::getInt32Ty(VMContext), 0),
+ VTableHolder,
+ TemplateParams
+ };
+ return DIType(MDNode::get(VMContext, Elts));
+}
+
+/// createStructType - Create debugging information entry for a struct.
+DIType DIBuilder::createStructType(DIDescriptor Context, StringRef Name,
+ DIFile File, unsigned LineNumber,
+ uint64_t SizeInBits, uint64_t AlignInBits,
+ unsigned Flags, DIArray Elements,
+ unsigned RunTimeLang) {
+ // TAG_structure_type is encoded in DICompositeType format.
+ Value *Elts[] = {
+ GetTagConstant(VMContext, dwarf::DW_TAG_structure_type),
+ getNonCompileUnitScope(Context),
+ MDString::get(VMContext, Name),
+ File,
+ ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber),
+ ConstantInt::get(Type::getInt64Ty(VMContext), SizeInBits),
+ ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits),
+ ConstantInt::get(Type::getInt32Ty(VMContext), 0),
+ ConstantInt::get(Type::getInt32Ty(VMContext), Flags),
+ NULL,
+ Elements,
+ ConstantInt::get(Type::getInt32Ty(VMContext), RunTimeLang),
+ Constant::getNullValue(Type::getInt32Ty(VMContext))
+ };
+ return DIType(MDNode::get(VMContext, Elts));
+}
+
+/// createUnionType - Create debugging information entry for an union.
+DIType DIBuilder::createUnionType(DIDescriptor Scope, StringRef Name,
+ DIFile File,
+ unsigned LineNumber, uint64_t SizeInBits,
+ uint64_t AlignInBits, unsigned Flags,
+ DIArray Elements, unsigned RunTimeLang) {
+ // TAG_union_type is encoded in DICompositeType format.
+ Value *Elts[] = {
+ GetTagConstant(VMContext, dwarf::DW_TAG_union_type),
+ getNonCompileUnitScope(Scope),
+ MDString::get(VMContext, Name),
+ File,
+ ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber),
+ ConstantInt::get(Type::getInt64Ty(VMContext), SizeInBits),
+ ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits),
+ ConstantInt::get(Type::getInt64Ty(VMContext), 0),
+ ConstantInt::get(Type::getInt32Ty(VMContext), Flags),
+ NULL,
+ Elements,
+ ConstantInt::get(Type::getInt32Ty(VMContext), RunTimeLang),
+ Constant::getNullValue(Type::getInt32Ty(VMContext))
+ };
+ return DIType(MDNode::get(VMContext, Elts));
+}
+
+/// createSubroutineType - Create subroutine type.
+DIType DIBuilder::createSubroutineType(DIFile File, DIArray ParameterTypes) {
+ // TAG_subroutine_type is encoded in DICompositeType format.
+ Value *Elts[] = {
+ GetTagConstant(VMContext, dwarf::DW_TAG_subroutine_type),
+ Constant::getNullValue(Type::getInt32Ty(VMContext)),
+ MDString::get(VMContext, ""),
+ Constant::getNullValue(Type::getInt32Ty(VMContext)),
+ ConstantInt::get(Type::getInt32Ty(VMContext), 0),
+ ConstantInt::get(Type::getInt64Ty(VMContext), 0),
+ ConstantInt::get(Type::getInt64Ty(VMContext), 0),
+ ConstantInt::get(Type::getInt64Ty(VMContext), 0),
+ ConstantInt::get(Type::getInt32Ty(VMContext), 0),
+ NULL,
+ ParameterTypes,
+ ConstantInt::get(Type::getInt32Ty(VMContext), 0),
+ Constant::getNullValue(Type::getInt32Ty(VMContext))
+ };
+ return DIType(MDNode::get(VMContext, Elts));
+}
+
+/// createEnumerationType - Create debugging information entry for an
+/// enumeration.
+DIType DIBuilder::createEnumerationType(DIDescriptor Scope, StringRef Name,
+ DIFile File, unsigned LineNumber,
+ uint64_t SizeInBits,
+ uint64_t AlignInBits,
+ DIArray Elements,
+ DIType ClassType, unsigned Flags) {
+ // TAG_enumeration_type is encoded in DICompositeType format.
+ Value *Elts[] = {
+ GetTagConstant(VMContext, dwarf::DW_TAG_enumeration_type),
+ getNonCompileUnitScope(Scope),
+ MDString::get(VMContext, Name),
+ File,
+ ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber),
+ ConstantInt::get(Type::getInt64Ty(VMContext), SizeInBits),
+ ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits),
+ ConstantInt::get(Type::getInt32Ty(VMContext), 0),
+ ConstantInt::get(Type::getInt32Ty(VMContext), Flags),
+ ClassType,
+ Elements,
+ ConstantInt::get(Type::getInt32Ty(VMContext), 0),
+ Constant::getNullValue(Type::getInt32Ty(VMContext))
+ };
+ MDNode *Node = MDNode::get(VMContext, Elts);
+ AllEnumTypes.push_back(Node);
+ return DIType(Node);
+}
+
+/// createArrayType - Create debugging information entry for an array.
+DIType DIBuilder::createArrayType(uint64_t Size, uint64_t AlignInBits,
+ DIType Ty, DIArray Subscripts) {
+ // TAG_array_type is encoded in DICompositeType format.
+ Value *Elts[] = {
+ GetTagConstant(VMContext, dwarf::DW_TAG_array_type),
+ NULL, //TheCU,
+ MDString::get(VMContext, ""),
+ NULL, //TheCU,
+ ConstantInt::get(Type::getInt32Ty(VMContext), 0),
+ ConstantInt::get(Type::getInt64Ty(VMContext), Size),
+ ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits),
+ ConstantInt::get(Type::getInt32Ty(VMContext), 0),
+ ConstantInt::get(Type::getInt32Ty(VMContext), 0),
+ Ty,
+ Subscripts,
+ ConstantInt::get(Type::getInt32Ty(VMContext), 0),
+ Constant::getNullValue(Type::getInt32Ty(VMContext))
+ };
+ return DIType(MDNode::get(VMContext, Elts));
+}
+
+/// createVectorType - Create debugging information entry for a vector.
+DIType DIBuilder::createVectorType(uint64_t Size, uint64_t AlignInBits,
+ DIType Ty, DIArray Subscripts) {
+ // TAG_vector_type is encoded in DICompositeType format.
+ Value *Elts[] = {
+ GetTagConstant(VMContext, dwarf::DW_TAG_vector_type),
+ NULL, //TheCU,
+ MDString::get(VMContext, ""),
+ NULL, //TheCU,
+ ConstantInt::get(Type::getInt32Ty(VMContext), 0),
+ ConstantInt::get(Type::getInt64Ty(VMContext), Size),
+ ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits),
+ ConstantInt::get(Type::getInt32Ty(VMContext), 0),
+ ConstantInt::get(Type::getInt32Ty(VMContext), 0),
+ Ty,
+ Subscripts,
+ ConstantInt::get(Type::getInt32Ty(VMContext), 0),
+ Constant::getNullValue(Type::getInt32Ty(VMContext))
+ };
+ return DIType(MDNode::get(VMContext, Elts));
+}
+
+/// createArtificialType - Create a new DIType with "artificial" flag set.
+DIType DIBuilder::createArtificialType(DIType Ty) {
+ if (Ty.isArtificial())
+ return Ty;
+
+ SmallVector<Value *, 9> Elts;
+ MDNode *N = Ty;
+ assert (N && "Unexpected input DIType!");
+ for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
+ if (Value *V = N->getOperand(i))
+ Elts.push_back(V);
+ else
+ Elts.push_back(Constant::getNullValue(Type::getInt32Ty(VMContext)));
+ }
+
+ unsigned CurFlags = Ty.getFlags();
+ CurFlags = CurFlags | DIType::FlagArtificial;
+
+ // Flags are stored at this slot.
+ Elts[8] = ConstantInt::get(Type::getInt32Ty(VMContext), CurFlags);
+
+ return DIType(MDNode::get(VMContext, Elts));
+}
+
+/// retainType - Retain DIType in a module even if it is not referenced
+/// through debug info anchors.
+void DIBuilder::retainType(DIType T) {
+ AllRetainTypes.push_back(T);
+}
+
+/// createUnspecifiedParameter - Create unspeicified type descriptor
+/// for the subroutine type.
+DIDescriptor DIBuilder::createUnspecifiedParameter() {
+ Value *Elts[] = {
+ GetTagConstant(VMContext, dwarf::DW_TAG_unspecified_parameters)
+ };
+ return DIDescriptor(MDNode::get(VMContext, Elts));
+}
+
+/// createTemporaryType - Create a temporary forward-declared type.
+DIType DIBuilder::createTemporaryType() {
+ // Give the temporary MDNode a tag. It doesn't matter what tag we
+ // use here as long as DIType accepts it.
+ Value *Elts[] = { GetTagConstant(VMContext, DW_TAG_base_type) };
+ MDNode *Node = MDNode::getTemporary(VMContext, Elts);
+ return DIType(Node);
+}
+
+/// createTemporaryType - Create a temporary forward-declared type.
+DIType DIBuilder::createTemporaryType(DIFile F) {
+ // Give the temporary MDNode a tag. It doesn't matter what tag we
+ // use here as long as DIType accepts it.
+ Value *Elts[] = {
+ GetTagConstant(VMContext, DW_TAG_base_type),
+ TheCU,
+ NULL,
+ F
+ };
+ MDNode *Node = MDNode::getTemporary(VMContext, Elts);
+ return DIType(Node);
+}
+
+/// createForwardDecl - Create a temporary forward-declared type that
+/// can be RAUW'd if the full type is seen.
+DIType DIBuilder::createForwardDecl(unsigned Tag, StringRef Name,
+ DIDescriptor Scope, DIFile F,
+ unsigned Line, unsigned RuntimeLang) {
+ // Create a temporary MDNode.
+ Value *Elts[] = {
+ GetTagConstant(VMContext, Tag),
+ getNonCompileUnitScope(Scope),
+ MDString::get(VMContext, Name),
+ F,
+ ConstantInt::get(Type::getInt32Ty(VMContext), Line),
+ // To ease transition include sizes etc of 0.
+ ConstantInt::get(Type::getInt32Ty(VMContext), 0),
+ ConstantInt::get(Type::getInt32Ty(VMContext), 0),
+ ConstantInt::get(Type::getInt32Ty(VMContext), 0),
+ ConstantInt::get(Type::getInt32Ty(VMContext),
+ DIDescriptor::FlagFwdDecl),
+ NULL,
+ DIArray(),
+ ConstantInt::get(Type::getInt32Ty(VMContext), RuntimeLang)
+ };
+ MDNode *Node = MDNode::getTemporary(VMContext, Elts);
+ return DIType(Node);
+}
+
+/// getOrCreateArray - Get a DIArray, create one if required.
+DIArray DIBuilder::getOrCreateArray(ArrayRef<Value *> Elements) {
+ if (Elements.empty()) {
+ Value *Null = Constant::getNullValue(Type::getInt32Ty(VMContext));
+ return DIArray(MDNode::get(VMContext, Null));
+ }
+ return DIArray(MDNode::get(VMContext, Elements));
+}
+
+/// getOrCreateSubrange - Create a descriptor for a value range. This
+/// implicitly uniques the values returned.
+DISubrange DIBuilder::getOrCreateSubrange(int64_t Lo, int64_t Hi) {
+ Value *Elts[] = {
+ GetTagConstant(VMContext, dwarf::DW_TAG_subrange_type),
+ ConstantInt::get(Type::getInt64Ty(VMContext), Lo),
+ ConstantInt::get(Type::getInt64Ty(VMContext), Hi)
+ };
+
+ return DISubrange(MDNode::get(VMContext, Elts));
+}
+
+/// createGlobalVariable - Create a new descriptor for the specified global.
+DIGlobalVariable DIBuilder::
+createGlobalVariable(StringRef Name, DIFile F, unsigned LineNumber,
+ DIType Ty, bool isLocalToUnit, Value *Val) {
+ Value *Elts[] = {
+ GetTagConstant(VMContext, dwarf::DW_TAG_variable),
+ Constant::getNullValue(Type::getInt32Ty(VMContext)),
+ NULL, // TheCU,
+ MDString::get(VMContext, Name),
+ MDString::get(VMContext, Name),
+ MDString::get(VMContext, Name),
+ F,
+ ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber),
+ Ty,
+ ConstantInt::get(Type::getInt32Ty(VMContext), isLocalToUnit),
+ ConstantInt::get(Type::getInt32Ty(VMContext), 1), /* isDefinition*/
+ Val
+ };
+ MDNode *Node = MDNode::get(VMContext, Elts);
+ AllGVs.push_back(Node);
+ return DIGlobalVariable(Node);
+}
+
+/// createStaticVariable - Create a new descriptor for the specified static
+/// variable.
+DIGlobalVariable DIBuilder::
+createStaticVariable(DIDescriptor Context, StringRef Name,
+ StringRef LinkageName, DIFile F, unsigned LineNumber,
+ DIType Ty, bool isLocalToUnit, Value *Val) {
+ Value *Elts[] = {
+ GetTagConstant(VMContext, dwarf::DW_TAG_variable),
+ Constant::getNullValue(Type::getInt32Ty(VMContext)),
+ getNonCompileUnitScope(Context),
+ MDString::get(VMContext, Name),
+ MDString::get(VMContext, Name),
+ MDString::get(VMContext, LinkageName),
+ F,
+ ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber),
+ Ty,
+ ConstantInt::get(Type::getInt32Ty(VMContext), isLocalToUnit),
+ ConstantInt::get(Type::getInt32Ty(VMContext), 1), /* isDefinition*/
+ Val
+ };
+ MDNode *Node = MDNode::get(VMContext, Elts);
+ AllGVs.push_back(Node);
+ return DIGlobalVariable(Node);
+}
+
+/// createVariable - Create a new descriptor for the specified variable.
+DIVariable DIBuilder::createLocalVariable(unsigned Tag, DIDescriptor Scope,
+ StringRef Name, DIFile File,
+ unsigned LineNo, DIType Ty,
+ bool AlwaysPreserve, unsigned Flags,
+ unsigned ArgNo) {
+ Value *Elts[] = {
+ GetTagConstant(VMContext, Tag),
+ getNonCompileUnitScope(Scope),
+ MDString::get(VMContext, Name),
+ File,
+ ConstantInt::get(Type::getInt32Ty(VMContext), (LineNo | (ArgNo << 24))),
+ Ty,
+ ConstantInt::get(Type::getInt32Ty(VMContext), Flags),
+ Constant::getNullValue(Type::getInt32Ty(VMContext))
+ };
+ MDNode *Node = MDNode::get(VMContext, Elts);
+ if (AlwaysPreserve) {
+ // The optimizer may remove local variable. If there is an interest
+ // to preserve variable info in such situation then stash it in a
+ // named mdnode.
+ DISubprogram Fn(getDISubprogram(Scope));
+ NamedMDNode *FnLocals = getOrInsertFnSpecificMDNode(M, Fn);
+ FnLocals->addOperand(Node);
+ }
+ return DIVariable(Node);
+}
+
+/// createComplexVariable - Create a new descriptor for the specified variable
+/// which has a complex address expression for its address.
+DIVariable DIBuilder::createComplexVariable(unsigned Tag, DIDescriptor Scope,
+ StringRef Name, DIFile F,
+ unsigned LineNo,
+ DIType Ty, ArrayRef<Value *> Addr,
+ unsigned ArgNo) {
+ SmallVector<Value *, 15> Elts;
+ Elts.push_back(GetTagConstant(VMContext, Tag));
+ Elts.push_back(getNonCompileUnitScope(Scope)),
+ Elts.push_back(MDString::get(VMContext, Name));
+ Elts.push_back(F);
+ Elts.push_back(ConstantInt::get(Type::getInt32Ty(VMContext),
+ (LineNo | (ArgNo << 24))));
+ Elts.push_back(Ty);
+ Elts.push_back(Constant::getNullValue(Type::getInt32Ty(VMContext)));
+ Elts.push_back(Constant::getNullValue(Type::getInt32Ty(VMContext)));
+ Elts.append(Addr.begin(), Addr.end());
+
+ return DIVariable(MDNode::get(VMContext, Elts));
+}
+
+/// createFunction - Create a new descriptor for the specified function.
+DISubprogram DIBuilder::createFunction(DIDescriptor Context,
+ StringRef Name,
+ StringRef LinkageName,
+ DIFile File, unsigned LineNo,
+ DIType Ty,
+ bool isLocalToUnit, bool isDefinition,
+ unsigned ScopeLine,
+ unsigned Flags, bool isOptimized,
+ Function *Fn,
+ MDNode *TParams,
+ MDNode *Decl) {
+ Value *TElts[] = { GetTagConstant(VMContext, DW_TAG_base_type) };
+ MDNode *Temp = MDNode::getTemporary(VMContext, TElts);
+ Value *TVElts[] = { Temp };
+ MDNode *THolder = MDNode::get(VMContext, TVElts);
+
+ Value *Elts[] = {
+ GetTagConstant(VMContext, dwarf::DW_TAG_subprogram),
+ Constant::getNullValue(Type::getInt32Ty(VMContext)),
+ getNonCompileUnitScope(Context),
+ MDString::get(VMContext, Name),
+ MDString::get(VMContext, Name),
+ MDString::get(VMContext, LinkageName),
+ File,
+ ConstantInt::get(Type::getInt32Ty(VMContext), LineNo),
+ Ty,
+ ConstantInt::get(Type::getInt1Ty(VMContext), isLocalToUnit),
+ ConstantInt::get(Type::getInt1Ty(VMContext), isDefinition),
+ ConstantInt::get(Type::getInt32Ty(VMContext), 0),
+ ConstantInt::get(Type::getInt32Ty(VMContext), 0),
+ NULL,
+ ConstantInt::get(Type::getInt32Ty(VMContext), Flags),
+ ConstantInt::get(Type::getInt1Ty(VMContext), isOptimized),
+ Fn,
+ TParams,
+ Decl,
+ THolder,
+ ConstantInt::get(Type::getInt32Ty(VMContext), ScopeLine)
+ };
+ MDNode *Node = MDNode::get(VMContext, Elts);
+
+ // Create a named metadata so that we do not lose this mdnode.
+ AllSubprograms.push_back(Node);
+ return DISubprogram(Node);
+}
+
+/// createMethod - Create a new descriptor for the specified C++ method.
+DISubprogram DIBuilder::createMethod(DIDescriptor Context,
+ StringRef Name,
+ StringRef LinkageName,
+ DIFile F,
+ unsigned LineNo, DIType Ty,
+ bool isLocalToUnit,
+ bool isDefinition,
+ unsigned VK, unsigned VIndex,
+ MDNode *VTableHolder,
+ unsigned Flags,
+ bool isOptimized,
+ Function *Fn,
+ MDNode *TParam) {
+ Value *TElts[] = { GetTagConstant(VMContext, DW_TAG_base_type) };
+ MDNode *Temp = MDNode::getTemporary(VMContext, TElts);
+ Value *TVElts[] = { Temp };
+ MDNode *THolder = MDNode::get(VMContext, TVElts);
+
+ Value *Elts[] = {
+ GetTagConstant(VMContext, dwarf::DW_TAG_subprogram),
+ Constant::getNullValue(Type::getInt32Ty(VMContext)),
+ getNonCompileUnitScope(Context),
+ MDString::get(VMContext, Name),
+ MDString::get(VMContext, Name),
+ MDString::get(VMContext, LinkageName),
+ F,
+ ConstantInt::get(Type::getInt32Ty(VMContext), LineNo),
+ Ty,
+ ConstantInt::get(Type::getInt1Ty(VMContext), isLocalToUnit),
+ ConstantInt::get(Type::getInt1Ty(VMContext), isDefinition),
+ ConstantInt::get(Type::getInt32Ty(VMContext), (unsigned)VK),
+ ConstantInt::get(Type::getInt32Ty(VMContext), VIndex),
+ VTableHolder,
+ ConstantInt::get(Type::getInt32Ty(VMContext), Flags),
+ ConstantInt::get(Type::getInt1Ty(VMContext), isOptimized),
+ Fn,
+ TParam,
+ Constant::getNullValue(Type::getInt32Ty(VMContext)),
+ THolder,
+ // FIXME: Do we want to use different scope/lines?
+ ConstantInt::get(Type::getInt32Ty(VMContext), LineNo)
+ };
+ MDNode *Node = MDNode::get(VMContext, Elts);
+ return DISubprogram(Node);
+}
+
+/// createNameSpace - This creates new descriptor for a namespace
+/// with the specified parent scope.
+DINameSpace DIBuilder::createNameSpace(DIDescriptor Scope, StringRef Name,
+ DIFile File, unsigned LineNo) {
+ Value *Elts[] = {
+ GetTagConstant(VMContext, dwarf::DW_TAG_namespace),
+ getNonCompileUnitScope(Scope),
+ MDString::get(VMContext, Name),
+ File,
+ ConstantInt::get(Type::getInt32Ty(VMContext), LineNo)
+ };
+ return DINameSpace(MDNode::get(VMContext, Elts));
+}
+
+/// createLexicalBlockFile - This creates a new MDNode that encapsulates
+/// an existing scope with a new filename.
+DILexicalBlockFile DIBuilder::createLexicalBlockFile(DIDescriptor Scope,
+ DIFile File) {
+ Value *Elts[] = {
+ GetTagConstant(VMContext, dwarf::DW_TAG_lexical_block),
+ Scope,
+ File
+ };
+ return DILexicalBlockFile(MDNode::get(VMContext, Elts));
+}
+
+DILexicalBlock DIBuilder::createLexicalBlock(DIDescriptor Scope, DIFile File,
+ unsigned Line, unsigned Col) {
+ // Defeat MDNode uniqing for lexical blocks by using unique id.
+ static unsigned int unique_id = 0;
+ Value *Elts[] = {
+ GetTagConstant(VMContext, dwarf::DW_TAG_lexical_block),
+ getNonCompileUnitScope(Scope),
+ ConstantInt::get(Type::getInt32Ty(VMContext), Line),
+ ConstantInt::get(Type::getInt32Ty(VMContext), Col),
+ File,
+ ConstantInt::get(Type::getInt32Ty(VMContext), unique_id++)
+ };
+ return DILexicalBlock(MDNode::get(VMContext, Elts));
+}
+
+/// insertDeclare - Insert a new llvm.dbg.declare intrinsic call.
+Instruction *DIBuilder::insertDeclare(Value *Storage, DIVariable VarInfo,
+ Instruction *InsertBefore) {
+ assert(Storage && "no storage passed to dbg.declare");
+ assert(VarInfo.Verify() && "empty DIVariable passed to dbg.declare");
+ if (!DeclareFn)
+ DeclareFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_declare);
+
+ Value *Args[] = { MDNode::get(Storage->getContext(), Storage), VarInfo };
+ return CallInst::Create(DeclareFn, Args, "", InsertBefore);
+}
+
+/// insertDeclare - Insert a new llvm.dbg.declare intrinsic call.
+Instruction *DIBuilder::insertDeclare(Value *Storage, DIVariable VarInfo,
+ BasicBlock *InsertAtEnd) {
+ assert(Storage && "no storage passed to dbg.declare");
+ assert(VarInfo.Verify() && "invalid DIVariable passed to dbg.declare");
+ if (!DeclareFn)
+ DeclareFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_declare);
+
+ Value *Args[] = { MDNode::get(Storage->getContext(), Storage), VarInfo };
+
+ // If this block already has a terminator then insert this intrinsic
+ // before the terminator.
+ if (TerminatorInst *T = InsertAtEnd->getTerminator())
+ return CallInst::Create(DeclareFn, Args, "", T);
+ else
+ return CallInst::Create(DeclareFn, Args, "", InsertAtEnd);
+}
+
+/// insertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call.
+Instruction *DIBuilder::insertDbgValueIntrinsic(Value *V, uint64_t Offset,
+ DIVariable VarInfo,
+ Instruction *InsertBefore) {
+ assert(V && "no value passed to dbg.value");
+ assert(VarInfo.Verify() && "invalid DIVariable passed to dbg.value");
+ if (!ValueFn)
+ ValueFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_value);
+
+ Value *Args[] = { MDNode::get(V->getContext(), V),
+ ConstantInt::get(Type::getInt64Ty(V->getContext()), Offset),
+ VarInfo };
+ return CallInst::Create(ValueFn, Args, "", InsertBefore);
+}
+
+/// insertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call.
+Instruction *DIBuilder::insertDbgValueIntrinsic(Value *V, uint64_t Offset,
+ DIVariable VarInfo,
+ BasicBlock *InsertAtEnd) {
+ assert(V && "no value passed to dbg.value");
+ assert(VarInfo.Verify() && "invalid DIVariable passed to dbg.value");
+ if (!ValueFn)
+ ValueFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_value);
+
+ Value *Args[] = { MDNode::get(V->getContext(), V),
+ ConstantInt::get(Type::getInt64Ty(V->getContext()), Offset),
+ VarInfo };
+ return CallInst::Create(ValueFn, Args, "", InsertAtEnd);
+}
diff --git a/lib/VMCore/DebugInfo.cpp b/lib/VMCore/DebugInfo.cpp
new file mode 100644
index 0000000..c8f8f7d
--- /dev/null
+++ b/lib/VMCore/DebugInfo.cpp
@@ -0,0 +1,1168 @@
+//===--- DebugInfo.cpp - Debug Information Helper Classes -----------------===//
+//
+// 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 helper classes used to build and interpret debug
+// information in LLVM IR form.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo.h"
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Intrinsics.h"
+#include "llvm/IntrinsicInst.h"
+#include "llvm/Instructions.h"
+#include "llvm/Module.h"
+#include "llvm/Analysis/ValueTracking.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/Dwarf.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace llvm;
+using namespace llvm::dwarf;
+
+//===----------------------------------------------------------------------===//
+// DIDescriptor
+//===----------------------------------------------------------------------===//
+
+DIDescriptor::DIDescriptor(const DIFile F) : DbgNode(F.DbgNode) {
+}
+
+DIDescriptor::DIDescriptor(const DISubprogram F) : DbgNode(F.DbgNode) {
+}
+
+DIDescriptor::DIDescriptor(const DILexicalBlockFile F) : DbgNode(F.DbgNode) {
+}
+
+DIDescriptor::DIDescriptor(const DILexicalBlock F) : DbgNode(F.DbgNode) {
+}
+
+DIDescriptor::DIDescriptor(const DIVariable F) : DbgNode(F.DbgNode) {
+}
+
+DIDescriptor::DIDescriptor(const DIType F) : DbgNode(F.DbgNode) {
+}
+
+StringRef
+DIDescriptor::getStringField(unsigned Elt) const {
+ if (DbgNode == 0)
+ return StringRef();
+
+ if (Elt < DbgNode->getNumOperands())
+ if (MDString *MDS = dyn_cast_or_null<MDString>(DbgNode->getOperand(Elt)))
+ return MDS->getString();
+
+ return StringRef();
+}
+
+uint64_t DIDescriptor::getUInt64Field(unsigned Elt) const {
+ if (DbgNode == 0)
+ return 0;
+
+ if (Elt < DbgNode->getNumOperands())
+ if (ConstantInt *CI = dyn_cast_or_null<ConstantInt>(DbgNode->getOperand(Elt)))
+ return CI->getZExtValue();
+
+ return 0;
+}
+
+DIDescriptor DIDescriptor::getDescriptorField(unsigned Elt) const {
+ if (DbgNode == 0)
+ return DIDescriptor();
+
+ if (Elt < DbgNode->getNumOperands())
+ return
+ DIDescriptor(dyn_cast_or_null<const MDNode>(DbgNode->getOperand(Elt)));
+ return DIDescriptor();
+}
+
+GlobalVariable *DIDescriptor::getGlobalVariableField(unsigned Elt) const {
+ if (DbgNode == 0)
+ return 0;
+
+ if (Elt < DbgNode->getNumOperands())
+ return dyn_cast_or_null<GlobalVariable>(DbgNode->getOperand(Elt));
+ return 0;
+}
+
+Constant *DIDescriptor::getConstantField(unsigned Elt) const {
+ if (DbgNode == 0)
+ return 0;
+
+ if (Elt < DbgNode->getNumOperands())
+ return dyn_cast_or_null<Constant>(DbgNode->getOperand(Elt));
+ return 0;
+}
+
+Function *DIDescriptor::getFunctionField(unsigned Elt) const {
+ if (DbgNode == 0)
+ return 0;
+
+ if (Elt < DbgNode->getNumOperands())
+ return dyn_cast_or_null<Function>(DbgNode->getOperand(Elt));
+ return 0;
+}
+
+unsigned DIVariable::getNumAddrElements() const {
+ if (getVersion() <= LLVMDebugVersion8)
+ return DbgNode->getNumOperands()-6;
+ if (getVersion() == LLVMDebugVersion9)
+ return DbgNode->getNumOperands()-7;
+ return DbgNode->getNumOperands()-8;
+}
+
+/// getInlinedAt - If this variable is inlined then return inline location.
+MDNode *DIVariable::getInlinedAt() const {
+ if (getVersion() <= LLVMDebugVersion9)
+ return NULL;
+ return dyn_cast_or_null<MDNode>(DbgNode->getOperand(7));
+}
+
+//===----------------------------------------------------------------------===//
+// Predicates
+//===----------------------------------------------------------------------===//
+
+/// isBasicType - Return true if the specified tag is legal for
+/// DIBasicType.
+bool DIDescriptor::isBasicType() const {
+ if (!DbgNode) return false;
+ switch (getTag()) {
+ case dwarf::DW_TAG_base_type:
+ case dwarf::DW_TAG_unspecified_type:
+ return true;
+ default:
+ return false;
+ }
+}
+
+/// isDerivedType - Return true if the specified tag is legal for DIDerivedType.
+bool DIDescriptor::isDerivedType() const {
+ if (!DbgNode) return false;
+ switch (getTag()) {
+ case dwarf::DW_TAG_typedef:
+ case dwarf::DW_TAG_pointer_type:
+ case dwarf::DW_TAG_reference_type:
+ case dwarf::DW_TAG_rvalue_reference_type:
+ case dwarf::DW_TAG_const_type:
+ case dwarf::DW_TAG_volatile_type:
+ case dwarf::DW_TAG_restrict_type:
+ case dwarf::DW_TAG_member:
+ case dwarf::DW_TAG_inheritance:
+ case dwarf::DW_TAG_friend:
+ return true;
+ default:
+ // CompositeTypes are currently modelled as DerivedTypes.
+ return isCompositeType();
+ }
+}
+
+/// isCompositeType - Return true if the specified tag is legal for
+/// DICompositeType.
+bool DIDescriptor::isCompositeType() const {
+ if (!DbgNode) return false;
+ switch (getTag()) {
+ case dwarf::DW_TAG_array_type:
+ case dwarf::DW_TAG_structure_type:
+ case dwarf::DW_TAG_union_type:
+ case dwarf::DW_TAG_enumeration_type:
+ case dwarf::DW_TAG_vector_type:
+ case dwarf::DW_TAG_subroutine_type:
+ case dwarf::DW_TAG_class_type:
+ return true;
+ default:
+ return false;
+ }
+}
+
+/// isVariable - Return true if the specified tag is legal for DIVariable.
+bool DIDescriptor::isVariable() const {
+ if (!DbgNode) return false;
+ switch (getTag()) {
+ case dwarf::DW_TAG_auto_variable:
+ case dwarf::DW_TAG_arg_variable:
+ case dwarf::DW_TAG_return_variable:
+ return true;
+ default:
+ return false;
+ }
+}
+
+/// isType - Return true if the specified tag is legal for DIType.
+bool DIDescriptor::isType() const {
+ return isBasicType() || isCompositeType() || isDerivedType();
+}
+
+/// isSubprogram - Return true if the specified tag is legal for
+/// DISubprogram.
+bool DIDescriptor::isSubprogram() const {
+ return DbgNode && getTag() == dwarf::DW_TAG_subprogram;
+}
+
+/// isGlobalVariable - Return true if the specified tag is legal for
+/// DIGlobalVariable.
+bool DIDescriptor::isGlobalVariable() const {
+ return DbgNode && (getTag() == dwarf::DW_TAG_variable ||
+ getTag() == dwarf::DW_TAG_constant);
+}
+
+/// isGlobal - Return true if the specified tag is legal for DIGlobal.
+bool DIDescriptor::isGlobal() const {
+ return isGlobalVariable();
+}
+
+/// isUnspecifiedParmeter - Return true if the specified tag is
+/// DW_TAG_unspecified_parameters.
+bool DIDescriptor::isUnspecifiedParameter() const {
+ return DbgNode && getTag() == dwarf::DW_TAG_unspecified_parameters;
+}
+
+/// isScope - Return true if the specified tag is one of the scope
+/// related tag.
+bool DIDescriptor::isScope() const {
+ if (!DbgNode) return false;
+ switch (getTag()) {
+ case dwarf::DW_TAG_compile_unit:
+ case dwarf::DW_TAG_lexical_block:
+ case dwarf::DW_TAG_subprogram:
+ case dwarf::DW_TAG_namespace:
+ return true;
+ default:
+ break;
+ }
+ return false;
+}
+
+/// isTemplateTypeParameter - Return true if the specified tag is
+/// DW_TAG_template_type_parameter.
+bool DIDescriptor::isTemplateTypeParameter() const {
+ return DbgNode && getTag() == dwarf::DW_TAG_template_type_parameter;
+}
+
+/// isTemplateValueParameter - Return true if the specified tag is
+/// DW_TAG_template_value_parameter.
+bool DIDescriptor::isTemplateValueParameter() const {
+ return DbgNode && getTag() == dwarf::DW_TAG_template_value_parameter;
+}
+
+/// isCompileUnit - Return true if the specified tag is DW_TAG_compile_unit.
+bool DIDescriptor::isCompileUnit() const {
+ return DbgNode && getTag() == dwarf::DW_TAG_compile_unit;
+}
+
+/// isFile - Return true if the specified tag is DW_TAG_file_type.
+bool DIDescriptor::isFile() const {
+ return DbgNode && getTag() == dwarf::DW_TAG_file_type;
+}
+
+/// isNameSpace - Return true if the specified tag is DW_TAG_namespace.
+bool DIDescriptor::isNameSpace() const {
+ return DbgNode && getTag() == dwarf::DW_TAG_namespace;
+}
+
+/// isLexicalBlockFile - Return true if the specified descriptor is a
+/// lexical block with an extra file.
+bool DIDescriptor::isLexicalBlockFile() const {
+ return DbgNode && getTag() == dwarf::DW_TAG_lexical_block &&
+ (DbgNode->getNumOperands() == 3);
+}
+
+/// isLexicalBlock - Return true if the specified tag is DW_TAG_lexical_block.
+bool DIDescriptor::isLexicalBlock() const {
+ return DbgNode && getTag() == dwarf::DW_TAG_lexical_block &&
+ (DbgNode->getNumOperands() > 3);
+}
+
+/// isSubrange - Return true if the specified tag is DW_TAG_subrange_type.
+bool DIDescriptor::isSubrange() const {
+ return DbgNode && getTag() == dwarf::DW_TAG_subrange_type;
+}
+
+/// isEnumerator - Return true if the specified tag is DW_TAG_enumerator.
+bool DIDescriptor::isEnumerator() const {
+ return DbgNode && getTag() == dwarf::DW_TAG_enumerator;
+}
+
+/// isObjCProperty - Return true if the specified tag is DW_TAG
+bool DIDescriptor::isObjCProperty() const {
+ return DbgNode && getTag() == dwarf::DW_TAG_APPLE_property;
+}
+//===----------------------------------------------------------------------===//
+// Simple Descriptor Constructors and other Methods
+//===----------------------------------------------------------------------===//
+
+DIType::DIType(const MDNode *N) : DIScope(N) {
+ if (!N) return;
+ if (!isBasicType() && !isDerivedType() && !isCompositeType()) {
+ DbgNode = 0;
+ }
+}
+
+unsigned DIArray::getNumElements() const {
+ if (!DbgNode)
+ return 0;
+ return DbgNode->getNumOperands();
+}
+
+/// replaceAllUsesWith - Replace all uses of debug info referenced by
+/// this descriptor.
+void DIType::replaceAllUsesWith(DIDescriptor &D) {
+ if (!DbgNode)
+ return;
+
+ // Since we use a TrackingVH for the node, its easy for clients to manufacture
+ // legitimate situations where they want to replaceAllUsesWith() on something
+ // which, due to uniquing, has merged with the source. We shield clients from
+ // this detail by allowing a value to be replaced with replaceAllUsesWith()
+ // itself.
+ if (DbgNode != D) {
+ MDNode *Node = const_cast<MDNode*>(DbgNode);
+ const MDNode *DN = D;
+ const Value *V = cast_or_null<Value>(DN);
+ Node->replaceAllUsesWith(const_cast<Value*>(V));
+ MDNode::deleteTemporary(Node);
+ }
+}
+
+/// replaceAllUsesWith - Replace all uses of debug info referenced by
+/// this descriptor.
+void DIType::replaceAllUsesWith(MDNode *D) {
+ if (!DbgNode)
+ return;
+
+ // Since we use a TrackingVH for the node, its easy for clients to manufacture
+ // legitimate situations where they want to replaceAllUsesWith() on something
+ // which, due to uniquing, has merged with the source. We shield clients from
+ // this detail by allowing a value to be replaced with replaceAllUsesWith()
+ // itself.
+ if (DbgNode != D) {
+ MDNode *Node = const_cast<MDNode*>(DbgNode);
+ const MDNode *DN = D;
+ const Value *V = cast_or_null<Value>(DN);
+ Node->replaceAllUsesWith(const_cast<Value*>(V));
+ MDNode::deleteTemporary(Node);
+ }
+}
+
+/// isUnsignedDIType - Return true if type encoding is unsigned.
+bool DIType::isUnsignedDIType() {
+ DIDerivedType DTy(DbgNode);
+ if (DTy.Verify())
+ return DTy.getTypeDerivedFrom().isUnsignedDIType();
+
+ DIBasicType BTy(DbgNode);
+ if (BTy.Verify()) {
+ unsigned Encoding = BTy.getEncoding();
+ if (Encoding == dwarf::DW_ATE_unsigned ||
+ Encoding == dwarf::DW_ATE_unsigned_char)
+ return true;
+ }
+ return false;
+}
+
+/// Verify - Verify that a compile unit is well formed.
+bool DICompileUnit::Verify() const {
+ if (!DbgNode)
+ return false;
+ StringRef N = getFilename();
+ if (N.empty())
+ return false;
+ // It is possible that directory and produce string is empty.
+ return true;
+}
+
+/// Verify - Verify that an ObjC property is well formed.
+bool DIObjCProperty::Verify() const {
+ if (!DbgNode)
+ return false;
+ unsigned Tag = getTag();
+ if (Tag != dwarf::DW_TAG_APPLE_property) return false;
+ DIType Ty = getType();
+ if (!Ty.Verify()) return false;
+
+ // Don't worry about the rest of the strings for now.
+ return true;
+}
+
+/// Verify - Verify that a type descriptor is well formed.
+bool DIType::Verify() const {
+ if (!DbgNode)
+ return false;
+ if (getContext() && !getContext().Verify())
+ return false;
+ unsigned Tag = getTag();
+ if (!isBasicType() && Tag != dwarf::DW_TAG_const_type &&
+ Tag != dwarf::DW_TAG_volatile_type && Tag != dwarf::DW_TAG_pointer_type &&
+ Tag != dwarf::DW_TAG_reference_type &&
+ Tag != dwarf::DW_TAG_rvalue_reference_type &&
+ Tag != dwarf::DW_TAG_restrict_type && Tag != dwarf::DW_TAG_vector_type &&
+ Tag != dwarf::DW_TAG_array_type &&
+ Tag != dwarf::DW_TAG_enumeration_type &&
+ Tag != dwarf::DW_TAG_subroutine_type &&
+ getFilename().empty())
+ return false;
+ return true;
+}
+
+/// Verify - Verify that a basic type descriptor is well formed.
+bool DIBasicType::Verify() const {
+ return isBasicType();
+}
+
+/// Verify - Verify that a derived type descriptor is well formed.
+bool DIDerivedType::Verify() const {
+ return isDerivedType();
+}
+
+/// Verify - Verify that a composite type descriptor is well formed.
+bool DICompositeType::Verify() const {
+ if (!DbgNode)
+ return false;
+ if (getContext() && !getContext().Verify())
+ return false;
+
+ return true;
+}
+
+/// Verify - Verify that a subprogram descriptor is well formed.
+bool DISubprogram::Verify() const {
+ if (!DbgNode)
+ return false;
+
+ if (getContext() && !getContext().Verify())
+ return false;
+
+ DICompositeType Ty = getType();
+ if (!Ty.Verify())
+ return false;
+ return true;
+}
+
+/// Verify - Verify that a global variable descriptor is well formed.
+bool DIGlobalVariable::Verify() const {
+ if (!DbgNode)
+ return false;
+
+ if (getDisplayName().empty())
+ return false;
+
+ if (getContext() && !getContext().Verify())
+ return false;
+
+ DIType Ty = getType();
+ if (!Ty.Verify())
+ return false;
+
+ if (!getGlobal() && !getConstant())
+ return false;
+
+ return true;
+}
+
+/// Verify - Verify that a variable descriptor is well formed.
+bool DIVariable::Verify() const {
+ if (!DbgNode)
+ return false;
+
+ if (getContext() && !getContext().Verify())
+ return false;
+
+ DIType Ty = getType();
+ if (!Ty.Verify())
+ return false;
+
+ return true;
+}
+
+/// Verify - Verify that a location descriptor is well formed.
+bool DILocation::Verify() const {
+ if (!DbgNode)
+ return false;
+
+ return DbgNode->getNumOperands() == 4;
+}
+
+/// Verify - Verify that a namespace descriptor is well formed.
+bool DINameSpace::Verify() const {
+ if (!DbgNode)
+ return false;
+ if (getName().empty())
+ return false;
+ return true;
+}
+
+/// getOriginalTypeSize - If this type is derived from a base type then
+/// return base type size.
+uint64_t DIDerivedType::getOriginalTypeSize() const {
+ unsigned Tag = getTag();
+
+ if (Tag != dwarf::DW_TAG_member && Tag != dwarf::DW_TAG_typedef &&
+ Tag != dwarf::DW_TAG_const_type && Tag != dwarf::DW_TAG_volatile_type &&
+ Tag != dwarf::DW_TAG_restrict_type)
+ return getSizeInBits();
+
+ DIType BaseType = getTypeDerivedFrom();
+
+ // If this type is not derived from any type then take conservative approach.
+ if (!BaseType.isValid())
+ return getSizeInBits();
+
+ // If this is a derived type, go ahead and get the base type, unless it's a
+ // reference then it's just the size of the field. Pointer types have no need
+ // of this since they're a different type of qualification on the type.
+ if (BaseType.getTag() == dwarf::DW_TAG_reference_type ||
+ BaseType.getTag() == dwarf::DW_TAG_rvalue_reference_type)
+ return getSizeInBits();
+
+ if (BaseType.isDerivedType())
+ return DIDerivedType(BaseType).getOriginalTypeSize();
+
+ return BaseType.getSizeInBits();
+}
+
+/// getObjCProperty - Return property node, if this ivar is associated with one.
+MDNode *DIDerivedType::getObjCProperty() const {
+ if (getVersion() <= LLVMDebugVersion11 || DbgNode->getNumOperands() <= 10)
+ return NULL;
+ return dyn_cast_or_null<MDNode>(DbgNode->getOperand(10));
+}
+
+/// isInlinedFnArgument - Return true if this variable provides debugging
+/// information for an inlined function arguments.
+bool DIVariable::isInlinedFnArgument(const Function *CurFn) {
+ assert(CurFn && "Invalid function");
+ if (!getContext().isSubprogram())
+ return false;
+ // This variable is not inlined function argument if its scope
+ // does not describe current function.
+ return !DISubprogram(getContext()).describes(CurFn);
+}
+
+/// describes - Return true if this subprogram provides debugging
+/// information for the function F.
+bool DISubprogram::describes(const Function *F) {
+ assert(F && "Invalid function");
+ if (F == getFunction())
+ return true;
+ StringRef Name = getLinkageName();
+ if (Name.empty())
+ Name = getName();
+ if (F->getName() == Name)
+ return true;
+ return false;
+}
+
+unsigned DISubprogram::isOptimized() const {
+ assert (DbgNode && "Invalid subprogram descriptor!");
+ if (DbgNode->getNumOperands() == 16)
+ return getUnsignedField(15);
+ return 0;
+}
+
+MDNode *DISubprogram::getVariablesNodes() const {
+ if (!DbgNode || DbgNode->getNumOperands() <= 19)
+ return NULL;
+ if (MDNode *Temp = dyn_cast_or_null<MDNode>(DbgNode->getOperand(19)))
+ return dyn_cast_or_null<MDNode>(Temp->getOperand(0));
+ return NULL;
+}
+
+DIArray DISubprogram::getVariables() const {
+ if (!DbgNode || DbgNode->getNumOperands() <= 19)
+ return DIArray();
+ if (MDNode *T = dyn_cast_or_null<MDNode>(DbgNode->getOperand(19)))
+ if (MDNode *A = dyn_cast_or_null<MDNode>(T->getOperand(0)))
+ return DIArray(A);
+ return DIArray();
+}
+
+StringRef DIScope::getFilename() const {
+ if (!DbgNode)
+ return StringRef();
+ if (isLexicalBlockFile())
+ return DILexicalBlockFile(DbgNode).getFilename();
+ if (isLexicalBlock())
+ return DILexicalBlock(DbgNode).getFilename();
+ if (isSubprogram())
+ return DISubprogram(DbgNode).getFilename();
+ if (isCompileUnit())
+ return DICompileUnit(DbgNode).getFilename();
+ if (isNameSpace())
+ return DINameSpace(DbgNode).getFilename();
+ if (isType())
+ return DIType(DbgNode).getFilename();
+ if (isFile())
+ return DIFile(DbgNode).getFilename();
+ llvm_unreachable("Invalid DIScope!");
+}
+
+StringRef DIScope::getDirectory() const {
+ if (!DbgNode)
+ return StringRef();
+ if (isLexicalBlockFile())
+ return DILexicalBlockFile(DbgNode).getDirectory();
+ if (isLexicalBlock())
+ return DILexicalBlock(DbgNode).getDirectory();
+ if (isSubprogram())
+ return DISubprogram(DbgNode).getDirectory();
+ if (isCompileUnit())
+ return DICompileUnit(DbgNode).getDirectory();
+ if (isNameSpace())
+ return DINameSpace(DbgNode).getDirectory();
+ if (isType())
+ return DIType(DbgNode).getDirectory();
+ if (isFile())
+ return DIFile(DbgNode).getDirectory();
+ llvm_unreachable("Invalid DIScope!");
+}
+
+DIArray DICompileUnit::getEnumTypes() const {
+ if (!DbgNode || DbgNode->getNumOperands() < 14)
+ return DIArray();
+
+ if (MDNode *N = dyn_cast_or_null<MDNode>(DbgNode->getOperand(10)))
+ if (MDNode *A = dyn_cast_or_null<MDNode>(N->getOperand(0)))
+ return DIArray(A);
+ return DIArray();
+}
+
+DIArray DICompileUnit::getRetainedTypes() const {
+ if (!DbgNode || DbgNode->getNumOperands() < 14)
+ return DIArray();
+
+ if (MDNode *N = dyn_cast_or_null<MDNode>(DbgNode->getOperand(11)))
+ if (MDNode *A = dyn_cast_or_null<MDNode>(N->getOperand(0)))
+ return DIArray(A);
+ return DIArray();
+}
+
+DIArray DICompileUnit::getSubprograms() const {
+ if (!DbgNode || DbgNode->getNumOperands() < 14)
+ return DIArray();
+
+ if (MDNode *N = dyn_cast_or_null<MDNode>(DbgNode->getOperand(12)))
+ if (MDNode *A = dyn_cast_or_null<MDNode>(N->getOperand(0)))
+ return DIArray(A);
+ return DIArray();
+}
+
+
+DIArray DICompileUnit::getGlobalVariables() const {
+ if (!DbgNode || DbgNode->getNumOperands() < 14)
+ return DIArray();
+
+ if (MDNode *N = dyn_cast_or_null<MDNode>(DbgNode->getOperand(13)))
+ if (MDNode *A = dyn_cast_or_null<MDNode>(N->getOperand(0)))
+ return DIArray(A);
+ return DIArray();
+}
+
+/// fixupObjcLikeName - Replace contains special characters used
+/// in a typical Objective-C names with '.' in a given string.
+static void fixupObjcLikeName(StringRef Str, SmallVectorImpl<char> &Out) {
+ bool isObjCLike = false;
+ for (size_t i = 0, e = Str.size(); i < e; ++i) {
+ char C = Str[i];
+ if (C == '[')
+ isObjCLike = true;
+
+ if (isObjCLike && (C == '[' || C == ']' || C == ' ' || C == ':' ||
+ C == '+' || C == '(' || C == ')'))
+ Out.push_back('.');
+ else
+ Out.push_back(C);
+ }
+}
+
+/// getFnSpecificMDNode - Return a NameMDNode, if available, that is
+/// suitable to hold function specific information.
+NamedMDNode *llvm::getFnSpecificMDNode(const Module &M, DISubprogram Fn) {
+ SmallString<32> Name = StringRef("llvm.dbg.lv.");
+ StringRef FName = "fn";
+ if (Fn.getFunction())
+ FName = Fn.getFunction()->getName();
+ else
+ FName = Fn.getName();
+ char One = '\1';
+ if (FName.startswith(StringRef(&One, 1)))
+ FName = FName.substr(1);
+ fixupObjcLikeName(FName, Name);
+ return M.getNamedMetadata(Name.str());
+}
+
+/// getOrInsertFnSpecificMDNode - Return a NameMDNode that is suitable
+/// to hold function specific information.
+NamedMDNode *llvm::getOrInsertFnSpecificMDNode(Module &M, DISubprogram Fn) {
+ SmallString<32> Name = StringRef("llvm.dbg.lv.");
+ StringRef FName = "fn";
+ if (Fn.getFunction())
+ FName = Fn.getFunction()->getName();
+ else
+ FName = Fn.getName();
+ char One = '\1';
+ if (FName.startswith(StringRef(&One, 1)))
+ FName = FName.substr(1);
+ fixupObjcLikeName(FName, Name);
+
+ return M.getOrInsertNamedMetadata(Name.str());
+}
+
+/// createInlinedVariable - Create a new inlined variable based on current
+/// variable.
+/// @param DV Current Variable.
+/// @param InlinedScope Location at current variable is inlined.
+DIVariable llvm::createInlinedVariable(MDNode *DV, MDNode *InlinedScope,
+ LLVMContext &VMContext) {
+ SmallVector<Value *, 16> Elts;
+ // Insert inlined scope as 7th element.
+ for (unsigned i = 0, e = DV->getNumOperands(); i != e; ++i)
+ i == 7 ? Elts.push_back(InlinedScope) :
+ Elts.push_back(DV->getOperand(i));
+ return DIVariable(MDNode::get(VMContext, Elts));
+}
+
+/// cleanseInlinedVariable - Remove inlined scope from the variable.
+DIVariable llvm::cleanseInlinedVariable(MDNode *DV, LLVMContext &VMContext) {
+ SmallVector<Value *, 16> Elts;
+ // Insert inlined scope as 7th element.
+ for (unsigned i = 0, e = DV->getNumOperands(); i != e; ++i)
+ i == 7 ?
+ Elts.push_back(Constant::getNullValue(Type::getInt32Ty(VMContext))):
+ Elts.push_back(DV->getOperand(i));
+ return DIVariable(MDNode::get(VMContext, Elts));
+}
+
+/// getDISubprogram - Find subprogram that is enclosing this scope.
+DISubprogram llvm::getDISubprogram(const MDNode *Scope) {
+ DIDescriptor D(Scope);
+ if (D.isSubprogram())
+ return DISubprogram(Scope);
+
+ if (D.isLexicalBlockFile())
+ return getDISubprogram(DILexicalBlockFile(Scope).getContext());
+
+ if (D.isLexicalBlock())
+ return getDISubprogram(DILexicalBlock(Scope).getContext());
+
+ return DISubprogram();
+}
+
+/// getDICompositeType - Find underlying composite type.
+DICompositeType llvm::getDICompositeType(DIType T) {
+ if (T.isCompositeType())
+ return DICompositeType(T);
+
+ if (T.isDerivedType())
+ return getDICompositeType(DIDerivedType(T).getTypeDerivedFrom());
+
+ return DICompositeType();
+}
+
+/// isSubprogramContext - Return true if Context is either a subprogram
+/// or another context nested inside a subprogram.
+bool llvm::isSubprogramContext(const MDNode *Context) {
+ if (!Context)
+ return false;
+ DIDescriptor D(Context);
+ if (D.isSubprogram())
+ return true;
+ if (D.isType())
+ return isSubprogramContext(DIType(Context).getContext());
+ return false;
+}
+
+//===----------------------------------------------------------------------===//
+// DebugInfoFinder implementations.
+//===----------------------------------------------------------------------===//
+
+/// processModule - Process entire module and collect debug info.
+void DebugInfoFinder::processModule(Module &M) {
+ if (NamedMDNode *CU_Nodes = M.getNamedMetadata("llvm.dbg.cu")) {
+ for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) {
+ DICompileUnit CU(CU_Nodes->getOperand(i));
+ addCompileUnit(CU);
+ if (CU.getVersion() > LLVMDebugVersion10) {
+ DIArray GVs = CU.getGlobalVariables();
+ for (unsigned i = 0, e = GVs.getNumElements(); i != e; ++i) {
+ DIGlobalVariable DIG(GVs.getElement(i));
+ if (addGlobalVariable(DIG))
+ processType(DIG.getType());
+ }
+ DIArray SPs = CU.getSubprograms();
+ for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i)
+ processSubprogram(DISubprogram(SPs.getElement(i)));
+ DIArray EnumTypes = CU.getEnumTypes();
+ for (unsigned i = 0, e = EnumTypes.getNumElements(); i != e; ++i)
+ processType(DIType(EnumTypes.getElement(i)));
+ DIArray RetainedTypes = CU.getRetainedTypes();
+ for (unsigned i = 0, e = RetainedTypes.getNumElements(); i != e; ++i)
+ processType(DIType(RetainedTypes.getElement(i)));
+ return;
+ }
+ }
+ }
+
+ for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
+ for (Function::iterator FI = (*I).begin(), FE = (*I).end(); FI != FE; ++FI)
+ for (BasicBlock::iterator BI = (*FI).begin(), BE = (*FI).end(); BI != BE;
+ ++BI) {
+ if (DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(BI))
+ processDeclare(DDI);
+
+ DebugLoc Loc = BI->getDebugLoc();
+ if (Loc.isUnknown())
+ continue;
+
+ LLVMContext &Ctx = BI->getContext();
+ DIDescriptor Scope(Loc.getScope(Ctx));
+
+ if (Scope.isCompileUnit())
+ addCompileUnit(DICompileUnit(Scope));
+ else if (Scope.isSubprogram())
+ processSubprogram(DISubprogram(Scope));
+ else if (Scope.isLexicalBlockFile()) {
+ DILexicalBlockFile DBF = DILexicalBlockFile(Scope);
+ processLexicalBlock(DILexicalBlock(DBF.getScope()));
+ }
+ else if (Scope.isLexicalBlock())
+ processLexicalBlock(DILexicalBlock(Scope));
+
+ if (MDNode *IA = Loc.getInlinedAt(Ctx))
+ processLocation(DILocation(IA));
+ }
+
+ if (NamedMDNode *NMD = M.getNamedMetadata("llvm.dbg.gv")) {
+ for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) {
+ DIGlobalVariable DIG(cast<MDNode>(NMD->getOperand(i)));
+ if (addGlobalVariable(DIG)) {
+ if (DIG.getVersion() <= LLVMDebugVersion10)
+ addCompileUnit(DIG.getCompileUnit());
+ processType(DIG.getType());
+ }
+ }
+ }
+
+ if (NamedMDNode *NMD = M.getNamedMetadata("llvm.dbg.sp"))
+ for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i)
+ processSubprogram(DISubprogram(NMD->getOperand(i)));
+}
+
+/// processLocation - Process DILocation.
+void DebugInfoFinder::processLocation(DILocation Loc) {
+ if (!Loc.Verify()) return;
+ DIDescriptor S(Loc.getScope());
+ if (S.isCompileUnit())
+ addCompileUnit(DICompileUnit(S));
+ else if (S.isSubprogram())
+ processSubprogram(DISubprogram(S));
+ else if (S.isLexicalBlock())
+ processLexicalBlock(DILexicalBlock(S));
+ else if (S.isLexicalBlockFile()) {
+ DILexicalBlockFile DBF = DILexicalBlockFile(S);
+ processLexicalBlock(DILexicalBlock(DBF.getScope()));
+ }
+ processLocation(Loc.getOrigLocation());
+}
+
+/// processType - Process DIType.
+void DebugInfoFinder::processType(DIType DT) {
+ if (!addType(DT))
+ return;
+ if (DT.getVersion() <= LLVMDebugVersion10)
+ addCompileUnit(DT.getCompileUnit());
+ if (DT.isCompositeType()) {
+ DICompositeType DCT(DT);
+ processType(DCT.getTypeDerivedFrom());
+ DIArray DA = DCT.getTypeArray();
+ for (unsigned i = 0, e = DA.getNumElements(); i != e; ++i) {
+ DIDescriptor D = DA.getElement(i);
+ if (D.isType())
+ processType(DIType(D));
+ else if (D.isSubprogram())
+ processSubprogram(DISubprogram(D));
+ }
+ } else if (DT.isDerivedType()) {
+ DIDerivedType DDT(DT);
+ processType(DDT.getTypeDerivedFrom());
+ }
+}
+
+/// processLexicalBlock
+void DebugInfoFinder::processLexicalBlock(DILexicalBlock LB) {
+ DIScope Context = LB.getContext();
+ if (Context.isLexicalBlock())
+ return processLexicalBlock(DILexicalBlock(Context));
+ else if (Context.isLexicalBlockFile()) {
+ DILexicalBlockFile DBF = DILexicalBlockFile(Context);
+ return processLexicalBlock(DILexicalBlock(DBF.getScope()));
+ }
+ else
+ return processSubprogram(DISubprogram(Context));
+}
+
+/// processSubprogram - Process DISubprogram.
+void DebugInfoFinder::processSubprogram(DISubprogram SP) {
+ if (!addSubprogram(SP))
+ return;
+ if (SP.getVersion() <= LLVMDebugVersion10)
+ addCompileUnit(SP.getCompileUnit());
+ processType(SP.getType());
+}
+
+/// processDeclare - Process DbgDeclareInst.
+void DebugInfoFinder::processDeclare(DbgDeclareInst *DDI) {
+ MDNode *N = dyn_cast<MDNode>(DDI->getVariable());
+ if (!N) return;
+
+ DIDescriptor DV(N);
+ if (!DV.isVariable())
+ return;
+
+ if (!NodesSeen.insert(DV))
+ return;
+ if (DIVariable(N).getVersion() <= LLVMDebugVersion10)
+ addCompileUnit(DIVariable(N).getCompileUnit());
+ processType(DIVariable(N).getType());
+}
+
+/// addType - Add type into Tys.
+bool DebugInfoFinder::addType(DIType DT) {
+ if (!DT.isValid())
+ return false;
+
+ if (!NodesSeen.insert(DT))
+ return false;
+
+ TYs.push_back(DT);
+ return true;
+}
+
+/// addCompileUnit - Add compile unit into CUs.
+bool DebugInfoFinder::addCompileUnit(DICompileUnit CU) {
+ if (!CU.Verify())
+ return false;
+
+ if (!NodesSeen.insert(CU))
+ return false;
+
+ CUs.push_back(CU);
+ return true;
+}
+
+/// addGlobalVariable - Add global variable into GVs.
+bool DebugInfoFinder::addGlobalVariable(DIGlobalVariable DIG) {
+ if (!DIDescriptor(DIG).isGlobalVariable())
+ return false;
+
+ if (!NodesSeen.insert(DIG))
+ return false;
+
+ GVs.push_back(DIG);
+ return true;
+}
+
+// addSubprogram - Add subprgoram into SPs.
+bool DebugInfoFinder::addSubprogram(DISubprogram SP) {
+ if (!DIDescriptor(SP).isSubprogram())
+ return false;
+
+ if (!NodesSeen.insert(SP))
+ return false;
+
+ SPs.push_back(SP);
+ return true;
+}
+
+//===----------------------------------------------------------------------===//
+// DIDescriptor: dump routines for all descriptors.
+//===----------------------------------------------------------------------===//
+
+/// dump - Print descriptor to dbgs() with a newline.
+void DIDescriptor::dump() const {
+ print(dbgs()); dbgs() << '\n';
+}
+
+/// print - Print descriptor.
+void DIDescriptor::print(raw_ostream &OS) const {
+ if (!DbgNode) return;
+
+ if (const char *Tag = dwarf::TagString(getTag()))
+ OS << "[ " << Tag << " ]";
+
+ if (this->isSubrange()) {
+ DISubrange(DbgNode).printInternal(OS);
+ } else if (this->isCompileUnit()) {
+ DICompileUnit(DbgNode).printInternal(OS);
+ } else if (this->isFile()) {
+ DIFile(DbgNode).printInternal(OS);
+ } else if (this->isEnumerator()) {
+ DIEnumerator(DbgNode).printInternal(OS);
+ } else if (this->isBasicType()) {
+ DIType(DbgNode).printInternal(OS);
+ } else if (this->isDerivedType()) {
+ DIDerivedType(DbgNode).printInternal(OS);
+ } else if (this->isCompositeType()) {
+ DICompositeType(DbgNode).printInternal(OS);
+ } else if (this->isSubprogram()) {
+ DISubprogram(DbgNode).printInternal(OS);
+ } else if (this->isGlobalVariable()) {
+ DIGlobalVariable(DbgNode).printInternal(OS);
+ } else if (this->isVariable()) {
+ DIVariable(DbgNode).printInternal(OS);
+ } else if (this->isObjCProperty()) {
+ DIObjCProperty(DbgNode).printInternal(OS);
+ } else if (this->isScope()) {
+ DIScope(DbgNode).printInternal(OS);
+ }
+}
+
+void DISubrange::printInternal(raw_ostream &OS) const {
+ OS << " [" << getLo() << ", " << getHi() << ']';
+}
+
+void DIScope::printInternal(raw_ostream &OS) const {
+ OS << " [" << getDirectory() << "/" << getFilename() << ']';
+}
+
+void DICompileUnit::printInternal(raw_ostream &OS) const {
+ DIScope::printInternal(OS);
+ if (unsigned Lang = getLanguage())
+ OS << " [" << dwarf::LanguageString(Lang) << ']';
+}
+
+void DIEnumerator::printInternal(raw_ostream &OS) const {
+ OS << " [" << getName() << " :: " << getEnumValue() << ']';
+}
+
+void DIType::printInternal(raw_ostream &OS) const {
+ if (!DbgNode) return;
+
+ StringRef Res = getName();
+ if (!Res.empty())
+ OS << " [" << Res << "]";
+
+ // TODO: Print context?
+
+ OS << " [line " << getLineNumber()
+ << ", size " << getSizeInBits()
+ << ", align " << getAlignInBits()
+ << ", offset " << getOffsetInBits();
+ if (isBasicType())
+ if (const char *Enc =
+ dwarf::AttributeEncodingString(DIBasicType(DbgNode).getEncoding()))
+ OS << ", enc " << Enc;
+ OS << "]";
+
+ if (isPrivate())
+ OS << " [private]";
+ else if (isProtected())
+ OS << " [protected]";
+
+ if (isForwardDecl())
+ OS << " [fwd]";
+}
+
+void DIDerivedType::printInternal(raw_ostream &OS) const {
+ DIType::printInternal(OS);
+ OS << " [from " << getTypeDerivedFrom().getName() << ']';
+}
+
+void DICompositeType::printInternal(raw_ostream &OS) const {
+ DIType::printInternal(OS);
+ DIArray A = getTypeArray();
+ OS << " [" << A.getNumElements() << " elements]";
+}
+
+void DISubprogram::printInternal(raw_ostream &OS) const {
+ // TODO : Print context
+ OS << " [line " << getLineNumber() << ']';
+
+ if (isLocalToUnit())
+ OS << " [local]";
+
+ if (isDefinition())
+ OS << " [def]";
+
+ if (getScopeLineNumber() != getLineNumber())
+ OS << " [scope " << getScopeLineNumber() << "]";
+
+ StringRef Res = getName();
+ if (!Res.empty())
+ OS << " [" << Res << ']';
+}
+
+void DIGlobalVariable::printInternal(raw_ostream &OS) const {
+ StringRef Res = getName();
+ if (!Res.empty())
+ OS << " [" << Res << ']';
+
+ OS << " [line " << getLineNumber() << ']';
+
+ // TODO : Print context
+
+ if (isLocalToUnit())
+ OS << " [local]";
+
+ if (isDefinition())
+ OS << " [def]";
+}
+
+void DIVariable::printInternal(raw_ostream &OS) const {
+ StringRef Res = getName();
+ if (!Res.empty())
+ OS << " [" << Res << ']';
+
+ OS << " [line " << getLineNumber() << ']';
+}
+
+void DIObjCProperty::printInternal(raw_ostream &OS) const {
+ StringRef Name = getObjCPropertyName();
+ if (!Name.empty())
+ OS << " [" << Name << ']';
+
+ OS << " [line " << getLineNumber()
+ << ", properties " << getUnsignedField(6) << ']';
+}
+
+static void printDebugLoc(DebugLoc DL, raw_ostream &CommentOS,
+ const LLVMContext &Ctx) {
+ if (!DL.isUnknown()) { // Print source line info.
+ DIScope Scope(DL.getScope(Ctx));
+ // Omit the directory, because it's likely to be long and uninteresting.
+ if (Scope.Verify())
+ CommentOS << Scope.getFilename();
+ else
+ CommentOS << "<unknown>";
+ CommentOS << ':' << DL.getLine();
+ if (DL.getCol() != 0)
+ CommentOS << ':' << DL.getCol();
+ DebugLoc InlinedAtDL = DebugLoc::getFromDILocation(DL.getInlinedAt(Ctx));
+ if (!InlinedAtDL.isUnknown()) {
+ CommentOS << " @[ ";
+ printDebugLoc(InlinedAtDL, CommentOS, Ctx);
+ CommentOS << " ]";
+ }
+ }
+}
+
+void DIVariable::printExtendedName(raw_ostream &OS) const {
+ const LLVMContext &Ctx = DbgNode->getContext();
+ StringRef Res = getName();
+ if (!Res.empty())
+ OS << Res << "," << getLineNumber();
+ if (MDNode *InlinedAt = getInlinedAt()) {
+ DebugLoc InlinedAtDL = DebugLoc::getFromDILocation(InlinedAt);
+ if (!InlinedAtDL.isUnknown()) {
+ OS << " @[";
+ printDebugLoc(InlinedAtDL, OS, Ctx);
+ OS << "]";
+ }
+ }
+}
diff --git a/lib/VMCore/DebugLoc.cpp b/lib/VMCore/DebugLoc.cpp
index 9013d28..c6a3053 100644
--- a/lib/VMCore/DebugLoc.cpp
+++ b/lib/VMCore/DebugLoc.cpp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/Support/DebugLoc.h"
+#include "llvm/DebugInfo.h"
#include "llvm/ADT/DenseMapInfo.h"
#include "LLVMContextImpl.h"
using namespace llvm;
@@ -114,34 +115,19 @@ MDNode *DebugLoc::getAsMDNode(const LLVMContext &Ctx) const {
/// 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));
+ DILocation Loc(N);
+ MDNode *Scope = Loc.getScope();
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)));
+ return get(Loc.getLineNumber(), Loc.getColumnNumber(), Scope,
+ Loc.getOrigLocation());
}
/// getFromDILexicalBlock - Translate the DILexicalBlock into a DebugLoc.
DebugLoc DebugLoc::getFromDILexicalBlock(MDNode *N) {
- if (N == 0 || N->getNumOperands() < 3) return DebugLoc();
-
- MDNode *Scope = dyn_cast_or_null<MDNode>(N->getOperand(1));
+ DILexicalBlock LexBlock(N);
+ MDNode *Scope = LexBlock.getContext();
if (Scope == 0) return DebugLoc();
-
- unsigned LineNo = 0, ColNo = 0;
- if (ConstantInt *Line = dyn_cast_or_null<ConstantInt>(N->getOperand(2)))
- LineNo = Line->getZExtValue();
- if (ConstantInt *Col = dyn_cast_or_null<ConstantInt>(N->getOperand(3)))
- ColNo = Col->getZExtValue();
-
- return get(LineNo, ColNo, Scope, NULL);
+ return get(LexBlock.getLineNumber(), LexBlock.getColumnNumber(), Scope, NULL);
}
void DebugLoc::dump(const LLVMContext &Ctx) const {
@@ -164,22 +150,10 @@ void DebugLoc::dump(const LLVMContext &Ctx) const {
// DenseMap specialization
//===----------------------------------------------------------------------===//
-DebugLoc DenseMapInfo<DebugLoc>::getEmptyKey() {
- return DebugLoc::getEmptyKey();
-}
-
-DebugLoc DenseMapInfo<DebugLoc>::getTombstoneKey() {
- return DebugLoc::getTombstoneKey();
-}
-
unsigned DenseMapInfo<DebugLoc>::getHashValue(const DebugLoc &Key) {
return static_cast<unsigned>(hash_combine(Key.LineCol, Key.ScopeIdx));
}
-bool DenseMapInfo<DebugLoc>::isEqual(const DebugLoc &LHS, const DebugLoc &RHS) {
- return LHS == RHS;
-}
-
//===----------------------------------------------------------------------===//
// LLVMContextImpl Implementation
//===----------------------------------------------------------------------===//
diff --git a/lib/VMCore/Dominators.cpp b/lib/VMCore/Dominators.cpp
index 219e631..682d928 100644
--- a/lib/VMCore/Dominators.cpp
+++ b/lib/VMCore/Dominators.cpp
@@ -39,6 +39,22 @@ static cl::opt<bool,true>
VerifyDomInfoX("verify-dom-info", cl::location(VerifyDomInfo),
cl::desc("Verify dominator info (time consuming)"));
+namespace llvm {
+ class BasicBlockEdge {
+ const BasicBlock *Start;
+ const BasicBlock *End;
+ public:
+ BasicBlockEdge(const BasicBlock *Start_, const BasicBlock *End_) :
+ Start(Start_), End(End_) { }
+ const BasicBlock *getStart() const {
+ return Start;
+ }
+ const BasicBlock *getEnd() const {
+ return End;
+ }
+ };
+}
+
//===----------------------------------------------------------------------===//
// DominatorTree Implementation
//===----------------------------------------------------------------------===//
@@ -142,12 +158,22 @@ bool DominatorTree::dominates(const Instruction *Def,
// Invoke results are only usable in the normal destination, not in the
// exceptional destination.
BasicBlock *NormalDest = II->getNormalDest();
- if (!dominates(NormalDest, UseBB))
+ BasicBlockEdge E(DefBB, NormalDest);
+ return dominates(E, UseBB);
+}
+
+bool DominatorTree::dominates(const BasicBlockEdge &BBE,
+ const BasicBlock *UseBB) const {
+ // If the BB the edge ends in doesn't dominate the use BB, then the
+ // edge also doesn't.
+ const BasicBlock *Start = BBE.getStart();
+ const BasicBlock *End = BBE.getEnd();
+ if (!dominates(End, UseBB))
return false;
- // Simple case: if the normal destination has a single predecessor, the
- // fact that it dominates the use block implies that we also do.
- if (NormalDest->getSinglePredecessor())
+ // Simple case: if the end BB has a single predecessor, the fact that it
+ // dominates the use block implies that the edge also does.
+ if (End->getSinglePredecessor())
return true;
// The normal edge from the invoke is critical. Conceptually, what we would
@@ -170,29 +196,40 @@ bool DominatorTree::dominates(const Instruction *Def,
// trivially dominates itself, so we only have to find if it dominates the
// other predecessors. Since the only way out of X is via NormalDest, X can
// only properly dominate a node if NormalDest dominates that node too.
- for (pred_iterator PI = pred_begin(NormalDest),
- E = pred_end(NormalDest); PI != E; ++PI) {
+ for (const_pred_iterator PI = pred_begin(End), E = pred_end(End);
+ PI != E; ++PI) {
const BasicBlock *BB = *PI;
- if (BB == DefBB)
+ if (BB == Start)
continue;
- if (!DT->isReachableFromEntry(BB))
- continue;
-
- if (!dominates(NormalDest, BB))
+ if (!dominates(End, BB))
return false;
}
return true;
}
-bool DominatorTree::dominates(const Instruction *Def,
+bool DominatorTree::dominates(const BasicBlockEdge &BBE,
const Use &U) const {
- Instruction *UserInst = dyn_cast<Instruction>(U.getUser());
+ Instruction *UserInst = cast<Instruction>(U.getUser());
+ // A PHI in the end of the edge is dominated by it.
+ PHINode *PN = dyn_cast<PHINode>(UserInst);
+ if (PN && PN->getParent() == BBE.getEnd() &&
+ PN->getIncomingBlock(U) == BBE.getStart())
+ return true;
- // Instructions do not dominate non-instructions.
- if (!UserInst)
- return false;
+ // Otherwise use the edge-dominates-block query, which
+ // handles the crazy critical edge cases properly.
+ const BasicBlock *UseBB;
+ if (PN)
+ UseBB = PN->getIncomingBlock(U);
+ else
+ UseBB = UserInst->getParent();
+ return dominates(BBE, UseBB);
+}
+bool DominatorTree::dominates(const Instruction *Def,
+ const Use &U) const {
+ Instruction *UserInst = cast<Instruction>(U.getUser());
const BasicBlock *DefBB = Def->getParent();
// Determine the block in which the use happens. PHI nodes use
@@ -218,17 +255,9 @@ bool DominatorTree::dominates(const Instruction *Def,
// their own block, except possibly a phi, so we don't need to
// walk the block in any case.
if (const InvokeInst *II = dyn_cast<InvokeInst>(Def)) {
- // A PHI in the normal successor using the invoke's return value is
- // dominated by the invoke's return value.
- if (isa<PHINode>(UserInst) &&
- UserInst->getParent() == II->getNormalDest() &&
- cast<PHINode>(UserInst)->getIncomingBlock(U) == DefBB)
- return true;
-
- // Otherwise use the instruction-dominates-block query, which
- // handles the crazy case of an invoke with a critical edge
- // properly.
- return dominates(Def, UseBB);
+ BasicBlock *NormalDest = II->getNormalDest();
+ BasicBlockEdge E(DefBB, NormalDest);
+ return dominates(E, U);
}
// If the def and use are in different blocks, do a simple CFG dominator
diff --git a/lib/VMCore/Function.cpp b/lib/VMCore/Function.cpp
index af6344e..2e0b316 100644
--- a/lib/VMCore/Function.cpp
+++ b/lib/VMCore/Function.cpp
@@ -29,7 +29,6 @@
#include "llvm/ADT/StringExtras.h"
using namespace llvm;
-
// Explicit instantiations of SymbolTableListTraits since some of the methods
// are not in the public header file...
template class llvm::SymbolTableListTraits<Argument, Function>;
@@ -358,17 +357,239 @@ std::string Intrinsic::getName(ID id, ArrayRef<Type*> Tys) {
return Result;
}
-FunctionType *Intrinsic::getType(LLVMContext &Context,
- ID id, ArrayRef<Type*> Tys) {
- Type *ResultTy = NULL;
- SmallVector<Type*, 8> ArgTys;
- bool IsVarArg = false;
+
+/// IIT_Info - These are enumerators that describe the entries returned by the
+/// getIntrinsicInfoTableEntries function.
+///
+/// NOTE: This must be kept in synch with the copy in TblGen/IntrinsicEmitter!
+enum IIT_Info {
+ // Common values should be encoded with 0-15.
+ IIT_Done = 0,
+ IIT_I1 = 1,
+ IIT_I8 = 2,
+ IIT_I16 = 3,
+ IIT_I32 = 4,
+ IIT_I64 = 5,
+ IIT_F32 = 6,
+ IIT_F64 = 7,
+ IIT_V2 = 8,
+ IIT_V4 = 9,
+ IIT_V8 = 10,
+ IIT_V16 = 11,
+ IIT_V32 = 12,
+ IIT_MMX = 13,
+ IIT_PTR = 14,
+ IIT_ARG = 15,
-#define GET_INTRINSIC_GENERATOR
+ // Values from 16+ are only encodable with the inefficient encoding.
+ IIT_METADATA = 16,
+ IIT_EMPTYSTRUCT = 17,
+ IIT_STRUCT2 = 18,
+ IIT_STRUCT3 = 19,
+ IIT_STRUCT4 = 20,
+ IIT_STRUCT5 = 21,
+ IIT_EXTEND_VEC_ARG = 22,
+ IIT_TRUNC_VEC_ARG = 23,
+ IIT_ANYPTR = 24
+};
+
+
+static void DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos,
+ SmallVectorImpl<Intrinsic::IITDescriptor> &OutputTable) {
+ IIT_Info Info = IIT_Info(Infos[NextElt++]);
+ unsigned StructElts = 2;
+ using namespace Intrinsic;
+
+ switch (Info) {
+ case IIT_Done:
+ OutputTable.push_back(IITDescriptor::get(IITDescriptor::Void, 0));
+ return;
+ case IIT_MMX:
+ OutputTable.push_back(IITDescriptor::get(IITDescriptor::MMX, 0));
+ return;
+ case IIT_METADATA:
+ OutputTable.push_back(IITDescriptor::get(IITDescriptor::Metadata, 0));
+ return;
+ case IIT_F32:
+ OutputTable.push_back(IITDescriptor::get(IITDescriptor::Float, 0));
+ return;
+ case IIT_F64:
+ OutputTable.push_back(IITDescriptor::get(IITDescriptor::Double, 0));
+ return;
+ case IIT_I1:
+ OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer, 1));
+ return;
+ case IIT_I8:
+ OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer, 8));
+ return;
+ case IIT_I16:
+ OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer,16));
+ return;
+ case IIT_I32:
+ OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer, 32));
+ return;
+ case IIT_I64:
+ OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer, 64));
+ return;
+ case IIT_V2:
+ OutputTable.push_back(IITDescriptor::get(IITDescriptor::Vector, 2));
+ DecodeIITType(NextElt, Infos, OutputTable);
+ return;
+ case IIT_V4:
+ OutputTable.push_back(IITDescriptor::get(IITDescriptor::Vector, 4));
+ DecodeIITType(NextElt, Infos, OutputTable);
+ return;
+ case IIT_V8:
+ OutputTable.push_back(IITDescriptor::get(IITDescriptor::Vector, 8));
+ DecodeIITType(NextElt, Infos, OutputTable);
+ return;
+ case IIT_V16:
+ OutputTable.push_back(IITDescriptor::get(IITDescriptor::Vector, 16));
+ DecodeIITType(NextElt, Infos, OutputTable);
+ return;
+ case IIT_V32:
+ OutputTable.push_back(IITDescriptor::get(IITDescriptor::Vector, 32));
+ DecodeIITType(NextElt, Infos, OutputTable);
+ return;
+ case IIT_PTR:
+ OutputTable.push_back(IITDescriptor::get(IITDescriptor::Pointer, 0));
+ DecodeIITType(NextElt, Infos, OutputTable);
+ return;
+ case IIT_ANYPTR: { // [ANYPTR addrspace, subtype]
+ OutputTable.push_back(IITDescriptor::get(IITDescriptor::Pointer,
+ Infos[NextElt++]));
+ DecodeIITType(NextElt, Infos, OutputTable);
+ return;
+ }
+ case IIT_ARG: {
+ unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
+ OutputTable.push_back(IITDescriptor::get(IITDescriptor::Argument, ArgInfo));
+ return;
+ }
+ case IIT_EXTEND_VEC_ARG: {
+ unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
+ OutputTable.push_back(IITDescriptor::get(IITDescriptor::ExtendVecArgument,
+ ArgInfo));
+ return;
+ }
+ case IIT_TRUNC_VEC_ARG: {
+ unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
+ OutputTable.push_back(IITDescriptor::get(IITDescriptor::TruncVecArgument,
+ ArgInfo));
+ return;
+ }
+ case IIT_EMPTYSTRUCT:
+ OutputTable.push_back(IITDescriptor::get(IITDescriptor::Struct, 0));
+ return;
+ case IIT_STRUCT5: ++StructElts; // FALL THROUGH.
+ case IIT_STRUCT4: ++StructElts; // FALL THROUGH.
+ case IIT_STRUCT3: ++StructElts; // FALL THROUGH.
+ case IIT_STRUCT2: {
+ OutputTable.push_back(IITDescriptor::get(IITDescriptor::Struct,StructElts));
+
+ for (unsigned i = 0; i != StructElts; ++i)
+ DecodeIITType(NextElt, Infos, OutputTable);
+ return;
+ }
+ }
+ llvm_unreachable("unhandled");
+}
+
+
+#define GET_INTRINSIC_GENERATOR_GLOBAL
#include "llvm/Intrinsics.gen"
-#undef GET_INTRINSIC_GENERATOR
+#undef GET_INTRINSIC_GENERATOR_GLOBAL
+
+void Intrinsic::getIntrinsicInfoTableEntries(ID id,
+ SmallVectorImpl<IITDescriptor> &T){
+ // Check to see if the intrinsic's type was expressible by the table.
+ unsigned TableVal = IIT_Table[id-1];
+
+ // Decode the TableVal into an array of IITValues.
+ SmallVector<unsigned char, 8> IITValues;
+ ArrayRef<unsigned char> IITEntries;
+ unsigned NextElt = 0;
+ if ((TableVal >> 31) != 0) {
+ // This is an offset into the IIT_LongEncodingTable.
+ IITEntries = IIT_LongEncodingTable;
+
+ // Strip sentinel bit.
+ NextElt = (TableVal << 1) >> 1;
+ } else {
+ // Decode the TableVal into an array of IITValues. If the entry was encoded
+ // into a single word in the table itself, decode it now.
+ do {
+ IITValues.push_back(TableVal & 0xF);
+ TableVal >>= 4;
+ } while (TableVal);
+
+ IITEntries = IITValues;
+ NextElt = 0;
+ }
- return FunctionType::get(ResultTy, ArgTys, IsVarArg);
+ // Okay, decode the table into the output vector of IITDescriptors.
+ DecodeIITType(NextElt, IITEntries, T);
+ while (NextElt != IITEntries.size() && IITEntries[NextElt] != 0)
+ DecodeIITType(NextElt, IITEntries, T);
+}
+
+
+static Type *DecodeFixedType(ArrayRef<Intrinsic::IITDescriptor> &Infos,
+ ArrayRef<Type*> Tys, LLVMContext &Context) {
+ using namespace Intrinsic;
+ IITDescriptor D = Infos.front();
+ Infos = Infos.slice(1);
+
+ switch (D.Kind) {
+ case IITDescriptor::Void: return Type::getVoidTy(Context);
+ case IITDescriptor::MMX: return Type::getX86_MMXTy(Context);
+ case IITDescriptor::Metadata: return Type::getMetadataTy(Context);
+ case IITDescriptor::Float: return Type::getFloatTy(Context);
+ case IITDescriptor::Double: return Type::getDoubleTy(Context);
+
+ case IITDescriptor::Integer:
+ return IntegerType::get(Context, D.Integer_Width);
+ case IITDescriptor::Vector:
+ return VectorType::get(DecodeFixedType(Infos, Tys, Context),D.Vector_Width);
+ case IITDescriptor::Pointer:
+ return PointerType::get(DecodeFixedType(Infos, Tys, Context),
+ D.Pointer_AddressSpace);
+ case IITDescriptor::Struct: {
+ Type *Elts[5];
+ assert(D.Struct_NumElements <= 5 && "Can't handle this yet");
+ for (unsigned i = 0, e = D.Struct_NumElements; i != e; ++i)
+ Elts[i] = DecodeFixedType(Infos, Tys, Context);
+ return StructType::get(Context, ArrayRef<Type*>(Elts,D.Struct_NumElements));
+ }
+
+ case IITDescriptor::Argument:
+ return Tys[D.getArgumentNumber()];
+ case IITDescriptor::ExtendVecArgument:
+ return VectorType::getExtendedElementVectorType(cast<VectorType>(
+ Tys[D.getArgumentNumber()]));
+
+ case IITDescriptor::TruncVecArgument:
+ return VectorType::getTruncatedElementVectorType(cast<VectorType>(
+ Tys[D.getArgumentNumber()]));
+ }
+ llvm_unreachable("unhandled");
+}
+
+
+
+FunctionType *Intrinsic::getType(LLVMContext &Context,
+ ID id, ArrayRef<Type*> Tys) {
+ SmallVector<IITDescriptor, 8> Table;
+ getIntrinsicInfoTableEntries(id, Table);
+
+ ArrayRef<IITDescriptor> TableRef = Table;
+ Type *ResultTy = DecodeFixedType(TableRef, Tys, Context);
+
+ SmallVector<Type*, 8> ArgTys;
+ while (!TableRef.empty())
+ ArgTys.push_back(DecodeFixedType(TableRef, Tys, Context));
+
+ return FunctionType::get(ResultTy, ArgTys, false);
}
bool Intrinsic::isOverloaded(ID id) {
@@ -400,7 +621,8 @@ Function *Intrinsic::getDeclaration(Module *M, ID id, ArrayRef<Type*> Tys) {
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;
- // FIXME: Check for blockaddress, which does not take the address.
+ if (isa<BlockAddress>(U))
+ continue;
if (!isa<CallInst>(U) && !isa<InvokeInst>(U))
return PutOffender ? (*PutOffender = U, true) : true;
ImmutableCallSite CS(cast<Instruction>(U));
@@ -439,4 +661,3 @@ bool Function::callsFunctionThatReturnsTwice() const {
return false;
}
-// vim: sw=2 ai
diff --git a/lib/VMCore/GCOV.cpp b/lib/VMCore/GCOV.cpp
index 595c452..003a5d4 100644
--- a/lib/VMCore/GCOV.cpp
+++ b/lib/VMCore/GCOV.cpp
@@ -64,7 +64,7 @@ bool GCOVFile::read(GCOVBuffer &Buffer) {
/// dump - Dump GCOVFile content on standard out for debugging purposes.
void GCOVFile::dump() {
for (SmallVector<GCOVFunction *, 16>::iterator I = Functions.begin(),
- E = Functions.end(); I != E; ++I)
+ E = Functions.end(); I != E; ++I)
(*I)->dump();
}
@@ -72,7 +72,7 @@ void GCOVFile::dump() {
/// reading .gcno and .gcda files.
void GCOVFile::collectLineCounts(FileInfo &FI) {
for (SmallVector<GCOVFunction *, 16>::iterator I = Functions.begin(),
- E = Functions.end(); I != E; ++I)
+ E = Functions.end(); I != E; ++I)
(*I)->collectLineCounts(FI);
FI.print();
}
@@ -143,7 +143,7 @@ bool GCOVFunction::read(GCOVBuffer &Buff, GCOVFormat Format) {
StringRef Filename = Buff.readString();
if (Buff.getCursor() == (Size - 4)) break;
while (uint32_t L = Buff.readInt())
- Block->addLine(Filename, L);
+ Block->addLine(Filename, L);
}
Buff.readInt(); // flag
}
@@ -154,7 +154,7 @@ bool GCOVFunction::read(GCOVBuffer &Buff, GCOVFormat Format) {
void GCOVFunction::dump() {
outs() << "===== " << Name << " @ " << Filename << ":" << LineNumber << "\n";
for (SmallVector<GCOVBlock *, 16>::iterator I = Blocks.begin(),
- E = Blocks.end(); I != E; ++I)
+ E = Blocks.end(); I != E; ++I)
(*I)->dump();
}
@@ -162,7 +162,7 @@ void GCOVFunction::dump() {
/// reading .gcno and .gcda files.
void GCOVFunction::collectLineCounts(FileInfo &FI) {
for (SmallVector<GCOVBlock *, 16>::iterator I = Blocks.begin(),
- E = Blocks.end(); I != E; ++I)
+ E = Blocks.end(); I != E; ++I)
(*I)->collectLineCounts(FI);
}
@@ -186,7 +186,7 @@ void GCOVBlock::addLine(StringRef Filename, uint32_t LineNo) {
/// reading .gcno and .gcda files.
void GCOVBlock::collectLineCounts(FileInfo &FI) {
for (StringMap<GCOVLines *>::iterator I = Lines.begin(),
- E = Lines.end(); I != E; ++I)
+ E = Lines.end(); I != E; ++I)
I->second->collectLineCounts(FI, I->first(), Counter);
}
@@ -196,14 +196,14 @@ void GCOVBlock::dump() {
if (!Edges.empty()) {
outs() << "\tEdges : ";
for (SmallVector<uint32_t, 16>::iterator I = Edges.begin(), E = Edges.end();
- I != E; ++I)
+ I != E; ++I)
outs() << (*I) << ",";
outs() << "\n";
}
if (!Lines.empty()) {
outs() << "\tLines : ";
for (StringMap<GCOVLines *>::iterator LI = Lines.begin(),
- LE = Lines.end(); LI != LE; ++LI) {
+ LE = Lines.end(); LI != LE; ++LI) {
outs() << LI->first() << " -> ";
LI->second->dump();
outs() << "\n";
@@ -217,16 +217,16 @@ void GCOVBlock::dump() {
/// collectLineCounts - Collect line counts. This must be used after
/// reading .gcno and .gcda files.
void GCOVLines::collectLineCounts(FileInfo &FI, StringRef Filename,
- uint32_t Count) {
+ uint32_t Count) {
for (SmallVector<uint32_t, 16>::iterator I = Lines.begin(),
- E = Lines.end(); I != E; ++I)
+ E = Lines.end(); I != E; ++I)
FI.addLineCount(Filename, *I, Count);
}
/// dump - Dump GCOVLines content on standard out for debugging purposes.
void GCOVLines::dump() {
for (SmallVector<uint32_t, 16>::iterator I = Lines.begin(),
- E = Lines.end(); I != E; ++I)
+ E = Lines.end(); I != E; ++I)
outs() << (*I) << ",";
}
@@ -266,12 +266,12 @@ void FileInfo::print() {
StringRef AllLines = Buff.take()->getBuffer();
for (unsigned i = 0, e = L.size(); i != e; ++i) {
if (L[i])
- outs() << L[i] << ":\t";
+ outs() << L[i] << ":\t";
else
- outs() << " :\t";
+ outs() << " :\t";
std::pair<StringRef, StringRef> P = AllLines.split('\n');
if (AllLines != P.first)
- outs() << P.first;
+ outs() << P.first;
outs() << "\n";
AllLines = P.second;
}
diff --git a/lib/VMCore/Globals.cpp b/lib/VMCore/Globals.cpp
index 4254fb2..c428b88 100644
--- a/lib/VMCore/Globals.cpp
+++ b/lib/VMCore/Globals.cpp
@@ -82,12 +82,12 @@ bool GlobalValue::isDeclaration() const {
GlobalVariable::GlobalVariable(Type *Ty, bool constant, LinkageTypes Link,
Constant *InitVal, const Twine &Name,
- bool ThreadLocal, unsigned AddressSpace)
- : GlobalValue(PointerType::get(Ty, AddressSpace),
+ ThreadLocalMode TLMode, unsigned AddressSpace)
+ : GlobalValue(PointerType::get(Ty, AddressSpace),
Value::GlobalVariableVal,
OperandTraits<GlobalVariable>::op_begin(this),
InitVal != 0, Link, Name),
- isConstantGlobal(constant), isThreadLocalSymbol(ThreadLocal) {
+ isConstantGlobal(constant), threadLocalMode(TLMode) {
if (InitVal) {
assert(InitVal->getType() == Ty &&
"Initializer should be the same type as the GlobalVariable!");
@@ -100,13 +100,13 @@ GlobalVariable::GlobalVariable(Type *Ty, bool constant, LinkageTypes Link,
GlobalVariable::GlobalVariable(Module &M, Type *Ty, bool constant,
LinkageTypes Link, Constant *InitVal,
const Twine &Name,
- GlobalVariable *Before, bool ThreadLocal,
+ GlobalVariable *Before, ThreadLocalMode TLMode,
unsigned AddressSpace)
- : GlobalValue(PointerType::get(Ty, AddressSpace),
+ : GlobalValue(PointerType::get(Ty, AddressSpace),
Value::GlobalVariableVal,
OperandTraits<GlobalVariable>::op_begin(this),
InitVal != 0, Link, Name),
- isConstantGlobal(constant), isThreadLocalSymbol(ThreadLocal) {
+ isConstantGlobal(constant), threadLocalMode(TLMode) {
if (InitVal) {
assert(InitVal->getType() == Ty &&
"Initializer should be the same type as the GlobalVariable!");
diff --git a/lib/VMCore/IRBuilder.cpp b/lib/VMCore/IRBuilder.cpp
index b459234..5c4e6d9 100644
--- a/lib/VMCore/IRBuilder.cpp
+++ b/lib/VMCore/IRBuilder.cpp
@@ -12,9 +12,9 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Support/IRBuilder.h"
-#include "llvm/GlobalVariable.h"
#include "llvm/Function.h"
+#include "llvm/GlobalVariable.h"
+#include "llvm/IRBuilder.h"
#include "llvm/Intrinsics.h"
#include "llvm/LLVMContext.h"
using namespace llvm;
@@ -28,7 +28,7 @@ Value *IRBuilderBase::CreateGlobalString(StringRef Str, const Twine &Name) {
Module &M = *BB->getParent()->getParent();
GlobalVariable *GV = new GlobalVariable(M, StrConstant->getType(),
true, GlobalValue::PrivateLinkage,
- StrConstant, "", 0, false);
+ StrConstant);
GV->setName(Name);
GV->setUnnamedAddr(true);
return GV;
@@ -120,13 +120,13 @@ CreateMemMove(Value *Dst, Value *Src, Value *Size, unsigned Align,
CallInst *IRBuilderBase::CreateLifetimeStart(Value *Ptr, ConstantInt *Size) {
assert(isa<PointerType>(Ptr->getType()) &&
- "lifetime.start only applies to pointers.");
+ "lifetime.start only applies to pointers.");
Ptr = getCastedInt8PtrValue(Ptr);
if (!Size)
Size = getInt64(-1);
else
assert(Size->getType() == getInt64Ty() &&
- "lifetime.start requires the size to be an i64");
+ "lifetime.start requires the size to be an i64");
Value *Ops[] = { Size, Ptr };
Module *M = BB->getParent()->getParent();
Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::lifetime_start);
@@ -135,13 +135,13 @@ CallInst *IRBuilderBase::CreateLifetimeStart(Value *Ptr, ConstantInt *Size) {
CallInst *IRBuilderBase::CreateLifetimeEnd(Value *Ptr, ConstantInt *Size) {
assert(isa<PointerType>(Ptr->getType()) &&
- "lifetime.end only applies to pointers.");
+ "lifetime.end only applies to pointers.");
Ptr = getCastedInt8PtrValue(Ptr);
if (!Size)
Size = getInt64(-1);
else
assert(Size->getType() == getInt64Ty() &&
- "lifetime.end requires the size to be an i64");
+ "lifetime.end requires the size to be an i64");
Value *Ops[] = { Size, Ptr };
Module *M = BB->getParent()->getParent();
Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::lifetime_end);
diff --git a/lib/VMCore/Instruction.cpp b/lib/VMCore/Instruction.cpp
index 5449714..66379a0 100644
--- a/lib/VMCore/Instruction.cpp
+++ b/lib/VMCore/Instruction.cpp
@@ -226,34 +226,52 @@ bool Instruction::isIdenticalToWhenDefined(const Instruction *I) const {
RMWI->isVolatile() == cast<AtomicRMWInst>(I)->isVolatile() &&
RMWI->getOrdering() == cast<AtomicRMWInst>(I)->getOrdering() &&
RMWI->getSynchScope() == cast<AtomicRMWInst>(I)->getSynchScope();
-
+ if (const PHINode *thisPHI = dyn_cast<PHINode>(this)) {
+ const PHINode *otherPHI = cast<PHINode>(I);
+ for (unsigned i = 0, e = thisPHI->getNumOperands(); i != e; ++i) {
+ if (thisPHI->getIncomingBlock(i) != otherPHI->getIncomingBlock(i))
+ return false;
+ }
+ return true;
+ }
return true;
}
// isSameOperationAs
// This should be kept in sync with isEquivalentOperation in
// lib/Transforms/IPO/MergeFunctions.cpp.
-bool Instruction::isSameOperationAs(const Instruction *I) const {
+bool Instruction::isSameOperationAs(const Instruction *I,
+ unsigned flags) const {
+ bool IgnoreAlignment = flags & CompareIgnoringAlignment;
+ bool UseScalarTypes = flags & CompareUsingScalarTypes;
+
if (getOpcode() != I->getOpcode() ||
getNumOperands() != I->getNumOperands() ||
- getType() != I->getType())
+ (UseScalarTypes ?
+ getType()->getScalarType() != I->getType()->getScalarType() :
+ getType() != I->getType()))
return false;
// We have two instructions of identical opcode and #operands. Check to see
// if all operands are the same type
for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
- if (getOperand(i)->getType() != I->getOperand(i)->getType())
+ if (UseScalarTypes ?
+ getOperand(i)->getType()->getScalarType() !=
+ I->getOperand(i)->getType()->getScalarType() :
+ getOperand(i)->getType() != I->getOperand(i)->getType())
return false;
// Check special state that is a part of some instructions.
if (const LoadInst *LI = dyn_cast<LoadInst>(this))
return LI->isVolatile() == cast<LoadInst>(I)->isVolatile() &&
- LI->getAlignment() == cast<LoadInst>(I)->getAlignment() &&
+ (LI->getAlignment() == cast<LoadInst>(I)->getAlignment() ||
+ IgnoreAlignment) &&
LI->getOrdering() == cast<LoadInst>(I)->getOrdering() &&
LI->getSynchScope() == cast<LoadInst>(I)->getSynchScope();
if (const StoreInst *SI = dyn_cast<StoreInst>(this))
return SI->isVolatile() == cast<StoreInst>(I)->isVolatile() &&
- SI->getAlignment() == cast<StoreInst>(I)->getAlignment() &&
+ (SI->getAlignment() == cast<StoreInst>(I)->getAlignment() ||
+ IgnoreAlignment) &&
SI->getOrdering() == cast<StoreInst>(I)->getOrdering() &&
SI->getSynchScope() == cast<StoreInst>(I)->getSynchScope();
if (const CmpInst *CI = dyn_cast<CmpInst>(this))
@@ -388,6 +406,29 @@ bool Instruction::isCommutative(unsigned op) {
}
}
+/// isIdempotent - Return true if the instruction is idempotent:
+///
+/// Idempotent operators satisfy: x op x === x
+///
+/// In LLVM, the And and Or operators are idempotent.
+///
+bool Instruction::isIdempotent(unsigned Opcode) {
+ return Opcode == And || Opcode == Or;
+}
+
+/// isNilpotent - Return true if the instruction is nilpotent:
+///
+/// Nilpotent operators satisfy: x op x === Id,
+///
+/// where Id is the identity for the operator, i.e. a constant such that
+/// x op Id === x and Id op x === x for all x.
+///
+/// In LLVM, the Xor operator is nilpotent.
+///
+bool Instruction::isNilpotent(unsigned Opcode) {
+ return Opcode == Xor;
+}
+
Instruction *Instruction::clone() const {
Instruction *New = clone_impl();
New->SubclassOptionalData = SubclassOptionalData;
diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp
index 6c5db32..9af98e8 100644
--- a/lib/VMCore/Instructions.cpp
+++ b/lib/VMCore/Instructions.cpp
@@ -161,8 +161,14 @@ Value *PHINode::hasConstantValue() const {
// Exploit the fact that phi nodes always have at least one entry.
Value *ConstantValue = getIncomingValue(0);
for (unsigned i = 1, e = getNumIncomingValues(); i != e; ++i)
- if (getIncomingValue(i) != ConstantValue)
- return 0; // Incoming values not all the same.
+ if (getIncomingValue(i) != ConstantValue && getIncomingValue(i) != this) {
+ if (ConstantValue != this)
+ return 0; // Incoming values not all the same.
+ // The case where the first value is this PHI.
+ ConstantValue = getIncomingValue(i);
+ }
+ if (ConstantValue == this)
+ return UndefValue::get(getType());
return ConstantValue;
}
@@ -3158,6 +3164,7 @@ SwitchInst::SwitchInst(const SwitchInst &SI)
OL[i] = InOL[i];
OL[i+1] = InOL[i+1];
}
+ TheSubsets = SI.TheSubsets;
SubclassOptionalData = SI.SubclassOptionalData;
}
@@ -3169,6 +3176,16 @@ SwitchInst::~SwitchInst() {
/// addCase - Add an entry to the switch instruction...
///
void SwitchInst::addCase(ConstantInt *OnVal, BasicBlock *Dest) {
+ IntegersSubsetToBB Mapping;
+
+ // FIXME: Currently we work with ConstantInt based cases.
+ // So inititalize IntItem container directly from ConstantInt.
+ Mapping.add(IntItem::fromConstantInt(OnVal));
+ IntegersSubset CaseRanges = Mapping.getCase();
+ addCase(CaseRanges, Dest);
+}
+
+void SwitchInst::addCase(IntegersSubset& OnVal, BasicBlock *Dest) {
unsigned NewCaseIdx = getNumCases();
unsigned OpNo = NumOperands;
if (OpNo+2 > ReservedSpace)
@@ -3176,14 +3193,17 @@ void SwitchInst::addCase(ConstantInt *OnVal, BasicBlock *Dest) {
// Initialize some new operands.
assert(OpNo+1 < ReservedSpace && "Growing didn't work!");
NumOperands = OpNo+2;
- CaseIt Case(this, NewCaseIdx);
- Case.setValue(OnVal);
+
+ SubsetsIt TheSubsetsIt = TheSubsets.insert(TheSubsets.end(), OnVal);
+
+ CaseIt Case(this, NewCaseIdx, TheSubsetsIt);
+ Case.updateCaseValueOperand(OnVal);
Case.setSuccessor(Dest);
}
/// removeCase - This method removes the specified case and its successor
/// from the switch instruction.
-void SwitchInst::removeCase(CaseIt i) {
+void SwitchInst::removeCase(CaseIt& i) {
unsigned idx = i.getCaseIndex();
assert(2 + idx*2 < getNumOperands() && "Case index out of range!!!");
@@ -3200,6 +3220,16 @@ void SwitchInst::removeCase(CaseIt i) {
// Nuke the last value.
OL[NumOps-2].set(0);
OL[NumOps-2+1].set(0);
+
+ // Do the same with TheCases collection:
+ if (i.SubsetIt != --TheSubsets.end()) {
+ *i.SubsetIt = TheSubsets.back();
+ TheSubsets.pop_back();
+ } else {
+ TheSubsets.pop_back();
+ i.SubsetIt = TheSubsets.end();
+ }
+
NumOperands = NumOps-2;
}
diff --git a/lib/VMCore/Metadata.cpp b/lib/VMCore/Metadata.cpp
index 090b09a..95e5a8b 100644
--- a/lib/VMCore/Metadata.cpp
+++ b/lib/VMCore/Metadata.cpp
@@ -21,6 +21,7 @@
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/STLExtras.h"
#include "SymbolTableListTraitsImpl.h"
+#include "llvm/Support/ConstantRange.h"
#include "llvm/Support/LeakDetector.h"
#include "llvm/Support/ValueHandle.h"
using namespace llvm;
@@ -66,7 +67,11 @@ public:
MDNodeOperand(Value *V) : CallbackVH(V) {}
~MDNodeOperand() {}
- void set(Value *V) { this->setValPtr(V); }
+ void set(Value *V) {
+ unsigned IsFirst = this->getValPtrInt();
+ this->setValPtr(V);
+ this->setAsFirstOperand(IsFirst);
+ }
/// setAsFirstOperand - Accessor method to mark the operand as the first in
/// the list.
@@ -95,7 +100,7 @@ void MDNodeOperand::allUsesReplacedWith(Value *NV) {
static MDNodeOperand *getOperandPtr(MDNode *N, unsigned Op) {
// Use <= instead of < to permit a one-past-the-end address.
assert(Op <= N->getNumOperands() && "Invalid operand number");
- return reinterpret_cast<MDNodeOperand*>(N+1)+Op;
+ return reinterpret_cast<MDNodeOperand*>(N + 1) + Op;
}
void MDNode::replaceOperandWith(unsigned i, Value *Val) {
@@ -122,7 +127,6 @@ MDNode::MDNode(LLVMContext &C, ArrayRef<Value*> Vals, bool isFunctionLocal)
}
}
-
/// ~MDNode - Destroy MDNode.
MDNode::~MDNode() {
assert((getSubclassDataFromValue() & DestroyFlag) != 0 &&
@@ -196,7 +200,7 @@ const Function *MDNode::getFunction() const {
// destroy - Delete this node. Only when there are no uses.
void MDNode::destroy() {
setValueSubclassData(getSubclassDataFromValue() | DestroyFlag);
- // Placement delete, the free the memory.
+ // Placement delete, then free the memory.
this->~MDNode();
free(this);
}
@@ -247,7 +251,7 @@ MDNode *MDNode::getMDNode(LLVMContext &Context, ArrayRef<Value*> Vals,
}
// Coallocate space for the node and Operands together, then placement new.
- void *Ptr = malloc(sizeof(MDNode)+Vals.size()*sizeof(MDNodeOperand));
+ void *Ptr = malloc(sizeof(MDNode) + Vals.size() * sizeof(MDNodeOperand));
N = new (Ptr) MDNode(Context, Vals, isFunctionLocal);
// Cache the operand hash.
@@ -275,7 +279,7 @@ MDNode *MDNode::getIfExists(LLVMContext &Context, ArrayRef<Value*> Vals) {
MDNode *MDNode::getTemporary(LLVMContext &Context, ArrayRef<Value*> Vals) {
MDNode *N =
- (MDNode *)malloc(sizeof(MDNode)+Vals.size()*sizeof(MDNodeOperand));
+ (MDNode *)malloc(sizeof(MDNode) + Vals.size() * sizeof(MDNodeOperand));
N = new (N) MDNode(Context, Vals, FL_No);
N->setValueSubclassData(N->getSubclassDataFromValue() |
NotUniquedBit);
@@ -398,6 +402,155 @@ void MDNode::replaceOperand(MDNodeOperand *Op, Value *To) {
}
}
+MDNode *MDNode::getMostGenericTBAA(MDNode *A, MDNode *B) {
+ if (!A || !B)
+ return NULL;
+
+ if (A == B)
+ return A;
+
+ SmallVector<MDNode *, 4> PathA;
+ MDNode *T = A;
+ while (T) {
+ PathA.push_back(T);
+ T = T->getNumOperands() >= 2 ? cast_or_null<MDNode>(T->getOperand(1)) : 0;
+ }
+
+ SmallVector<MDNode *, 4> PathB;
+ T = B;
+ while (T) {
+ PathB.push_back(T);
+ T = T->getNumOperands() >= 2 ? cast_or_null<MDNode>(T->getOperand(1)) : 0;
+ }
+
+ int IA = PathA.size() - 1;
+ int IB = PathB.size() - 1;
+
+ MDNode *Ret = 0;
+ while (IA >= 0 && IB >=0) {
+ if (PathA[IA] == PathB[IB])
+ Ret = PathA[IA];
+ else
+ break;
+ --IA;
+ --IB;
+ }
+ return Ret;
+}
+
+MDNode *MDNode::getMostGenericFPMath(MDNode *A, MDNode *B) {
+ if (!A || !B)
+ return NULL;
+
+ APFloat AVal = cast<ConstantFP>(A->getOperand(0))->getValueAPF();
+ APFloat BVal = cast<ConstantFP>(B->getOperand(0))->getValueAPF();
+ if (AVal.compare(BVal) == APFloat::cmpLessThan)
+ return A;
+ return B;
+}
+
+static bool isContiguous(const ConstantRange &A, const ConstantRange &B) {
+ return A.getUpper() == B.getLower() || A.getLower() == B.getUpper();
+}
+
+static bool canBeMerged(const ConstantRange &A, const ConstantRange &B) {
+ return !A.intersectWith(B).isEmptySet() || isContiguous(A, B);
+}
+
+static bool tryMergeRange(SmallVector<Value*, 4> &EndPoints, ConstantInt *Low,
+ ConstantInt *High) {
+ ConstantRange NewRange(Low->getValue(), High->getValue());
+ unsigned Size = EndPoints.size();
+ APInt LB = cast<ConstantInt>(EndPoints[Size - 2])->getValue();
+ APInt LE = cast<ConstantInt>(EndPoints[Size - 1])->getValue();
+ ConstantRange LastRange(LB, LE);
+ if (canBeMerged(NewRange, LastRange)) {
+ ConstantRange Union = LastRange.unionWith(NewRange);
+ Type *Ty = High->getType();
+ EndPoints[Size - 2] = ConstantInt::get(Ty, Union.getLower());
+ EndPoints[Size - 1] = ConstantInt::get(Ty, Union.getUpper());
+ return true;
+ }
+ return false;
+}
+
+static void addRange(SmallVector<Value*, 4> &EndPoints, ConstantInt *Low,
+ ConstantInt *High) {
+ if (!EndPoints.empty())
+ if (tryMergeRange(EndPoints, Low, High))
+ return;
+
+ EndPoints.push_back(Low);
+ EndPoints.push_back(High);
+}
+
+MDNode *MDNode::getMostGenericRange(MDNode *A, MDNode *B) {
+ // Given two ranges, we want to compute the union of the ranges. This
+ // is slightly complitade by having to combine the intervals and merge
+ // the ones that overlap.
+
+ if (!A || !B)
+ return NULL;
+
+ if (A == B)
+ return A;
+
+ // First, walk both lists in older of the lower boundary of each interval.
+ // At each step, try to merge the new interval to the last one we adedd.
+ SmallVector<Value*, 4> EndPoints;
+ int AI = 0;
+ int BI = 0;
+ int AN = A->getNumOperands() / 2;
+ int BN = B->getNumOperands() / 2;
+ while (AI < AN && BI < BN) {
+ ConstantInt *ALow = cast<ConstantInt>(A->getOperand(2 * AI));
+ ConstantInt *BLow = cast<ConstantInt>(B->getOperand(2 * BI));
+
+ if (ALow->getValue().slt(BLow->getValue())) {
+ addRange(EndPoints, ALow, cast<ConstantInt>(A->getOperand(2 * AI + 1)));
+ ++AI;
+ } else {
+ addRange(EndPoints, BLow, cast<ConstantInt>(B->getOperand(2 * BI + 1)));
+ ++BI;
+ }
+ }
+ while (AI < AN) {
+ addRange(EndPoints, cast<ConstantInt>(A->getOperand(2 * AI)),
+ cast<ConstantInt>(A->getOperand(2 * AI + 1)));
+ ++AI;
+ }
+ while (BI < BN) {
+ addRange(EndPoints, cast<ConstantInt>(B->getOperand(2 * BI)),
+ cast<ConstantInt>(B->getOperand(2 * BI + 1)));
+ ++BI;
+ }
+
+ // If we have more than 2 ranges (4 endpoints) we have to try to merge
+ // the last and first ones.
+ unsigned Size = EndPoints.size();
+ if (Size > 4) {
+ ConstantInt *FB = cast<ConstantInt>(EndPoints[0]);
+ ConstantInt *FE = cast<ConstantInt>(EndPoints[1]);
+ if (tryMergeRange(EndPoints, FB, FE)) {
+ for (unsigned i = 0; i < Size - 2; ++i) {
+ EndPoints[i] = EndPoints[i + 2];
+ }
+ EndPoints.resize(Size - 2);
+ }
+ }
+
+ // If in the end we have a single range, it is possible that it is now the
+ // full range. Just drop the metadata in that case.
+ if (EndPoints.size() == 2) {
+ ConstantRange Range(cast<ConstantInt>(EndPoints[0])->getValue(),
+ cast<ConstantInt>(EndPoints[1])->getValue());
+ if (Range.isFullSet())
+ return NULL;
+ }
+
+ return MDNode::get(A->getContext(), EndPoints);
+}
+
//===----------------------------------------------------------------------===//
// NamedMDNode implementation.
//
diff --git a/lib/VMCore/Module.cpp b/lib/VMCore/Module.cpp
index 3c67191..5b5176b 100644
--- a/lib/VMCore/Module.cpp
+++ b/lib/VMCore/Module.cpp
@@ -65,20 +65,20 @@ Module::~Module() {
Module::Endianness Module::getEndianness() const {
StringRef temp = DataLayout;
Module::Endianness ret = AnyEndianness;
-
+
while (!temp.empty()) {
std::pair<StringRef, StringRef> P = getToken(temp, "-");
-
+
StringRef token = P.first;
temp = P.second;
-
+
if (token[0] == 'e') {
ret = LittleEndian;
} else if (token[0] == 'E') {
ret = BigEndian;
}
}
-
+
return ret;
}
@@ -86,13 +86,13 @@ Module::Endianness Module::getEndianness() const {
Module::PointerSize Module::getPointerSize() const {
StringRef temp = DataLayout;
Module::PointerSize ret = AnyPointerSize;
-
+
while (!temp.empty()) {
std::pair<StringRef, StringRef> TmpP = getToken(temp, "-");
temp = TmpP.second;
TmpP = getToken(TmpP.first, ":");
StringRef token = TmpP.second, signalToken = TmpP.first;
-
+
if (signalToken[0] == 'p') {
int size = 0;
getToken(token, ":").first.getAsInteger(10, size);
@@ -102,7 +102,7 @@ Module::PointerSize Module::getPointerSize() const {
ret = Pointer64;
}
}
-
+
return ret;
}
@@ -164,9 +164,9 @@ Constant *Module::getOrInsertFunction(StringRef Name,
// right type.
if (F->getType() != PointerType::getUnqual(Ty))
return ConstantExpr::getBitCast(F, PointerType::getUnqual(Ty));
-
+
// Otherwise, we just found the existing function or a prototype.
- return F;
+ return F;
}
Constant *Module::getOrInsertTargetIntrinsic(StringRef Name,
@@ -183,13 +183,12 @@ Constant *Module::getOrInsertTargetIntrinsic(StringRef Name,
}
// Otherwise, we just found the existing function or a prototype.
- return F;
+ return F;
}
Constant *Module::getOrInsertFunction(StringRef Name,
FunctionType *Ty) {
- AttrListPtr AttributeList = AttrListPtr::get((AttributeWithIndex *)0, 0);
- return getOrInsertFunction(Name, Ty, AttributeList);
+ return getOrInsertFunction(Name, Ty, AttrListPtr());
}
// getOrInsertFunction - Look up the specified function in the module symbol
@@ -229,9 +228,9 @@ Constant *Module::getOrInsertFunction(StringRef Name,
va_end(Args);
// Build the function type and chain to the other getOrInsertFunction...
- return getOrInsertFunction(Name,
+ return getOrInsertFunction(Name,
FunctionType::get(RetTy, ArgTys, false),
- AttrListPtr::get((AttributeWithIndex *)0, 0));
+ AttrListPtr());
}
// getFunction - Look up the specified function in the module symbol table.
@@ -254,7 +253,7 @@ Function *Module::getFunction(StringRef Name) const {
///
GlobalVariable *Module::getGlobalVariable(StringRef Name,
bool AllowLocal) const {
- if (GlobalVariable *Result =
+ if (GlobalVariable *Result =
dyn_cast_or_null<GlobalVariable>(getNamedValue(Name)))
if (AllowLocal || !Result->hasLocalLinkage())
return Result;
@@ -282,7 +281,7 @@ Constant *Module::getOrInsertGlobal(StringRef Name, Type *Ty) {
// right type.
if (GV->getType() != PointerType::getUnqual(Ty))
return ConstantExpr::getBitCast(GV, PointerType::getUnqual(Ty));
-
+
// Otherwise, we just found the existing function or a prototype.
return GV;
}
@@ -299,7 +298,7 @@ GlobalAlias *Module::getNamedAlias(StringRef Name) const {
}
/// getNamedMetadata - Return the first NamedMDNode in the module with the
-/// specified name. This method returns null if a NamedMDNode with the
+/// specified name. This method returns null if a NamedMDNode with the
/// specified name is not found.
NamedMDNode *Module::getNamedMetadata(const Twine &Name) const {
SmallString<256> NameData;
@@ -307,8 +306,8 @@ NamedMDNode *Module::getNamedMetadata(const Twine &Name) const {
return static_cast<StringMap<NamedMDNode*> *>(NamedMDSymTab)->lookup(NameRef);
}
-/// getOrInsertNamedMetadata - Return the first named MDNode in the module
-/// with the specified name. This method returns a new NamedMDNode if a
+/// getOrInsertNamedMetadata - Return the first named MDNode in the module
+/// with the specified name. This method returns a new NamedMDNode if a
/// NamedMDNode with the specified name is not found.
NamedMDNode *Module::getOrInsertNamedMetadata(StringRef Name) {
NamedMDNode *&NMD =
@@ -468,128 +467,3 @@ void Module::removeLibrary(StringRef Lib) {
return;
}
}
-
-//===----------------------------------------------------------------------===//
-// Type finding functionality.
-//===----------------------------------------------------------------------===//
-
-namespace {
- /// TypeFinder - Walk over a module, identifying all of the types that are
- /// used by the module.
- class TypeFinder {
- // To avoid walking constant expressions multiple times and other IR
- // objects, we keep several helper maps.
- DenseSet<const Value*> VisitedConstants;
- DenseSet<Type*> VisitedTypes;
-
- std::vector<StructType*> &StructTypes;
- public:
- TypeFinder(std::vector<StructType*> &structTypes)
- : StructTypes(structTypes) {}
-
- void run(const Module &M) {
- // Get types from global variables.
- for (Module::const_global_iterator I = M.global_begin(),
- E = M.global_end(); I != E; ++I) {
- incorporateType(I->getType());
- if (I->hasInitializer())
- incorporateValue(I->getInitializer());
- }
-
- // Get types from aliases.
- for (Module::const_alias_iterator I = M.alias_begin(),
- E = M.alias_end(); I != E; ++I) {
- incorporateType(I->getType());
- if (const Value *Aliasee = I->getAliasee())
- incorporateValue(Aliasee);
- }
-
- SmallVector<std::pair<unsigned, MDNode*>, 4> MDForInst;
-
- // Get types from functions.
- for (Module::const_iterator FI = M.begin(), E = M.end(); FI != E; ++FI) {
- incorporateType(FI->getType());
-
- for (Function::const_iterator BB = FI->begin(), E = FI->end();
- BB != E;++BB)
- for (BasicBlock::const_iterator II = BB->begin(),
- E = BB->end(); II != E; ++II) {
- const Instruction &I = *II;
- // Incorporate the type of the instruction and all its operands.
- incorporateType(I.getType());
- for (User::const_op_iterator OI = I.op_begin(), OE = I.op_end();
- OI != OE; ++OI)
- incorporateValue(*OI);
-
- // Incorporate types hiding in metadata.
- I.getAllMetadataOtherThanDebugLoc(MDForInst);
- for (unsigned i = 0, e = MDForInst.size(); i != e; ++i)
- incorporateMDNode(MDForInst[i].second);
- MDForInst.clear();
- }
- }
-
- for (Module::const_named_metadata_iterator I = M.named_metadata_begin(),
- E = M.named_metadata_end(); I != E; ++I) {
- const NamedMDNode *NMD = I;
- for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i)
- incorporateMDNode(NMD->getOperand(i));
- }
- }
-
- private:
- void incorporateType(Type *Ty) {
- // Check to see if we're already visited this type.
- if (!VisitedTypes.insert(Ty).second)
- return;
-
- // If this is a structure or opaque type, add a name for the type.
- if (StructType *STy = dyn_cast<StructType>(Ty))
- StructTypes.push_back(STy);
-
- // Recursively walk all contained types.
- for (Type::subtype_iterator I = Ty->subtype_begin(),
- E = Ty->subtype_end(); I != E; ++I)
- incorporateType(*I);
- }
-
- /// incorporateValue - This method is used to walk operand lists finding
- /// types hiding in constant expressions and other operands that won't be
- /// walked in other ways. GlobalValues, basic blocks, instructions, and
- /// inst operands are all explicitly enumerated.
- void incorporateValue(const Value *V) {
- if (const MDNode *M = dyn_cast<MDNode>(V))
- return incorporateMDNode(M);
- if (!isa<Constant>(V) || isa<GlobalValue>(V)) return;
-
- // Already visited?
- if (!VisitedConstants.insert(V).second)
- return;
-
- // Check this type.
- incorporateType(V->getType());
-
- // Look in operands for types.
- const User *U = cast<User>(V);
- for (Constant::const_op_iterator I = U->op_begin(),
- E = U->op_end(); I != E;++I)
- incorporateValue(*I);
- }
-
- void incorporateMDNode(const MDNode *V) {
-
- // Already visited?
- if (!VisitedConstants.insert(V).second)
- return;
-
- // Look in operands for types.
- for (unsigned i = 0, e = V->getNumOperands(); i != e; ++i)
- if (Value *Op = V->getOperand(i))
- incorporateValue(Op);
- }
- };
-} // end anonymous namespace
-
-void Module::findUsedStructTypes(std::vector<StructType*> &StructTypes) const {
- TypeFinder(StructTypes).run(*this);
-}
diff --git a/lib/VMCore/PassManager.cpp b/lib/VMCore/PassManager.cpp
index 28fbaa6..4530c04 100644
--- a/lib/VMCore/PassManager.cpp
+++ b/lib/VMCore/PassManager.cpp
@@ -478,8 +478,7 @@ PMTopLevelManager::PMTopLevelManager(PMDataManager *PMDM) {
/// Set pass P as the last user of the given analysis passes.
void
-PMTopLevelManager::setLastUser(const SmallVectorImpl<Pass *> &AnalysisPasses,
- Pass *P) {
+PMTopLevelManager::setLastUser(ArrayRef<Pass*> AnalysisPasses, Pass *P) {
unsigned PDepth = 0;
if (P->getResolver())
PDepth = P->getResolver()->getPMDataManager().getDepth();
@@ -594,6 +593,26 @@ void PMTopLevelManager::schedulePass(Pass *P) {
Pass *AnalysisPass = findAnalysisPass(*I);
if (!AnalysisPass) {
const PassInfo *PI = PassRegistry::getPassRegistry()->getPassInfo(*I);
+
+ if (PI == NULL) {
+ // Pass P is not in the global PassRegistry
+ dbgs() << "Pass '" << P->getPassName() << "' is not initialized." << "\n";
+ dbgs() << "Verify if there is a pass dependency cycle." << "\n";
+ dbgs() << "Required Passes:" << "\n";
+ for (AnalysisUsage::VectorType::const_iterator I2 = RequiredSet.begin(),
+ E = RequiredSet.end(); I2 != E && I2 != I; ++I2) {
+ Pass *AnalysisPass2 = findAnalysisPass(*I2);
+ if (AnalysisPass2) {
+ dbgs() << "\t" << AnalysisPass2->getPassName() << "\n";
+ }
+ else {
+ dbgs() << "\t" << "Error: Required pass not found! Possible causes:" << "\n";
+ dbgs() << "\t\t" << "- Pass misconfiguration (e.g.: missing macros)" << "\n";
+ dbgs() << "\t\t" << "- Corruption of the global PassRegistry" << "\n";
+ }
+ }
+ }
+
assert(PI && "Expected required passes to be initialized");
AnalysisPass = PI->createPass();
if (P->getPotentialPassManagerType () ==
diff --git a/lib/VMCore/Type.cpp b/lib/VMCore/Type.cpp
index c6f3558..5e9a00f 100644
--- a/lib/VMCore/Type.cpp
+++ b/lib/VMCore/Type.cpp
@@ -464,19 +464,26 @@ void StructType::setBody(ArrayRef<Type*> Elements, bool isPacked) {
void StructType::setName(StringRef Name) {
if (Name == getName()) return;
- // If this struct already had a name, remove its symbol table entry.
- if (SymbolTableEntry) {
- getContext().pImpl->NamedStructTypes.erase(getName());
- SymbolTableEntry = 0;
- }
-
+ StringMap<StructType *> &SymbolTable = getContext().pImpl->NamedStructTypes;
+ typedef StringMap<StructType *>::MapEntryTy EntryTy;
+
+ // If this struct already had a name, remove its symbol table entry. Don't
+ // delete the data yet because it may be part of the new name.
+ if (SymbolTableEntry)
+ SymbolTable.remove((EntryTy *)SymbolTableEntry);
+
// If this is just removing the name, we're done.
- if (Name.empty())
+ if (Name.empty()) {
+ if (SymbolTableEntry) {
+ // Delete the old string data.
+ ((EntryTy *)SymbolTableEntry)->Destroy(SymbolTable.getAllocator());
+ SymbolTableEntry = 0;
+ }
return;
+ }
// Look up the entry for the name.
- StringMapEntry<StructType*> *Entry =
- &getContext().pImpl->NamedStructTypes.GetOrCreateValue(Name);
+ EntryTy *Entry = &getContext().pImpl->NamedStructTypes.GetOrCreateValue(Name);
// While we have a name collision, try a random rename.
if (Entry->getValue()) {
@@ -497,7 +504,10 @@ void StructType::setName(StringRef Name) {
// Okay, we found an entry that isn't used. It's us!
Entry->setValue(this);
-
+
+ // Delete the old string data.
+ if (SymbolTableEntry)
+ ((EntryTy *)SymbolTableEntry)->Destroy(SymbolTable.getAllocator());
SymbolTableEntry = Entry;
}
diff --git a/lib/VMCore/TypeFinder.cpp b/lib/VMCore/TypeFinder.cpp
new file mode 100644
index 0000000..4de649f
--- /dev/null
+++ b/lib/VMCore/TypeFinder.cpp
@@ -0,0 +1,148 @@
+//===-- TypeFinder.cpp - Implement the TypeFinder class -------------------===//
+//
+// 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 TypeFinder class for the VMCore library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/TypeFinder.h"
+#include "llvm/BasicBlock.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Function.h"
+#include "llvm/Metadata.h"
+#include "llvm/Module.h"
+#include "llvm/ADT/SmallVector.h"
+using namespace llvm;
+
+void TypeFinder::run(const Module &M, bool onlyNamed) {
+ OnlyNamed = onlyNamed;
+
+ // Get types from global variables.
+ for (Module::const_global_iterator I = M.global_begin(),
+ E = M.global_end(); I != E; ++I) {
+ incorporateType(I->getType());
+ if (I->hasInitializer())
+ incorporateValue(I->getInitializer());
+ }
+
+ // Get types from aliases.
+ for (Module::const_alias_iterator I = M.alias_begin(),
+ E = M.alias_end(); I != E; ++I) {
+ incorporateType(I->getType());
+ if (const Value *Aliasee = I->getAliasee())
+ incorporateValue(Aliasee);
+ }
+
+ // Get types from functions.
+ SmallVector<std::pair<unsigned, MDNode*>, 4> MDForInst;
+ for (Module::const_iterator FI = M.begin(), E = M.end(); FI != E; ++FI) {
+ incorporateType(FI->getType());
+
+ // First incorporate the arguments.
+ for (Function::const_arg_iterator AI = FI->arg_begin(),
+ AE = FI->arg_end(); AI != AE; ++AI)
+ incorporateValue(AI);
+
+ for (Function::const_iterator BB = FI->begin(), E = FI->end();
+ BB != E;++BB)
+ for (BasicBlock::const_iterator II = BB->begin(),
+ E = BB->end(); II != E; ++II) {
+ const Instruction &I = *II;
+
+ // Incorporate the type of the instruction.
+ incorporateType(I.getType());
+
+ // Incorporate non-instruction operand types. (We are incorporating all
+ // instructions with this loop.)
+ for (User::const_op_iterator OI = I.op_begin(), OE = I.op_end();
+ OI != OE; ++OI)
+ if (!isa<Instruction>(OI))
+ incorporateValue(*OI);
+
+ // Incorporate types hiding in metadata.
+ I.getAllMetadataOtherThanDebugLoc(MDForInst);
+ for (unsigned i = 0, e = MDForInst.size(); i != e; ++i)
+ incorporateMDNode(MDForInst[i].second);
+
+ MDForInst.clear();
+ }
+ }
+
+ for (Module::const_named_metadata_iterator I = M.named_metadata_begin(),
+ E = M.named_metadata_end(); I != E; ++I) {
+ const NamedMDNode *NMD = I;
+ for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i)
+ incorporateMDNode(NMD->getOperand(i));
+ }
+}
+
+void TypeFinder::clear() {
+ VisitedConstants.clear();
+ VisitedTypes.clear();
+ StructTypes.clear();
+}
+
+/// incorporateType - This method adds the type to the list of used structures
+/// if it's not in there already.
+void TypeFinder::incorporateType(Type *Ty) {
+ // Check to see if we're already visited this type.
+ if (!VisitedTypes.insert(Ty).second)
+ return;
+
+ // If this is a structure or opaque type, add a name for the type.
+ if (StructType *STy = dyn_cast<StructType>(Ty))
+ if (!OnlyNamed || STy->hasName())
+ StructTypes.push_back(STy);
+
+ // Recursively walk all contained types.
+ for (Type::subtype_iterator I = Ty->subtype_begin(),
+ E = Ty->subtype_end(); I != E; ++I)
+ incorporateType(*I);
+}
+
+/// incorporateValue - This method is used to walk operand lists finding types
+/// hiding in constant expressions and other operands that won't be walked in
+/// other ways. GlobalValues, basic blocks, instructions, and inst operands are
+/// all explicitly enumerated.
+void TypeFinder::incorporateValue(const Value *V) {
+ if (const MDNode *M = dyn_cast<MDNode>(V))
+ return incorporateMDNode(M);
+
+ if (!isa<Constant>(V) || isa<GlobalValue>(V)) return;
+
+ // Already visited?
+ if (!VisitedConstants.insert(V).second)
+ return;
+
+ // Check this type.
+ incorporateType(V->getType());
+
+ // If this is an instruction, we incorporate it separately.
+ if (isa<Instruction>(V))
+ return;
+
+ // Look in operands for types.
+ const User *U = cast<User>(V);
+ for (Constant::const_op_iterator I = U->op_begin(),
+ E = U->op_end(); I != E;++I)
+ incorporateValue(*I);
+}
+
+/// incorporateMDNode - This method is used to walk the operands of an MDNode to
+/// find types hiding within.
+void TypeFinder::incorporateMDNode(const MDNode *V) {
+ // Already visited?
+ if (!VisitedConstants.insert(V).second)
+ return;
+
+ // Look in operands for types.
+ for (unsigned i = 0, e = V->getNumOperands(); i != e; ++i)
+ if (Value *Op = V->getOperand(i))
+ incorporateValue(Op);
+}
diff --git a/lib/VMCore/Value.cpp b/lib/VMCore/Value.cpp
index 4006b2c..d871108 100644
--- a/lib/VMCore/Value.cpp
+++ b/lib/VMCore/Value.cpp
@@ -686,6 +686,9 @@ void ValueHandleBase::ValueIsRAUWd(Value *Old, Value *New) {
#endif
}
-/// ~CallbackVH. Empty, but defined here to avoid emitting the vtable
-/// more than once.
-CallbackVH::~CallbackVH() {}
+// Default implementation for CallbackVH.
+void CallbackVH::allUsesReplacedWith(Value *) {}
+
+void CallbackVH::deleted() {
+ setValPtr(NULL);
+}
diff --git a/lib/VMCore/ValueTypes.cpp b/lib/VMCore/ValueTypes.cpp
index 9a8e185..d1ca953 100644
--- a/lib/VMCore/ValueTypes.cpp
+++ b/lib/VMCore/ValueTypes.cpp
@@ -71,6 +71,10 @@ bool EVT::isExtended512BitVector() const {
return isExtendedVector() && getSizeInBits() == 512;
}
+bool EVT::isExtended1024BitVector() const {
+ return isExtendedVector() && getSizeInBits() == 1024;
+}
+
EVT EVT::getExtendedVectorElementType() const {
assert(isExtended() && "Type is not extended!");
return EVT::getEVT(cast<VectorType>(LLVMTy)->getElementType());
@@ -128,10 +132,12 @@ std::string EVT::getEVTString() const {
case MVT::v2i32: return "v2i32";
case MVT::v4i32: return "v4i32";
case MVT::v8i32: return "v8i32";
+ case MVT::v16i32: return "v16i32";
case MVT::v1i64: return "v1i64";
case MVT::v2i64: return "v2i64";
case MVT::v4i64: return "v4i64";
case MVT::v8i64: return "v8i64";
+ case MVT::v16i64: return "v16i64";
case MVT::v2f32: return "v2f32";
case MVT::v2f16: return "v2f16";
case MVT::v4f32: return "v4f32";
@@ -177,10 +183,12 @@ Type *EVT::getTypeForEVT(LLVMContext &Context) const {
case MVT::v2i32: return VectorType::get(Type::getInt32Ty(Context), 2);
case MVT::v4i32: return VectorType::get(Type::getInt32Ty(Context), 4);
case MVT::v8i32: return VectorType::get(Type::getInt32Ty(Context), 8);
+ case MVT::v16i32: return VectorType::get(Type::getInt32Ty(Context), 16);
case MVT::v1i64: return VectorType::get(Type::getInt64Ty(Context), 1);
case MVT::v2i64: return VectorType::get(Type::getInt64Ty(Context), 2);
case MVT::v4i64: return VectorType::get(Type::getInt64Ty(Context), 4);
case MVT::v8i64: return VectorType::get(Type::getInt64Ty(Context), 8);
+ case MVT::v16i64: return VectorType::get(Type::getInt64Ty(Context), 16);
case MVT::v2f16: return VectorType::get(Type::getHalfTy(Context), 2);
case MVT::v2f32: return VectorType::get(Type::getFloatTy(Context), 2);
case MVT::v4f32: return VectorType::get(Type::getFloatTy(Context), 4);
diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp
index 47baef3..6851246 100644
--- a/lib/VMCore/Verifier.cpp
+++ b/lib/VMCore/Verifier.cpp
@@ -68,6 +68,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/ConstantRange.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
@@ -293,8 +294,9 @@ namespace {
void VerifyCallSite(CallSite CS);
bool PerformTypeCheck(Intrinsic::ID ID, Function *F, Type *Ty,
int VT, unsigned ArgNo, std::string &Suffix);
- void VerifyIntrinsicPrototype(Intrinsic::ID ID, Function *F,
- unsigned RetNum, unsigned ParamNum, ...);
+ bool VerifyIntrinsicType(Type *Ty,
+ ArrayRef<Intrinsic::IITDescriptor> &Infos,
+ SmallVectorImpl<Type*> &ArgTys);
void VerifyParameterAttrs(Attributes Attrs, Type *Ty,
bool isReturnValue, const Value *V);
void VerifyFunctionAttrs(FunctionType *FT, const AttrListPtr &Attrs,
@@ -804,14 +806,29 @@ void Verifier::visitSwitchInst(SwitchInst &SI) {
// Check to make sure that all of the constants in the switch instruction
// have the same type as the switched-on value.
Type *SwitchTy = SI.getCondition()->getType();
- SmallPtrSet<ConstantInt*, 32> Constants;
+ IntegerType *IntTy = cast<IntegerType>(SwitchTy);
+ IntegersSubsetToBB Mapping;
+ std::map<IntegersSubset::Range, unsigned> RangeSetMap;
for (SwitchInst::CaseIt i = SI.case_begin(), e = SI.case_end(); i != e; ++i) {
- Assert1(i.getCaseValue()->getType() == SwitchTy,
- "Switch constants must all be same type as switch value!", &SI);
- Assert2(Constants.insert(i.getCaseValue()),
- "Duplicate integer as switch case", &SI, i.getCaseValue());
+ IntegersSubset CaseRanges = i.getCaseValueEx();
+ for (unsigned ri = 0, rie = CaseRanges.getNumItems(); ri < rie; ++ri) {
+ IntegersSubset::Range r = CaseRanges.getItem(ri);
+ Assert1(((const APInt&)r.getLow()).getBitWidth() == IntTy->getBitWidth(),
+ "Switch constants must all be same type as switch value!", &SI);
+ Assert1(((const APInt&)r.getHigh()).getBitWidth() == IntTy->getBitWidth(),
+ "Switch constants must all be same type as switch value!", &SI);
+ Mapping.add(r);
+ RangeSetMap[r] = i.getCaseIndex();
+ }
}
-
+
+ IntegersSubsetToBB::RangeIterator errItem;
+ if (!Mapping.verify(errItem)) {
+ unsigned CaseIndex = RangeSetMap[errItem->first];
+ SwitchInst::CaseIt i(&SI, CaseIndex);
+ Assert2(false, "Duplicate integer as switch case", &SI, i.getCaseValueEx());
+ }
+
visitTerminatorInst(SI);
}
@@ -1346,6 +1363,10 @@ void Verifier::visitGetElementPtrInst(GetElementPtrInst &GEP) {
visitInstruction(GEP);
}
+static bool isContiguous(const ConstantRange &A, const ConstantRange &B) {
+ return A.getUpper() == B.getLower() || A.getLower() == B.getUpper();
+}
+
void Verifier::visitLoadInst(LoadInst &LI) {
PointerType *PTy = dyn_cast<PointerType>(LI.getOperand(0)->getType());
Assert1(PTy, "Load operand must be a pointer.", &LI);
@@ -1367,6 +1388,8 @@ void Verifier::visitLoadInst(LoadInst &LI) {
Assert1(NumOperands % 2 == 0, "Unfinished range!", Range);
unsigned NumRanges = NumOperands / 2;
Assert1(NumRanges >= 1, "It should have at least one range!", Range);
+
+ ConstantRange LastRange(1); // Dummy initial value
for (unsigned i = 0; i < NumRanges; ++i) {
ConstantInt *Low = dyn_cast<ConstantInt>(Range->getOperand(2*i));
Assert1(Low, "The lower limit must be an integer!", Low);
@@ -1375,9 +1398,35 @@ void Verifier::visitLoadInst(LoadInst &LI) {
Assert1(High->getType() == Low->getType() &&
High->getType() == ElTy, "Range types must match load type!",
&LI);
- Assert1(High->getValue() != Low->getValue(), "Range must not be empty!",
+
+ APInt HighV = High->getValue();
+ APInt LowV = Low->getValue();
+ ConstantRange CurRange(LowV, HighV);
+ Assert1(!CurRange.isEmptySet() && !CurRange.isFullSet(),
+ "Range must not be empty!", Range);
+ if (i != 0) {
+ Assert1(CurRange.intersectWith(LastRange).isEmptySet(),
+ "Intervals are overlapping", Range);
+ Assert1(LowV.sgt(LastRange.getLower()), "Intervals are not in order",
+ Range);
+ Assert1(!isContiguous(CurRange, LastRange), "Intervals are contiguous",
+ Range);
+ }
+ LastRange = ConstantRange(LowV, HighV);
+ }
+ if (NumRanges > 2) {
+ APInt FirstLow =
+ dyn_cast<ConstantInt>(Range->getOperand(0))->getValue();
+ APInt FirstHigh =
+ dyn_cast<ConstantInt>(Range->getOperand(1))->getValue();
+ ConstantRange FirstRange(FirstLow, FirstHigh);
+ Assert1(FirstRange.intersectWith(LastRange).isEmptySet(),
+ "Intervals are overlapping", Range);
+ Assert1(!isContiguous(FirstRange, LastRange), "Intervals are contiguous",
Range);
}
+
+
}
visitInstruction(LI);
@@ -1487,7 +1536,7 @@ void Verifier::visitLandingPadInst(LandingPadInst &LPI) {
// landing pad block may be branched to only by the unwind edge of an invoke.
for (pred_iterator I = pred_begin(BB), E = pred_end(BB); I != E; ++I) {
const InvokeInst *II = dyn_cast<InvokeInst>((*I)->getTerminator());
- Assert1(II && II->getUnwindDest() == BB,
+ Assert1(II && II->getUnwindDest() == BB && II->getNormalDest() != BB,
"Block containing LandingPadInst must be jumped to "
"only by the unwind edge of an invoke.", &LPI);
}
@@ -1526,53 +1575,9 @@ void Verifier::visitLandingPadInst(LandingPadInst &LPI) {
void Verifier::verifyDominatesUse(Instruction &I, unsigned i) {
Instruction *Op = cast<Instruction>(I.getOperand(i));
- BasicBlock *BB = I.getParent();
- BasicBlock *OpBlock = Op->getParent();
- PHINode *PN = dyn_cast<PHINode>(&I);
-
- // DT can handle non phi instructions for us.
- if (!PN) {
- // Definition must dominate use unless use is unreachable!
- Assert2(InstsInThisBlock.count(Op) || !DT->isReachableFromEntry(BB) ||
- DT->dominates(Op, &I),
- "Instruction does not dominate all uses!", Op, &I);
- return;
- }
- // Check that a definition dominates all of its uses.
- if (InvokeInst *II = dyn_cast<InvokeInst>(Op)) {
- // Invoke results are only usable in the normal destination, not in the
- // exceptional destination.
- BasicBlock *NormalDest = II->getNormalDest();
-
-
- // PHI nodes differ from other nodes because they actually "use" the
- // value in the predecessor basic blocks they correspond to.
- BasicBlock *UseBlock = BB;
- unsigned j = PHINode::getIncomingValueNumForOperand(i);
- UseBlock = PN->getIncomingBlock(j);
- Assert2(UseBlock, "Invoke operand is PHI node with bad incoming-BB",
- Op, &I);
-
- if (UseBlock == OpBlock) {
- // Special case of a phi node in the normal destination or the unwind
- // destination.
- Assert2(BB == NormalDest || !DT->isReachableFromEntry(UseBlock),
- "Invoke result not available in the unwind destination!",
- Op, &I);
- } else {
- Assert2(DT->dominates(II, UseBlock) ||
- !DT->isReachableFromEntry(UseBlock),
- "Invoke result does not dominate all uses!", Op, &I);
- }
- }
-
- // PHI nodes are more difficult than other nodes because they actually
- // "use" the value in the predecessor basic blocks they correspond to.
- unsigned j = PHINode::getIncomingValueNumForOperand(i);
- BasicBlock *PredBB = PN->getIncomingBlock(j);
- Assert2(PredBB && (DT->dominates(OpBlock, PredBB) ||
- !DT->isReachableFromEntry(PredBB)),
+ const Use &U = I.getOperandUse(i);
+ Assert2(InstsInThisBlock.count(Op) || DT->dominates(Op, U),
"Instruction does not dominate all uses!", Op, &I);
}
@@ -1631,8 +1636,11 @@ void Verifier::visitInstruction(Instruction &I) {
if (Function *F = dyn_cast<Function>(I.getOperand(i))) {
// Check to make sure that the "address of" an intrinsic function is never
// taken.
- Assert1(!F->isIntrinsic() || (i + 1 == e && isa<CallInst>(I)),
+ Assert1(!F->isIntrinsic() || i == (isa<CallInst>(I) ? e-1 : 0),
"Cannot take the address of an intrinsic!", &I);
+ Assert1(!F->isIntrinsic() || isa<CallInst>(I) ||
+ F->getIntrinsicID() == Intrinsic::donothing,
+ "Cannot invoke an intrinsinc other than donothing", &I);
Assert1(F->getParent() == Mod, "Referencing function in another module!",
&I);
} else if (BasicBlock *OpBB = dyn_cast<BasicBlock>(I.getOperand(i))) {
@@ -1673,10 +1681,85 @@ void Verifier::visitInstruction(Instruction &I) {
InstsInThisBlock.insert(&I);
}
-// Flags used by TableGen to mark intrinsic parameters with the
-// LLVMExtendedElementVectorType and LLVMTruncatedElementVectorType classes.
-static const unsigned ExtendedElementVectorType = 0x40000000;
-static const unsigned TruncatedElementVectorType = 0x20000000;
+/// VerifyIntrinsicType - Verify that the specified type (which comes from an
+/// intrinsic argument or return value) matches the type constraints specified
+/// by the .td file (e.g. an "any integer" argument really is an integer).
+///
+/// This return true on error but does not print a message.
+bool Verifier::VerifyIntrinsicType(Type *Ty,
+ ArrayRef<Intrinsic::IITDescriptor> &Infos,
+ SmallVectorImpl<Type*> &ArgTys) {
+ using namespace Intrinsic;
+
+ // If we ran out of descriptors, there are too many arguments.
+ if (Infos.empty()) return true;
+ IITDescriptor D = Infos.front();
+ Infos = Infos.slice(1);
+
+ switch (D.Kind) {
+ case IITDescriptor::Void: return !Ty->isVoidTy();
+ case IITDescriptor::MMX: return !Ty->isX86_MMXTy();
+ case IITDescriptor::Metadata: return !Ty->isMetadataTy();
+ case IITDescriptor::Float: return !Ty->isFloatTy();
+ case IITDescriptor::Double: return !Ty->isDoubleTy();
+ case IITDescriptor::Integer: return !Ty->isIntegerTy(D.Integer_Width);
+ case IITDescriptor::Vector: {
+ VectorType *VT = dyn_cast<VectorType>(Ty);
+ return VT == 0 || VT->getNumElements() != D.Vector_Width ||
+ VerifyIntrinsicType(VT->getElementType(), Infos, ArgTys);
+ }
+ case IITDescriptor::Pointer: {
+ PointerType *PT = dyn_cast<PointerType>(Ty);
+ return PT == 0 || PT->getAddressSpace() != D.Pointer_AddressSpace ||
+ VerifyIntrinsicType(PT->getElementType(), Infos, ArgTys);
+ }
+
+ case IITDescriptor::Struct: {
+ StructType *ST = dyn_cast<StructType>(Ty);
+ if (ST == 0 || ST->getNumElements() != D.Struct_NumElements)
+ return true;
+
+ for (unsigned i = 0, e = D.Struct_NumElements; i != e; ++i)
+ if (VerifyIntrinsicType(ST->getElementType(i), Infos, ArgTys))
+ return true;
+ return false;
+ }
+
+ case IITDescriptor::Argument:
+ // Two cases here - If this is the second occurrence of an argument, verify
+ // that the later instance matches the previous instance.
+ if (D.getArgumentNumber() < ArgTys.size())
+ return Ty != ArgTys[D.getArgumentNumber()];
+
+ // Otherwise, if this is the first instance of an argument, record it and
+ // verify the "Any" kind.
+ assert(D.getArgumentNumber() == ArgTys.size() && "Table consistency error");
+ ArgTys.push_back(Ty);
+
+ switch (D.getArgumentKind()) {
+ case IITDescriptor::AK_AnyInteger: return !Ty->isIntOrIntVectorTy();
+ case IITDescriptor::AK_AnyFloat: return !Ty->isFPOrFPVectorTy();
+ case IITDescriptor::AK_AnyVector: return !isa<VectorType>(Ty);
+ case IITDescriptor::AK_AnyPointer: return !isa<PointerType>(Ty);
+ }
+ llvm_unreachable("all argument kinds not covered");
+
+ case IITDescriptor::ExtendVecArgument:
+ // This may only be used when referring to a previous vector argument.
+ return D.getArgumentNumber() >= ArgTys.size() ||
+ !isa<VectorType>(ArgTys[D.getArgumentNumber()]) ||
+ VectorType::getExtendedElementVectorType(
+ cast<VectorType>(ArgTys[D.getArgumentNumber()])) != Ty;
+
+ case IITDescriptor::TruncVecArgument:
+ // This may only be used when referring to a previous vector argument.
+ return D.getArgumentNumber() >= ArgTys.size() ||
+ !isa<VectorType>(ArgTys[D.getArgumentNumber()]) ||
+ VectorType::getTruncatedElementVectorType(
+ cast<VectorType>(ArgTys[D.getArgumentNumber()])) != Ty;
+ }
+ llvm_unreachable("unhandled");
+}
/// visitIntrinsicFunction - Allow intrinsics to be verified in different ways.
///
@@ -1685,10 +1768,30 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) {
Assert1(IF->isDeclaration(), "Intrinsic functions should never be defined!",
IF);
-#define GET_INTRINSIC_VERIFIER
-#include "llvm/Intrinsics.gen"
-#undef GET_INTRINSIC_VERIFIER
-
+ // Verify that the intrinsic prototype lines up with what the .td files
+ // describe.
+ FunctionType *IFTy = IF->getFunctionType();
+ Assert1(!IFTy->isVarArg(), "Intrinsic prototypes are not varargs", IF);
+
+ SmallVector<Intrinsic::IITDescriptor, 8> Table;
+ getIntrinsicInfoTableEntries(ID, Table);
+ ArrayRef<Intrinsic::IITDescriptor> TableRef = Table;
+
+ SmallVector<Type *, 4> ArgTys;
+ Assert1(!VerifyIntrinsicType(IFTy->getReturnType(), TableRef, ArgTys),
+ "Intrinsic has incorrect return type!", IF);
+ for (unsigned i = 0, e = IFTy->getNumParams(); i != e; ++i)
+ Assert1(!VerifyIntrinsicType(IFTy->getParamType(i), TableRef, ArgTys),
+ "Intrinsic has incorrect argument type!", IF);
+ Assert1(TableRef.empty(), "Intrinsic has too few arguments!", IF);
+
+ // Now that we have the intrinsic ID and the actual argument types (and we
+ // know they are legal for the intrinsic!) get the intrinsic name through the
+ // usual means. This allows us to verify the mangling of argument types into
+ // the name.
+ Assert1(Intrinsic::getName(ID, ArgTys) == IF->getName(),
+ "Intrinsic name not mangled correctly for type arguments!", IF);
+
// If the intrinsic takes MDNode arguments, verify that they are either global
// or are local to *this* function.
for (unsigned i = 0, e = CI.getNumArgOperands(); i != e; ++i)
@@ -1772,261 +1875,6 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) {
}
}
-/// Produce a string to identify an intrinsic parameter or return value.
-/// The ArgNo value numbers the return values from 0 to NumRets-1 and the
-/// parameters beginning with NumRets.
-///
-static std::string IntrinsicParam(unsigned ArgNo, unsigned NumRets) {
- 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, Type *Ty,
- int VT, unsigned ArgNo, std::string &Suffix) {
- FunctionType *FTy = F->getFunctionType();
-
- unsigned NumElts = 0;
- Type *EltTy = Ty;
- VectorType *VTy = dyn_cast<VectorType>(Ty);
- if (VTy) {
- EltTy = VTy->getElementType();
- NumElts = VTy->getNumElements();
- }
-
- Type *RetTy = FTy->getReturnType();
- StructType *ST = dyn_cast<StructType>(RetTy);
- unsigned NumRetVals;
- if (RetTy->isVoidTy())
- NumRetVals = 0;
- else if (ST)
- NumRetVals = ST->getNumElements();
- else
- NumRetVals = 1;
-
- if (VT < 0) {
- int Match = ~VT;
-
- // Check flags that indicate a type that is an integral vector type with
- // elements that are larger or smaller than the elements of the matched
- // type.
- if ((Match & (ExtendedElementVectorType |
- TruncatedElementVectorType)) != 0) {
- IntegerType *IEltTy = dyn_cast<IntegerType>(EltTy);
- if (!VTy || !IEltTy) {
- CheckFailed(IntrinsicParam(ArgNo, NumRetVals) + " is not "
- "an integral vector type.", F);
- return false;
- }
- // Adjust the current Ty (in the opposite direction) rather than
- // the type being matched against.
- if ((Match & ExtendedElementVectorType) != 0) {
- if ((IEltTy->getBitWidth() & 1) != 0) {
- CheckFailed(IntrinsicParam(ArgNo, NumRetVals) + " vector "
- "element bit-width is odd.", F);
- return false;
- }
- Ty = VectorType::getTruncatedElementVectorType(VTy);
- } else
- Ty = VectorType::getExtendedElementVectorType(VTy);
- Match &= ~(ExtendedElementVectorType | TruncatedElementVectorType);
- }
-
- if (Match <= static_cast<int>(NumRetVals - 1)) {
- if (ST)
- RetTy = ST->getElementType(Match);
-
- if (Ty != RetTy) {
- CheckFailed(IntrinsicParam(ArgNo, NumRetVals) + " does not "
- "match return type.", F);
- return false;
- }
- } else {
- 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, NumRetVals) + " is not "
- "an integer type.", F);
- return false;
- }
-
- unsigned GotBits = cast<IntegerType>(EltTy)->getBitWidth();
- Suffix += ".";
-
- if (EltTy != Ty)
- Suffix += "v" + utostr(NumElts);
-
- Suffix += "i" + utostr(GotBits);
-
- // Check some constraints on various intrinsics.
- switch (ID) {
- default: break; // Not everything needs to be checked.
- case Intrinsic::bswap:
- if (GotBits < 16 || GotBits % 16 != 0) {
- CheckFailed("Intrinsic requires even byte width argument", F);
- return false;
- }
- break;
- }
- } else if (VT == MVT::fAny) {
- if (!EltTy->isFloatingPointTy()) {
- CheckFailed(IntrinsicParam(ArgNo, NumRetVals) + " is not "
- "a floating-point type.", F);
- return false;
- }
-
- Suffix += ".";
-
- if (EltTy != Ty)
- Suffix += "v" + utostr(NumElts);
-
- Suffix += EVT::getEVT(EltTy).getEVTString();
- } else if (VT == MVT::vAny) {
- if (!VTy) {
- 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, NumRetVals) + " is not a "
- "pointer and a pointer is required.", F);
- return false;
- }
- } else if (VT == MVT::iPTRAny) {
- // Outside of TableGen, we don't distinguish iPTRAny (to any address space)
- // and iPTR. In the verifier, we can not distinguish which case we have so
- // allow either case to be legal.
- if (PointerType* PTyp = dyn_cast<PointerType>(Ty)) {
- EVT PointeeVT = EVT::getEVT(PTyp->getElementType(), true);
- if (PointeeVT == MVT::Other) {
- CheckFailed("Intrinsic has pointer to complex type.");
- return false;
- }
- Suffix += ".p" + utostr(PTyp->getAddressSpace()) +
- PointeeVT.getEVTString();
- } else {
- CheckFailed(IntrinsicParam(ArgNo, NumRetVals) + " is not a "
- "pointer and a pointer is required.", F);
- return false;
- }
- } else if (EVT((MVT::SimpleValueType)VT).isVector()) {
- EVT VVT = EVT((MVT::SimpleValueType)VT);
-
- // If this is a vector argument, verify the number and type of elements.
- if (VVT.getVectorElementType() != EVT::getEVT(EltTy)) {
- CheckFailed("Intrinsic prototype has incorrect vector element type!", F);
- return false;
- }
-
- if (VVT.getVectorNumElements() != NumElts) {
- CheckFailed("Intrinsic prototype has incorrect number of "
- "vector elements!", F);
- return false;
- }
- } else if (EVT((MVT::SimpleValueType)VT).getTypeForEVT(Ty->getContext()) !=
- EltTy) {
- CheckFailed(IntrinsicParam(ArgNo, NumRetVals) + " is wrong!", F);
- return false;
- } else if (EltTy != Ty) {
- CheckFailed(IntrinsicParam(ArgNo, NumRetVals) + " is a vector "
- "and a scalar is required.", F);
- return false;
- }
-
- return true;
-}
-
-/// VerifyIntrinsicPrototype - TableGen emits calls to this function into
-/// Intrinsics.gen. This implements a little state machine that verifies the
-/// prototype of intrinsics.
-void Verifier::VerifyIntrinsicPrototype(Intrinsic::ID ID, Function *F,
- unsigned NumRetVals,
- unsigned NumParams, ...) {
- va_list VA;
- va_start(VA, NumParams);
- FunctionType *FTy = F->getFunctionType();
-
- // For overloaded intrinsics, the Suffix of the function name must match the
- // types of the arguments. This variable keeps track of the expected
- // suffix, to be checked at the end.
- std::string Suffix;
-
- if (FTy->getNumParams() + FTy->isVarArg() != NumParams) {
- CheckFailed("Intrinsic prototype has incorrect number of arguments!", F);
- return;
- }
-
- Type *Ty = FTy->getReturnType();
- 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() != NumRetVals) {
- CheckFailed("Intrinsic prototype has incorrect number of return types!", F);
- return;
- }
-
- 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 != NumParams; ++ArgNo) {
- int VT = va_arg(VA, int); // An MVT::SimpleValueType when non-negative.
-
- if (VT == MVT::isVoid && ArgNo > 0) {
- if (!FTy->isVarArg())
- CheckFailed("Intrinsic prototype has no '...'!", F);
- break;
- }
-
- if (!PerformTypeCheck(ID, F, FTy->getParamType(ArgNo), VT,
- ArgNo + NumRetVals, Suffix))
- break;
- }
-
- va_end(VA);
-
- // For intrinsics without pointer arguments, if we computed a Suffix then the
- // intrinsic is overloaded and we need to make sure that the name of the
- // function is correct. We add the suffix to the name of the intrinsic and
- // compare against the given function name. If they are not the same, the
- // function name is invalid. This ensures that overloading of intrinsics
- // uses a sane and consistent naming convention. Note that intrinsics with
- // pointer argument may or may not be overloaded so we will check assuming it
- // has a suffix and not.
- if (!Suffix.empty()) {
- std::string Name(Intrinsic::getName(ID));
- if (Name + Suffix != F->getName()) {
- CheckFailed("Overloaded intrinsic has incorrect suffix: '" +
- F->getName().substr(Name.length()) + "'. It should be '" +
- Suffix + "'", F);
- }
- }
-
- // Check parameter attributes.
- Assert1(F->getAttributes() == Intrinsic::getAttributes(ID),
- "Intrinsic has wrong parameter attributes!", F);
-}
-
-
//===----------------------------------------------------------------------===//
// Implement the public interfaces to this file...
//===----------------------------------------------------------------------===//
OpenPOWER on IntegriCloud