aboutsummaryrefslogtreecommitdiffstats
path: root/lib/VMCore
diff options
context:
space:
mode:
authorNowar Gu <nowar100@gmail.com>2011-06-17 14:29:24 +0800
committerNowar Gu <nowar100@gmail.com>2011-06-20 15:49:07 +0800
commit907af0f20f58f2ea26da7ea64e1f094cd6880db7 (patch)
tree02007757de416c561df174d582205cebfa582801 /lib/VMCore
parent1d4f9a57447faa0142a1d0301e5ce550cfe60c4f (diff)
parentec324e5ae44025c6bdb930b78198f30f807e355b (diff)
downloadexternal_llvm-907af0f20f58f2ea26da7ea64e1f094cd6880db7.zip
external_llvm-907af0f20f58f2ea26da7ea64e1f094cd6880db7.tar.gz
external_llvm-907af0f20f58f2ea26da7ea64e1f094cd6880db7.tar.bz2
Merge upstream to r133240 at Fri. 17th Jun 2011.
Conflicts: lib/CodeGen/AsmPrinter/AsmPrinter.cpp lib/Target/ARM/ARMCodeEmitter.cpp
Diffstat (limited to 'lib/VMCore')
-rw-r--r--lib/VMCore/AsmWriter.cpp80
-rw-r--r--lib/VMCore/Attributes.cpp4
-rw-r--r--lib/VMCore/AutoUpgrade.cpp137
-rw-r--r--lib/VMCore/ConstantFold.cpp3
-rw-r--r--lib/VMCore/Constants.cpp17
-rw-r--r--lib/VMCore/ConstantsContext.h12
-rw-r--r--lib/VMCore/Core.cpp5
-rw-r--r--lib/VMCore/DebugInfoProbe.cpp56
-rw-r--r--lib/VMCore/DebugLoc.cpp2
-rw-r--r--lib/VMCore/Function.cpp43
-rw-r--r--lib/VMCore/IRBuilder.cpp33
-rw-r--r--lib/VMCore/InlineAsm.cpp5
-rw-r--r--lib/VMCore/Instructions.cpp170
-rw-r--r--lib/VMCore/LLVMContextImpl.h2
-rw-r--r--lib/VMCore/Metadata.cpp48
-rw-r--r--lib/VMCore/PassManager.cpp20
-rw-r--r--lib/VMCore/PassRegistry.cpp2
-rw-r--r--lib/VMCore/Type.cpp68
-rw-r--r--lib/VMCore/TypesContext.h2
-rw-r--r--lib/VMCore/Verifier.cpp3
20 files changed, 493 insertions, 219 deletions
diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp
index ffd367a..cfcffeb 100644
--- a/lib/VMCore/AsmWriter.cpp
+++ b/lib/VMCore/AsmWriter.cpp
@@ -32,6 +32,7 @@
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/CFG.h"
+#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/ErrorHandling.h"
@@ -39,9 +40,13 @@
#include "llvm/Support/FormattedStream.h"
#include <algorithm>
#include <cctype>
-#include <map>
using namespace llvm;
+static cl::opt<bool>
+EnableDebugInfoComment("enable-debug-info-comment", cl::Hidden,
+ cl::desc("Enable debug info comments"));
+
+
// Make virtual table appear in this compilation unit.
AssemblyAnnotationWriter::~AssemblyAnnotationWriter() {}
@@ -89,7 +94,7 @@ enum PrefixType {
/// prefixed with % (if the string only contains simple characters) or is
/// surrounded with ""'s (if it has special chars in it). Print it out.
static void PrintLLVMName(raw_ostream &OS, StringRef Name, PrefixType Prefix) {
- assert(Name.data() && "Cannot get empty name!");
+ assert(!Name.empty() && "Cannot get empty name!");
switch (Prefix) {
default: llvm_unreachable("Bad prefix!");
case NoPrefix: break;
@@ -1075,7 +1080,7 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV,
}
if (CE->hasIndices()) {
- const SmallVector<unsigned, 4> &Indices = CE->getIndices();
+ ArrayRef<unsigned> Indices = CE->getIndices();
for (unsigned i = 0, e = Indices.size(); i != e; ++i)
Out << ", " << Indices[i];
}
@@ -1396,7 +1401,25 @@ void AssemblyWriter::printModule(const Module *M) {
}
void AssemblyWriter::printNamedMDNode(const NamedMDNode *NMD) {
- Out << "!" << NMD->getName() << " = !{";
+ Out << '!';
+ StringRef Name = NMD->getName();
+ if (Name.empty()) {
+ Out << "<empty name> ";
+ } else {
+ if (isalpha(Name[0]) || Name[0] == '-' || Name[0] == '$' ||
+ Name[0] == '.' || Name[0] == '_')
+ Out << Name[0];
+ else
+ Out << '\\' << hexdigit(Name[0] >> 4) << hexdigit(Name[0] & 0x0F);
+ for (unsigned i = 1, e = Name.size(); i != e; ++i) {
+ unsigned char C = Name[i];
+ if (isalnum(C) || C == '-' || C == '$' || C == '.' || C == '_')
+ Out << C;
+ else
+ Out << '\\' << hexdigit(C >> 4) << hexdigit(C & 0x0F);
+ }
+ }
+ Out << " = !{";
for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) {
if (i) Out << ", ";
int Slot = Machine.getMetadataSlot(NMD->getOperand(i));
@@ -1730,6 +1753,18 @@ void AssemblyWriter::printBasicBlock(const BasicBlock *BB) {
if (AnnotationWriter) AnnotationWriter->emitBasicBlockEndAnnot(BB, Out);
}
+/// printDebugLoc - Print DebugLoc.
+static void printDebugLoc(const DebugLoc &DL, formatted_raw_ostream &OS) {
+ OS << DL.getLine() << ":" << DL.getCol();
+ if (MDNode *N = DL.getInlinedAt(getGlobalContext())) {
+ DebugLoc IDL = DebugLoc::getFromDILocation(N);
+ if (!IDL.isUnknown()) {
+ OS << "@";
+ printDebugLoc(IDL,OS);
+ }
+ }
+}
+
/// printInfoComment - Print a little comment after the instruction indicating
/// which slot it occupies.
///
@@ -1737,6 +1772,43 @@ void AssemblyWriter::printInfoComment(const Value &V) {
if (AnnotationWriter) {
AnnotationWriter->printInfoComment(V, Out);
return;
+ } else if (EnableDebugInfoComment) {
+ bool Padded = false;
+ if (const Instruction *I = dyn_cast<Instruction>(&V)) {
+ const DebugLoc &DL = I->getDebugLoc();
+ if (!DL.isUnknown()) {
+ if (!Padded) {
+ Out.PadToColumn(50);
+ Padded = true;
+ Out << ";";
+ }
+ Out << " [debug line = ";
+ printDebugLoc(DL,Out);
+ Out << "]";
+ }
+ if (const DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(I)) {
+ const MDNode *Var = DDI->getVariable();
+ if (!Padded) {
+ Out.PadToColumn(50);
+ Padded = true;
+ Out << ";";
+ }
+ if (Var && Var->getNumOperands() >= 2)
+ if (MDString *MDS = dyn_cast_or_null<MDString>(Var->getOperand(2)))
+ Out << " [debug variable = " << MDS->getString() << "]";
+ }
+ else if (const DbgValueInst *DVI = dyn_cast<DbgValueInst>(I)) {
+ const MDNode *Var = DVI->getVariable();
+ if (!Padded) {
+ Out.PadToColumn(50);
+ Padded = true;
+ Out << ";";
+ }
+ if (Var && Var->getNumOperands() >= 2)
+ if (MDString *MDS = dyn_cast_or_null<MDString>(Var->getOperand(2)))
+ Out << " [debug variable = " << MDS->getString() << "]";
+ }
+ }
}
}
diff --git a/lib/VMCore/Attributes.cpp b/lib/VMCore/Attributes.cpp
index 92152a3..bf6efa1 100644
--- a/lib/VMCore/Attributes.cpp
+++ b/lib/VMCore/Attributes.cpp
@@ -36,6 +36,8 @@ std::string Attribute::getAsString(Attributes Attrs) {
Result += "noreturn ";
if (Attrs & Attribute::NoUnwind)
Result += "nounwind ";
+ if (Attrs & Attribute::UWTable)
+ Result += "uwtable ";
if (Attrs & Attribute::InReg)
Result += "inreg ";
if (Attrs & Attribute::NoAlias)
@@ -72,6 +74,8 @@ std::string Attribute::getAsString(Attributes Attrs) {
Result += "naked ";
if (Attrs & Attribute::Hotpatch)
Result += "hotpatch ";
+ if (Attrs & Attribute::NonLazyBind)
+ Result += "nonlazybind ";
if (Attrs & Attribute::StackAlignment) {
Result += "alignstack(";
Result += utostr(Attribute::getStackAlignmentFromAttrs(Attrs));
diff --git a/lib/VMCore/AutoUpgrade.cpp b/lib/VMCore/AutoUpgrade.cpp
index 9e551bb..9d4543d 100644
--- a/lib/VMCore/AutoUpgrade.cpp
+++ b/lib/VMCore/AutoUpgrade.cpp
@@ -284,8 +284,58 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
break;
}
+ // This upgrades the llvm.prefetch intrinsic to accept one more parameter,
+ // which is a instruction / data cache identifier. The old version only
+ // implicitly accepted the data version.
+ if (Name.compare(5,8,"prefetch",8) == 0) {
+ // Don't do anything if it has the correct number of arguments already
+ if (FTy->getNumParams() == 4)
+ break;
+
+ assert(FTy->getNumParams() == 3 && "old prefetch takes 3 args!");
+ // We first need to change the name of the old (bad) intrinsic, because
+ // its type is incorrect, but we cannot overload that name. We
+ // arbitrarily unique it here allowing us to construct a correctly named
+ // and typed function below.
+ F->setName("");
+ NewFn = cast<Function>(M->getOrInsertFunction(Name,
+ FTy->getReturnType(),
+ FTy->getParamType(0),
+ FTy->getParamType(1),
+ FTy->getParamType(2),
+ FTy->getParamType(2),
+ (Type*)0));
+ return true;
+ }
+
break;
- case 'x':
+ case 'x':
+ // This fixes the poorly named crc32 intrinsics
+ if (Name.compare(5, 13, "x86.sse42.crc", 13) == 0) {
+ const char* NewFnName = NULL;
+ if (Name.compare(18, 2, "32", 2) == 0) {
+ if (Name.compare(20, 2, ".8") == 0 && Name.length() == 22) {
+ NewFnName = "llvm.x86.sse42.crc32.32.8";
+ } else if (Name.compare(20, 3, ".16") == 0 && Name.length() == 23) {
+ NewFnName = "llvm.x86.sse42.crc32.32.16";
+ } else if (Name.compare(20, 3, ".32") == 0 && Name.length() == 23) {
+ NewFnName = "llvm.x86.sse42.crc32.32.32";
+ }
+ }
+ else if (Name.compare(18, 2, "64", 2) == 0) {
+ if (Name.compare(20, 2, ".8") == 0 && Name.length() == 22) {
+ NewFnName = "llvm.x86.sse42.crc32.64.8";
+ } else if (Name.compare(20, 3, ".64") == 0 && Name.length() == 23) {
+ NewFnName = "llvm.x86.sse42.crc32.64.64";
+ }
+ }
+ if (NewFnName) {
+ F->setName(NewFnName);
+ NewFn = F;
+ return true;
+ }
+ }
+
// This fixes all MMX shift intrinsic instructions to take a
// x86_mmx instead of a v1i64, v2i32, v4i16, or v8i8.
if (Name.compare(5, 8, "x86.mmx.", 8) == 0) {
@@ -527,6 +577,19 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
// or 0.
NewFn = 0;
return true;
+ } else if (Name.compare(5, 16, "x86.sse.loadu.ps", 16) == 0 ||
+ Name.compare(5, 17, "x86.sse2.loadu.dq", 17) == 0 ||
+ Name.compare(5, 17, "x86.sse2.loadu.pd", 17) == 0) {
+ // Calls to these instructions are transformed into unaligned loads.
+ NewFn = 0;
+ return true;
+ } else if (Name.compare(5, 16, "x86.sse.movnt.ps", 16) == 0 ||
+ Name.compare(5, 17, "x86.sse2.movnt.dq", 17) == 0 ||
+ Name.compare(5, 17, "x86.sse2.movnt.pd", 17) == 0 ||
+ Name.compare(5, 17, "x86.sse2.movnt.i", 16) == 0) {
+ // Calls to these instructions are transformed into nontemporal stores.
+ NewFn = 0;
+ return true;
} else if (Name.compare(5, 17, "x86.ssse3.pshuf.w", 17) == 0) {
// This is an SSE/MMX instruction.
const Type *X86_MMXTy = VectorType::getX86_MMXTy(FTy->getContext());
@@ -946,7 +1009,54 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
// Remove upgraded instruction.
CI->eraseFromParent();
-
+
+ } else if (F->getName() == "llvm.x86.sse.loadu.ps" ||
+ F->getName() == "llvm.x86.sse2.loadu.dq" ||
+ F->getName() == "llvm.x86.sse2.loadu.pd") {
+ // Convert to a native, unaligned load.
+ const Type *VecTy = CI->getType();
+ const Type *IntTy = IntegerType::get(C, 128);
+ IRBuilder<> Builder(C);
+ Builder.SetInsertPoint(CI->getParent(), CI);
+
+ Value *BC = Builder.CreateBitCast(CI->getArgOperand(0),
+ PointerType::getUnqual(IntTy),
+ "cast");
+ LoadInst *LI = Builder.CreateLoad(BC, CI->getName());
+ LI->setAlignment(1); // Unaligned load.
+ BC = Builder.CreateBitCast(LI, VecTy, "new.cast");
+
+ // Fix up all the uses with our new load.
+ if (!CI->use_empty())
+ CI->replaceAllUsesWith(BC);
+
+ // Remove intrinsic.
+ CI->eraseFromParent();
+ } else if (F->getName() == "llvm.x86.sse.movnt.ps" ||
+ F->getName() == "llvm.x86.sse2.movnt.dq" ||
+ F->getName() == "llvm.x86.sse2.movnt.pd" ||
+ F->getName() == "llvm.x86.sse2.movnt.i") {
+ IRBuilder<> Builder(C);
+ Builder.SetInsertPoint(CI->getParent(), CI);
+
+ Module *M = F->getParent();
+ SmallVector<Value *, 1> Elts;
+ Elts.push_back(ConstantInt::get(Type::getInt32Ty(C), 1));
+ MDNode *Node = MDNode::get(C, Elts);
+
+ Value *Arg0 = CI->getArgOperand(0);
+ Value *Arg1 = CI->getArgOperand(1);
+
+ // Convert the type of the pointer to a pointer to the stored type.
+ Value *BC = Builder.CreateBitCast(Arg0,
+ PointerType::getUnqual(Arg1->getType()),
+ "cast");
+ StoreInst *SI = Builder.CreateStore(Arg1, BC);
+ SI->setMetadata(M->getMDKindID("nontemporal"), Node);
+ SI->setAlignment(16);
+
+ // Remove intrinsic.
+ CI->eraseFromParent();
} else {
llvm_unreachable("Unknown function for CallInst upgrade.");
}
@@ -1258,6 +1368,29 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
CI->eraseFromParent();
break;
}
+ case Intrinsic::prefetch: {
+ IRBuilder<> Builder(C);
+ Builder.SetInsertPoint(CI->getParent(), CI);
+ const llvm::Type *I32Ty = llvm::Type::getInt32Ty(CI->getContext());
+
+ // Add the extra "data cache" argument
+ Value *Operands[4] = { CI->getArgOperand(0), CI->getArgOperand(1),
+ CI->getArgOperand(2),
+ llvm::ConstantInt::get(I32Ty, 1) };
+ CallInst *NewCI = CallInst::Create(NewFn, Operands, Operands+4,
+ CI->getName(), CI);
+ NewCI->setTailCall(CI->isTailCall());
+ NewCI->setCallingConv(CI->getCallingConv());
+ // Handle any uses of the old CallInst.
+ if (!CI->use_empty())
+ // Replace all uses of the old call with the new cast which has the
+ // correct type.
+ CI->replaceAllUsesWith(NewCI);
+
+ // Clean up the old call now that it has been completely upgraded.
+ CI->eraseFromParent();
+ break;
+ }
}
}
diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp
index 573efb7..9985ada 100644
--- a/lib/VMCore/ConstantFold.cpp
+++ b/lib/VMCore/ConstantFold.cpp
@@ -24,6 +24,7 @@
#include "llvm/Function.h"
#include "llvm/GlobalAlias.h"
#include "llvm/GlobalVariable.h"
+#include "llvm/Operator.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
@@ -1735,7 +1736,7 @@ static ICmpInst::Predicate evaluateICmpRelation(Constant *V1, Constant *V2,
// with a single zero index, it must be nonzero.
assert(CE1->getNumOperands() == 2 &&
!CE1->getOperand(1)->isNullValue() &&
- "Suprising getelementptr!");
+ "Surprising getelementptr!");
return isSigned ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT;
} else {
// If they are different globals, we don't know what the value is,
diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp
index 7a4dcf9..15d7793 100644
--- a/lib/VMCore/Constants.cpp
+++ b/lib/VMCore/Constants.cpp
@@ -32,7 +32,6 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
#include <algorithm>
-#include <map>
#include <cstdarg>
using namespace llvm;
@@ -771,7 +770,7 @@ bool ConstantExpr::hasIndices() const {
getOpcode() == Instruction::InsertValue;
}
-const SmallVector<unsigned, 4> &ConstantExpr::getIndices() const {
+ArrayRef<unsigned> ConstantExpr::getIndices() const {
if (const ExtractValueConstantExpr *EVCE =
dyn_cast<ExtractValueConstantExpr>(this))
return EVCE->Indices;
@@ -855,10 +854,10 @@ ConstantExpr::getWithOperandReplaced(unsigned OpNo, Constant *Op) const {
/// operands replaced with the specified values. The specified operands must
/// match count and type with the existing ones.
Constant *ConstantExpr::
-getWithOperands(Constant *const *Ops, unsigned NumOps) const {
- assert(NumOps == getNumOperands() && "Operand count mismatch!");
+getWithOperands(ArrayRef<Constant*> Ops) const {
+ assert(Ops.size() == getNumOperands() && "Operand count mismatch!");
bool AnyChange = false;
- for (unsigned i = 0; i != NumOps; ++i) {
+ for (unsigned i = 0; i != Ops.size(); ++i) {
assert(Ops[i]->getType() == getOperand(i)->getType() &&
"Operand type mismatch!");
AnyChange |= Ops[i] != getOperand(i);
@@ -890,8 +889,8 @@ getWithOperands(Constant *const *Ops, unsigned NumOps) const {
return ConstantExpr::getShuffleVector(Ops[0], Ops[1], Ops[2]);
case Instruction::GetElementPtr:
return cast<GEPOperator>(this)->isInBounds() ?
- ConstantExpr::getInBoundsGetElementPtr(Ops[0], &Ops[1], NumOps-1) :
- ConstantExpr::getGetElementPtr(Ops[0], &Ops[1], NumOps-1);
+ ConstantExpr::getInBoundsGetElementPtr(Ops[0], &Ops[1], Ops.size()-1) :
+ ConstantExpr::getGetElementPtr(Ops[0], &Ops[1], Ops.size()-1);
case Instruction::ICmp:
case Instruction::FCmp:
return ConstantExpr::getCompare(getPredicate(), Ops[0], Ops[1]);
@@ -2151,7 +2150,7 @@ void ConstantExpr::replaceUsesOfWithOnConstant(Value *From, Value *ToV,
Constant *Agg = getOperand(0);
if (Agg == From) Agg = To;
- const SmallVector<unsigned, 4> &Indices = getIndices();
+ ArrayRef<unsigned> Indices = getIndices();
Replacement = ConstantExpr::getExtractValue(Agg,
&Indices[0], Indices.size());
} else if (getOpcode() == Instruction::InsertValue) {
@@ -2160,7 +2159,7 @@ void ConstantExpr::replaceUsesOfWithOnConstant(Value *From, Value *ToV,
if (Agg == From) Agg = To;
if (Val == From) Val = To;
- const SmallVector<unsigned, 4> &Indices = getIndices();
+ ArrayRef<unsigned> Indices = getIndices();
Replacement = ConstantExpr::getInsertValue(Agg, Val,
&Indices[0], Indices.size());
} else if (isCast()) {
diff --git a/lib/VMCore/ConstantsContext.h b/lib/VMCore/ConstantsContext.h
index ffc673f..1395754 100644
--- a/lib/VMCore/ConstantsContext.h
+++ b/lib/VMCore/ConstantsContext.h
@@ -301,20 +301,18 @@ struct OperandTraits<CompareConstantExpr> :
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CompareConstantExpr, Value)
struct ExprMapKeyType {
- typedef SmallVector<unsigned, 4> IndexList;
-
ExprMapKeyType(unsigned opc,
- const std::vector<Constant*> &ops,
+ ArrayRef<Constant*> ops,
unsigned short flags = 0,
unsigned short optionalflags = 0,
- const IndexList &inds = IndexList())
+ ArrayRef<unsigned> inds = ArrayRef<unsigned>())
: opcode(opc), subclassoptionaldata(optionalflags), subclassdata(flags),
- operands(ops), indices(inds) {}
+ operands(ops.begin(), ops.end()), indices(inds.begin(), inds.end()) {}
uint8_t opcode;
uint8_t subclassoptionaldata;
uint16_t subclassdata;
std::vector<Constant*> operands;
- IndexList indices;
+ SmallVector<unsigned, 4> indices;
bool operator==(const ExprMapKeyType& that) const {
return this->opcode == that.opcode &&
this->subclassdata == that.subclassdata &&
@@ -465,7 +463,7 @@ struct ConstantKeyData<ConstantExpr> {
CE->isCompare() ? CE->getPredicate() : 0,
CE->getRawSubclassOptionalData(),
CE->hasIndices() ?
- CE->getIndices() : SmallVector<unsigned, 4>());
+ CE->getIndices() : ArrayRef<unsigned>());
}
};
diff --git a/lib/VMCore/Core.cpp b/lib/VMCore/Core.cpp
index 986b403..92f9440 100644
--- a/lib/VMCore/Core.cpp
+++ b/lib/VMCore/Core.cpp
@@ -335,7 +335,7 @@ unsigned LLVMCountStructElementTypes(LLVMTypeRef StructTy) {
void LLVMGetStructElementTypes(LLVMTypeRef StructTy, LLVMTypeRef *Dest) {
StructType *Ty = unwrap<StructType>(StructTy);
- for (FunctionType::param_iterator I = Ty->element_begin(),
+ for (StructType::element_iterator I = Ty->element_begin(),
E = Ty->element_end(); I != E; ++I)
*Dest++ = wrap(*I);
}
@@ -543,7 +543,8 @@ LLVMValueRef LLVMMDString(const char *Str, unsigned SLen) {
LLVMValueRef LLVMMDNodeInContext(LLVMContextRef C, LLVMValueRef *Vals,
unsigned Count) {
- return wrap(MDNode::get(*unwrap(C), unwrap<Value>(Vals, Count), Count));
+ return wrap(MDNode::get(*unwrap(C),
+ ArrayRef<Value*>(unwrap<Value>(Vals, Count), Count)));
}
LLVMValueRef LLVMMDNode(LLVMValueRef *Vals, unsigned Count) {
diff --git a/lib/VMCore/DebugInfoProbe.cpp b/lib/VMCore/DebugInfoProbe.cpp
index 57d17a6..d1275ff 100644
--- a/lib/VMCore/DebugInfoProbe.cpp
+++ b/lib/VMCore/DebugInfoProbe.cpp
@@ -51,44 +51,28 @@ namespace llvm {
unsigned NumDbgLineLost, NumDbgValueLost;
std::string PassName;
Function *TheFn;
- std::set<unsigned> LineNos;
std::set<MDNode *> DbgVariables;
+ std::set<Instruction *> MissingDebugLoc;
};
}
//===----------------------------------------------------------------------===//
// DebugInfoProbeImpl
-static void collect(Function &F, std::set<unsigned> &Lines) {
- for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI)
- for (BasicBlock::iterator BI = FI->begin(), BE = FI->end();
- BI != BE; ++BI) {
- const DebugLoc &DL = BI->getDebugLoc();
- unsigned LineNo = 0;
- if (!DL.isUnknown()) {
- if (MDNode *N = DL.getInlinedAt(F.getContext()))
- LineNo = DebugLoc::getFromDILocation(N).getLine();
- else
- LineNo = DL.getLine();
-
- Lines.insert(LineNo);
- }
- }
-}
-
/// initialize - Collect information before running an optimization pass.
void DebugInfoProbeImpl::initialize(StringRef PName, Function &F) {
if (!EnableDebugInfoProbe) return;
PassName = PName;
- LineNos.clear();
DbgVariables.clear();
+ MissingDebugLoc.clear();
TheFn = &F;
- collect(F, LineNos);
for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI)
for (BasicBlock::iterator BI = FI->begin(), BE = FI->end();
BI != BE; ++BI) {
+ if (!isa<PHINode>(BI) && BI->getDebugLoc().isUnknown())
+ MissingDebugLoc.insert(BI);
if (!isa<DbgInfoIntrinsic>(BI)) continue;
Value *Addr = NULL;
MDNode *Node = NULL;
@@ -127,23 +111,19 @@ void DebugInfoProbeImpl::report() {
/// must be used after initialization.
void DebugInfoProbeImpl::finalize(Function &F) {
if (!EnableDebugInfoProbe) return;
- std::set<unsigned> LineNos2;
- collect(F, LineNos2);
assert (TheFn == &F && "Invalid function to measure!");
- for (std::set<unsigned>::iterator I = LineNos.begin(),
- E = LineNos.end(); I != E; ++I) {
- unsigned LineNo = *I;
- if (LineNos2.count(LineNo) == 0) {
- DEBUG(dbgs() << "DebugInfoProbe: Losing dbg info intrinsic at line " << LineNo << "\n");
- ++NumDbgLineLost;
- }
- }
-
std::set<MDNode *>DbgVariables2;
for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI)
for (BasicBlock::iterator BI = FI->begin(), BE = FI->end();
BI != BE; ++BI) {
+ if (!isa<PHINode>(BI) && BI->getDebugLoc().isUnknown() &&
+ MissingDebugLoc.count(BI) == 0) {
+ ++NumDbgLineLost;
+ DEBUG(dbgs() << "DebugInfoProbe (" << PassName << "): --- ");
+ DEBUG(BI->print(dbgs()));
+ DEBUG(dbgs() << "\n");
+ }
if (!isa<DbgInfoIntrinsic>(BI)) continue;
Value *Addr = NULL;
MDNode *Node = NULL;
@@ -160,9 +140,17 @@ void DebugInfoProbeImpl::finalize(Function &F) {
for (std::set<MDNode *>::iterator I = DbgVariables.begin(),
E = DbgVariables.end(); I != E; ++I) {
- if (DbgVariables2.count(*I) == 0) {
- DEBUG(dbgs() << "DebugInfoProbe: Losing dbg info for variable: ");
- DEBUG((*I)->print(dbgs()));
+ if (DbgVariables2.count(*I) == 0 && (*I)->getNumOperands() >= 2) {
+ DEBUG(dbgs()
+ << "DebugInfoProbe("
+ << PassName
+ << "): Losing dbg info for variable: ";
+ if (MDString *MDS = dyn_cast_or_null<MDString>(
+ (*I)->getOperand(2)))
+ dbgs() << MDS->getString();
+ else
+ dbgs() << "...";
+ dbgs() << "\n");
++NumDbgValueLost;
}
}
diff --git a/lib/VMCore/DebugLoc.cpp b/lib/VMCore/DebugLoc.cpp
index 3569162..520333c 100644
--- a/lib/VMCore/DebugLoc.cpp
+++ b/lib/VMCore/DebugLoc.cpp
@@ -109,7 +109,7 @@ MDNode *DebugLoc::getAsMDNode(const LLVMContext &Ctx) const {
ConstantInt::get(Int32, getLine()), ConstantInt::get(Int32, getCol()),
Scope, IA
};
- return MDNode::get(Ctx2, &Elts[0], 4);
+ return MDNode::get(Ctx2, Elts);
}
/// getFromDILocation - Translate the DILocation quad into a DebugLoc.
diff --git a/lib/VMCore/Function.cpp b/lib/VMCore/Function.cpp
index 00d1d78..0ae0bdb 100644
--- a/lib/VMCore/Function.cpp
+++ b/lib/VMCore/Function.cpp
@@ -24,6 +24,7 @@
#include "llvm/Support/Threading.h"
#include "SymbolTableListTraitsImpl.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
using namespace llvm;
@@ -78,6 +79,12 @@ bool Argument::hasByValAttr() const {
return getParent()->paramHasAttr(getArgNo()+1, Attribute::ByVal);
}
+unsigned Argument::getParamAlignment() const {
+ assert(getType()->isPointerTy() && "Only pointers have alignments");
+ return getParent()->getParamAlignment(getArgNo()+1);
+
+}
+
/// hasNestAttr - Return true if this argument has the nest attribute on
/// it in its containing function.
bool Argument::hasNestAttr() const {
@@ -328,7 +335,7 @@ unsigned Function::getIntrinsicID() const {
std::string Intrinsic::getName(ID id, const Type **Tys, unsigned numTys) {
assert(id < num_intrinsics && "Invalid intrinsic ID!");
- const char * const Table[] = {
+ static const char * const Table[] = {
"not_intrinsic",
#define GET_INTRINSIC_NAME_TABLE
#include "llvm/Intrinsics.gen"
@@ -363,7 +370,7 @@ const FunctionType *Intrinsic::getType(LLVMContext &Context,
}
bool Intrinsic::isOverloaded(ID id) {
- const bool OTable[] = {
+ static const bool OTable[] = {
false,
#define GET_INTRINSIC_OVERLOAD_TABLE
#include "llvm/Intrinsics.gen"
@@ -406,4 +413,36 @@ bool Function::hasAddressTaken(const User* *PutOffender) const {
return false;
}
+/// callsFunctionThatReturnsTwice - Return true if the function has a call to
+/// setjmp or other function that gcc recognizes as "returning twice".
+///
+/// FIXME: Remove after <rdar://problem/8031714> is fixed.
+/// FIXME: Is the obove FIXME valid?
+bool Function::callsFunctionThatReturnsTwice() const {
+ const Module *M = this->getParent();
+ static const char *ReturnsTwiceFns[] = {
+ "_setjmp",
+ "setjmp",
+ "sigsetjmp",
+ "setjmp_syscall",
+ "savectx",
+ "qsetjmp",
+ "vfork",
+ "getcontext"
+ };
+
+ for (unsigned I = 0; I < array_lengthof(ReturnsTwiceFns); ++I)
+ if (const Function *Callee = M->getFunction(ReturnsTwiceFns[I])) {
+ if (!Callee->use_empty())
+ for (Value::const_use_iterator
+ I = Callee->use_begin(), E = Callee->use_end();
+ I != E; ++I)
+ if (const CallInst *CI = dyn_cast<CallInst>(*I))
+ if (CI->getParent()->getParent() == this)
+ return true;
+ }
+
+ return false;
+}
+
// vim: sw=2 ai
diff --git a/lib/VMCore/IRBuilder.cpp b/lib/VMCore/IRBuilder.cpp
index 1658d79..f2d469a 100644
--- a/lib/VMCore/IRBuilder.cpp
+++ b/lib/VMCore/IRBuilder.cpp
@@ -23,7 +23,7 @@ using namespace llvm;
/// has array of i8 type filled in with the nul terminated string value
/// specified. If Name is specified, it is the name of the global variable
/// created.
-Value *IRBuilderBase::CreateGlobalString(const char *Str, const Twine &Name) {
+Value *IRBuilderBase::CreateGlobalString(StringRef Str, const Twine &Name) {
Constant *StrConstant = ConstantArray::get(Context, Str, true);
Module &M = *BB->getParent()->getParent();
GlobalVariable *GV = new GlobalVariable(M, StrConstant->getType(),
@@ -60,7 +60,6 @@ static CallInst *createCallHelper(Value *Callee, Value *const* Ops,
return CI;
}
-
CallInst *IRBuilderBase::
CreateMemSet(Value *Ptr, Value *Val, Value *Size, unsigned Align,
bool isVolatile, MDNode *TBAATag) {
@@ -118,3 +117,33 @@ CreateMemMove(Value *Dst, Value *Src, Value *Size, unsigned Align,
return CI;
}
+
+CallInst *IRBuilderBase::CreateLifetimeStart(Value *Ptr, ConstantInt *Size) {
+ assert(isa<PointerType>(Ptr->getType()) &&
+ "lifetime.start only applies to pointers.");
+ Ptr = getCastedInt8PtrValue(Ptr);
+ if (!Size)
+ Size = getInt64(-1);
+ else
+ assert(Size->getType() == getInt64Ty() &&
+ "lifetime.start requires the size to be an i64");
+ Value *Ops[] = { Size, Ptr };
+ Module *M = BB->getParent()->getParent();
+ Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::lifetime_start);
+ return createCallHelper(TheFn, Ops, 2, this);
+}
+
+CallInst *IRBuilderBase::CreateLifetimeEnd(Value *Ptr, ConstantInt *Size) {
+ assert(isa<PointerType>(Ptr->getType()) &&
+ "lifetime.end only applies to pointers.");
+ Ptr = getCastedInt8PtrValue(Ptr);
+ if (!Size)
+ Size = getInt64(-1);
+ else
+ assert(Size->getType() == getInt64Ty() &&
+ "lifetime.end requires the size to be an i64");
+ Value *Ops[] = { Size, Ptr };
+ Module *M = BB->getParent()->getParent();
+ Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::lifetime_end);
+ return createCallHelper(TheFn, Ops, 2, this);
+}
diff --git a/lib/VMCore/InlineAsm.cpp b/lib/VMCore/InlineAsm.cpp
index e4f99f0..bd3667d 100644
--- a/lib/VMCore/InlineAsm.cpp
+++ b/lib/VMCore/InlineAsm.cpp
@@ -181,6 +181,11 @@ bool InlineAsm::ConstraintInfo::Parse(StringRef Str,
multipleAlternativeIndex++;
pCodes = &multipleAlternatives[multipleAlternativeIndex].Codes;
++I;
+ } else if (*I == '^') {
+ // Multi-letter constraint
+ // FIXME: For now assuming these are 2-character constraints.
+ pCodes->push_back(std::string(I+1, I+3));
+ I += 3;
} else {
// Single letter constraint.
pCodes->push_back(std::string(I, I+1));
diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp
index 33dfcc0..8f4eabe 100644
--- a/lib/VMCore/Instructions.cpp
+++ b/lib/VMCore/Instructions.cpp
@@ -137,7 +137,8 @@ Value *PHINode::removeIncomingValue(unsigned Idx, bool DeletePHIIfEmpty) {
///
void PHINode::growOperands() {
unsigned e = getNumOperands();
- unsigned NumOps = e*3/2;
+ // Multiply by 1.5 and round down so the result is still even.
+ unsigned NumOps = e + e / 4 * 2;
if (NumOps < 4) NumOps = 4; // 4 op PHI nodes are VERY common.
ReservedSpace = NumOps;
@@ -2075,6 +2076,7 @@ unsigned CastInst::isEliminableCastPair(
CastInst *CastInst::Create(Instruction::CastOps op, Value *S, const Type *Ty,
const Twine &Name, Instruction *InsertBefore) {
+ assert(castIsValid(op, S, Ty) && "Invalid cast!");
// Construct and return the appropriate CastInst subclass
switch (op) {
case Trunc: return new TruncInst (S, Ty, Name, InsertBefore);
@@ -2097,6 +2099,7 @@ CastInst *CastInst::Create(Instruction::CastOps op, Value *S, const Type *Ty,
CastInst *CastInst::Create(Instruction::CastOps op, Value *S, const Type *Ty,
const Twine &Name, BasicBlock *InsertAtEnd) {
+ assert(castIsValid(op, S, Ty) && "Invalid cast!");
// Construct and return the appropriate CastInst subclass
switch (op) {
case Trunc: return new TruncInst (S, Ty, Name, InsertAtEnd);
@@ -2253,60 +2256,56 @@ bool CastInst::isCastable(const Type *SrcTy, const Type *DestTy) {
if (SrcTy == DestTy)
return true;
+ if (const VectorType *SrcVecTy = dyn_cast<VectorType>(SrcTy))
+ if (const VectorType *DestVecTy = dyn_cast<VectorType>(DestTy))
+ if (SrcVecTy->getNumElements() == DestVecTy->getNumElements()) {
+ // An element by element cast. Valid if casting the elements is valid.
+ SrcTy = SrcVecTy->getElementType();
+ DestTy = DestVecTy->getElementType();
+ }
+
// Get the bit sizes, we'll need these
- unsigned SrcBits = SrcTy->getScalarSizeInBits(); // 0 for ptr
- unsigned DestBits = DestTy->getScalarSizeInBits(); // 0 for ptr
+ unsigned SrcBits = SrcTy->getPrimitiveSizeInBits(); // 0 for ptr
+ unsigned DestBits = DestTy->getPrimitiveSizeInBits(); // 0 for ptr
// Run through the possibilities ...
- if (DestTy->isIntegerTy()) { // Casting to integral
- if (SrcTy->isIntegerTy()) { // Casting from integral
+ if (DestTy->isIntegerTy()) { // Casting to integral
+ if (SrcTy->isIntegerTy()) { // Casting from integral
return true;
- } else if (SrcTy->isFloatingPointTy()) { // Casting from floating pt
+ } else if (SrcTy->isFloatingPointTy()) { // Casting from floating pt
return true;
- } else if (const VectorType *PTy = dyn_cast<VectorType>(SrcTy)) {
- // Casting from vector
- return DestBits == PTy->getBitWidth();
+ } else if (SrcTy->isVectorTy()) { // Casting from vector
+ return DestBits == SrcBits;
} else { // Casting from something else
return SrcTy->isPointerTy();
}
- } else if (DestTy->isFloatingPointTy()) { // Casting to floating pt
- if (SrcTy->isIntegerTy()) { // Casting from integral
+ } else if (DestTy->isFloatingPointTy()) { // Casting to floating pt
+ if (SrcTy->isIntegerTy()) { // Casting from integral
return true;
- } else if (SrcTy->isFloatingPointTy()) { // Casting from floating pt
+ } else if (SrcTy->isFloatingPointTy()) { // Casting from floating pt
return true;
- } else if (const VectorType *PTy = dyn_cast<VectorType>(SrcTy)) {
- // Casting from vector
- return DestBits == PTy->getBitWidth();
+ } else if (SrcTy->isVectorTy()) { // Casting from vector
+ return DestBits == SrcBits;
} else { // Casting from something else
return false;
}
- } else if (const VectorType *DestPTy = dyn_cast<VectorType>(DestTy)) {
- // Casting to vector
- if (const VectorType *SrcPTy = dyn_cast<VectorType>(SrcTy)) {
- // Casting from vector
- return DestPTy->getBitWidth() == SrcPTy->getBitWidth();
- } else if (DestPTy->getBitWidth() == SrcBits) {
- return true; // float/int -> vector
- } else if (SrcTy->isX86_MMXTy()) {
- return DestPTy->getBitWidth() == 64; // MMX to 64-bit vector
- } else {
- return false;
- }
+ } else if (DestTy->isVectorTy()) { // Casting to vector
+ return DestBits == SrcBits;
} else if (DestTy->isPointerTy()) { // Casting to pointer
- if (SrcTy->isPointerTy()) { // Casting from pointer
+ if (SrcTy->isPointerTy()) { // Casting from pointer
return true;
- } else if (SrcTy->isIntegerTy()) { // Casting from integral
+ } else if (SrcTy->isIntegerTy()) { // Casting from integral
return true;
- } else { // Casting from something else
+ } else { // Casting from something else
return false;
}
} else if (DestTy->isX86_MMXTy()) {
- if (const VectorType *SrcPTy = dyn_cast<VectorType>(SrcTy)) {
- return SrcPTy->getBitWidth() == 64; // 64-bit vector to MMX
+ if (SrcTy->isVectorTy()) {
+ return DestBits == SrcBits; // 64-bit vector to MMX
} else {
return false;
}
- } else { // Casting to something else
+ } else { // Casting to something else
return false;
}
}
@@ -2321,14 +2320,27 @@ bool CastInst::isCastable(const Type *SrcTy, const Type *DestTy) {
Instruction::CastOps
CastInst::getCastOpcode(
const Value *Src, bool SrcIsSigned, const Type *DestTy, bool DestIsSigned) {
- // Get the bit sizes, we'll need these
const Type *SrcTy = Src->getType();
- unsigned SrcBits = SrcTy->getScalarSizeInBits(); // 0 for ptr
- unsigned DestBits = DestTy->getScalarSizeInBits(); // 0 for ptr
assert(SrcTy->isFirstClassType() && DestTy->isFirstClassType() &&
"Only first class types are castable!");
+ if (SrcTy == DestTy)
+ return BitCast;
+
+ if (const VectorType *SrcVecTy = dyn_cast<VectorType>(SrcTy))
+ if (const VectorType *DestVecTy = dyn_cast<VectorType>(DestTy))
+ if (SrcVecTy->getNumElements() == DestVecTy->getNumElements()) {
+ // An element by element cast. Find the appropriate opcode based on the
+ // element types.
+ SrcTy = SrcVecTy->getElementType();
+ DestTy = DestVecTy->getElementType();
+ }
+
+ // Get the bit sizes, we'll need these
+ unsigned SrcBits = SrcTy->getPrimitiveSizeInBits(); // 0 for ptr
+ unsigned DestBits = DestTy->getPrimitiveSizeInBits(); // 0 for ptr
+
// Run through the possibilities ...
if (DestTy->isIntegerTy()) { // Casting to integral
if (SrcTy->isIntegerTy()) { // Casting from integral
@@ -2347,10 +2359,9 @@ CastInst::getCastOpcode(
return FPToSI; // FP -> sint
else
return FPToUI; // FP -> uint
- } else if (const VectorType *PTy = dyn_cast<VectorType>(SrcTy)) {
- assert(DestBits == PTy->getBitWidth() &&
- "Casting vector to integer of different width");
- PTy = NULL;
+ } else if (SrcTy->isVectorTy()) {
+ assert(DestBits == SrcBits &&
+ "Casting vector to integer of different width");
return BitCast; // Same size, no-op cast
} else {
assert(SrcTy->isPointerTy() &&
@@ -2371,29 +2382,17 @@ CastInst::getCastOpcode(
} else {
return BitCast; // same size, no-op cast
}
- } else if (const VectorType *PTy = dyn_cast<VectorType>(SrcTy)) {
- assert(DestBits == PTy->getBitWidth() &&
+ } else if (SrcTy->isVectorTy()) {
+ assert(DestBits == SrcBits &&
"Casting vector to floating point of different width");
- PTy = NULL;
return BitCast; // same size, no-op cast
} else {
llvm_unreachable("Casting pointer or non-first class to float");
}
- } else if (const VectorType *DestPTy = dyn_cast<VectorType>(DestTy)) {
- if (const VectorType *SrcPTy = dyn_cast<VectorType>(SrcTy)) {
- assert(DestPTy->getBitWidth() == SrcPTy->getBitWidth() &&
- "Casting vector to vector of different widths");
- SrcPTy = NULL;
- return BitCast; // vector -> vector
- } else if (DestPTy->getBitWidth() == SrcBits) {
- return BitCast; // float/int -> vector
- } else if (SrcTy->isX86_MMXTy()) {
- assert(DestPTy->getBitWidth()==64 &&
- "Casting X86_MMX to vector of wrong width");
- return BitCast; // MMX to 64-bit vector
- } else {
- assert(!"Illegal cast to vector (wrong type or size)");
- }
+ } else if (DestTy->isVectorTy()) {
+ assert(DestBits == SrcBits &&
+ "Illegal cast to vector (wrong type or size)");
+ return BitCast;
} else if (DestTy->isPointerTy()) {
if (SrcTy->isPointerTy()) {
return BitCast; // ptr -> ptr
@@ -2403,9 +2402,8 @@ CastInst::getCastOpcode(
assert(!"Casting pointer to other than pointer or int");
}
} else if (DestTy->isX86_MMXTy()) {
- if (isa<VectorType>(SrcTy)) {
- assert(cast<VectorType>(SrcTy)->getBitWidth() == 64 &&
- "Casting vector of wrong width to X86_MMX");
+ if (SrcTy->isVectorTy()) {
+ assert(DestBits == SrcBits && "Casting vector of wrong width to X86_MMX");
return BitCast; // 64-bit vector to MMX
} else {
assert(!"Illegal cast to X86_MMX");
@@ -2441,46 +2439,40 @@ CastInst::castIsValid(Instruction::CastOps op, Value *S, const Type *DstTy) {
unsigned SrcBitSize = SrcTy->getScalarSizeInBits();
unsigned DstBitSize = DstTy->getScalarSizeInBits();
+ // If these are vector types, get the lengths of the vectors (using zero for
+ // scalar types means that checking that vector lengths match also checks that
+ // scalars are not being converted to vectors or vectors to scalars).
+ unsigned SrcLength = SrcTy->isVectorTy() ?
+ cast<VectorType>(SrcTy)->getNumElements() : 0;
+ unsigned DstLength = DstTy->isVectorTy() ?
+ cast<VectorType>(DstTy)->getNumElements() : 0;
+
// Switch on the opcode provided
switch (op) {
default: return false; // This is an input error
case Instruction::Trunc:
- return SrcTy->isIntOrIntVectorTy() &&
- DstTy->isIntOrIntVectorTy()&& SrcBitSize > DstBitSize;
+ return SrcTy->isIntOrIntVectorTy() && DstTy->isIntOrIntVectorTy() &&
+ SrcLength == DstLength && SrcBitSize > DstBitSize;
case Instruction::ZExt:
- return SrcTy->isIntOrIntVectorTy() &&
- DstTy->isIntOrIntVectorTy()&& SrcBitSize < DstBitSize;
+ return SrcTy->isIntOrIntVectorTy() && DstTy->isIntOrIntVectorTy() &&
+ SrcLength == DstLength && SrcBitSize < DstBitSize;
case Instruction::SExt:
- return SrcTy->isIntOrIntVectorTy() &&
- DstTy->isIntOrIntVectorTy()&& SrcBitSize < DstBitSize;
+ return SrcTy->isIntOrIntVectorTy() && DstTy->isIntOrIntVectorTy() &&
+ SrcLength == DstLength && SrcBitSize < DstBitSize;
case Instruction::FPTrunc:
- return SrcTy->isFPOrFPVectorTy() &&
- DstTy->isFPOrFPVectorTy() &&
- SrcBitSize > DstBitSize;
+ return SrcTy->isFPOrFPVectorTy() && DstTy->isFPOrFPVectorTy() &&
+ SrcLength == DstLength && SrcBitSize > DstBitSize;
case Instruction::FPExt:
- return SrcTy->isFPOrFPVectorTy() &&
- DstTy->isFPOrFPVectorTy() &&
- SrcBitSize < DstBitSize;
+ return SrcTy->isFPOrFPVectorTy() && DstTy->isFPOrFPVectorTy() &&
+ SrcLength == DstLength && SrcBitSize < DstBitSize;
case Instruction::UIToFP:
case Instruction::SIToFP:
- if (const VectorType *SVTy = dyn_cast<VectorType>(SrcTy)) {
- if (const VectorType *DVTy = dyn_cast<VectorType>(DstTy)) {
- return SVTy->getElementType()->isIntOrIntVectorTy() &&
- DVTy->getElementType()->isFPOrFPVectorTy() &&
- SVTy->getNumElements() == DVTy->getNumElements();
- }
- }
- return SrcTy->isIntOrIntVectorTy() && DstTy->isFPOrFPVectorTy();
+ return SrcTy->isIntOrIntVectorTy() && DstTy->isFPOrFPVectorTy() &&
+ SrcLength == DstLength;
case Instruction::FPToUI:
case Instruction::FPToSI:
- if (const VectorType *SVTy = dyn_cast<VectorType>(SrcTy)) {
- if (const VectorType *DVTy = dyn_cast<VectorType>(DstTy)) {
- return SVTy->getElementType()->isFPOrFPVectorTy() &&
- DVTy->getElementType()->isIntOrIntVectorTy() &&
- SVTy->getNumElements() == DVTy->getNumElements();
- }
- }
- return SrcTy->isFPOrFPVectorTy() && DstTy->isIntOrIntVectorTy();
+ return SrcTy->isFPOrFPVectorTy() && DstTy->isIntOrIntVectorTy() &&
+ SrcLength == DstLength;
case Instruction::PtrToInt:
return SrcTy->isPointerTy() && DstTy->isIntegerTy();
case Instruction::IntToPtr:
diff --git a/lib/VMCore/LLVMContextImpl.h b/lib/VMCore/LLVMContextImpl.h
index 23971aa..6ea4b48e 100644
--- a/lib/VMCore/LLVMContextImpl.h
+++ b/lib/VMCore/LLVMContextImpl.h
@@ -184,7 +184,7 @@ public:
// Concrete/Abstract TypeDescriptions - We lazily calculate type descriptions
// for types as they are needed. Because resolution of types must invalidate
- // all of the abstract type descriptions, we keep them in a seperate map to
+ // all of the abstract type descriptions, we keep them in a separate map to
// make this easy.
TypePrinting ConcreteTypeDescriptions;
TypePrinting AbstractTypeDescriptions;
diff --git a/lib/VMCore/Metadata.cpp b/lib/VMCore/Metadata.cpp
index 84a0975..eb719e5 100644
--- a/lib/VMCore/Metadata.cpp
+++ b/lib/VMCore/Metadata.cpp
@@ -84,18 +84,18 @@ static MDNodeOperand *getOperandPtr(MDNode *N, unsigned Op) {
return reinterpret_cast<MDNodeOperand*>(N+1)+Op;
}
-MDNode::MDNode(LLVMContext &C, Value *const *Vals, unsigned NumVals,
- bool isFunctionLocal)
+MDNode::MDNode(LLVMContext &C, ArrayRef<Value*> Vals, bool isFunctionLocal)
: Value(Type::getMetadataTy(C), Value::MDNodeVal) {
- NumOperands = NumVals;
+ NumOperands = Vals.size();
if (isFunctionLocal)
setValueSubclassData(getSubclassDataFromValue() | FunctionLocalBit);
// Initialize the operand list, which is co-allocated on the end of the node.
+ unsigned i = 0;
for (MDNodeOperand *Op = getOperandPtr(this, 0), *E = Op+NumOperands;
- Op != E; ++Op, ++Vals)
- new (Op) MDNodeOperand(*Vals, this);
+ Op != E; ++Op, ++i)
+ new (Op) MDNodeOperand(Vals[i], this);
}
@@ -183,9 +183,8 @@ static bool isFunctionLocalValue(Value *V) {
(isa<MDNode>(V) && cast<MDNode>(V)->isFunctionLocal());
}
-MDNode *MDNode::getMDNode(LLVMContext &Context, Value *const *Vals,
- unsigned NumVals, FunctionLocalness FL,
- bool Insert) {
+MDNode *MDNode::getMDNode(LLVMContext &Context, ArrayRef<Value*> Vals,
+ FunctionLocalness FL, bool Insert) {
LLVMContextImpl *pImpl = Context.pImpl;
// Add all the operand pointers. Note that we don't have to add the
@@ -193,7 +192,7 @@ MDNode *MDNode::getMDNode(LLVMContext &Context, Value *const *Vals,
// Note that if the operands are later nulled out, the node will be
// removed from the uniquing map.
FoldingSetNodeID ID;
- for (unsigned i = 0; i != NumVals; ++i)
+ for (unsigned i = 0; i != Vals.size(); ++i)
ID.AddPointer(Vals[i]);
void *InsertPoint;
@@ -205,7 +204,7 @@ MDNode *MDNode::getMDNode(LLVMContext &Context, Value *const *Vals,
bool isFunctionLocal = false;
switch (FL) {
case FL_Unknown:
- for (unsigned i = 0; i != NumVals; ++i) {
+ for (unsigned i = 0; i != Vals.size(); ++i) {
Value *V = Vals[i];
if (!V) continue;
if (isFunctionLocalValue(V)) {
@@ -223,8 +222,8 @@ MDNode *MDNode::getMDNode(LLVMContext &Context, Value *const *Vals,
}
// Coallocate space for the node and Operands together, then placement new.
- void *Ptr = malloc(sizeof(MDNode)+NumVals*sizeof(MDNodeOperand));
- N = new (Ptr) MDNode(Context, Vals, NumVals, isFunctionLocal);
+ void *Ptr = malloc(sizeof(MDNode)+Vals.size()*sizeof(MDNodeOperand));
+ N = new (Ptr) MDNode(Context, Vals, isFunctionLocal);
// InsertPoint will have been set by the FindNodeOrInsertPos call.
pImpl->MDNodeSet.InsertNode(N, InsertPoint);
@@ -233,26 +232,23 @@ MDNode *MDNode::getMDNode(LLVMContext &Context, Value *const *Vals,
}
MDNode *MDNode::get(LLVMContext &Context, ArrayRef<Value*> Vals) {
- return getMDNode(Context, Vals.data(), Vals.size(), FL_Unknown);
-}
-MDNode *MDNode::get(LLVMContext &Context, Value*const* Vals, unsigned NumVals) {
- return getMDNode(Context, Vals, NumVals, FL_Unknown);
+ return getMDNode(Context, Vals, FL_Unknown);
}
-MDNode *MDNode::getWhenValsUnresolved(LLVMContext &Context, Value *const *Vals,
- unsigned NumVals, bool isFunctionLocal) {
- return getMDNode(Context, Vals, NumVals, isFunctionLocal ? FL_Yes : FL_No);
+MDNode *MDNode::getWhenValsUnresolved(LLVMContext &Context,
+ ArrayRef<Value*> Vals,
+ bool isFunctionLocal) {
+ return getMDNode(Context, Vals, isFunctionLocal ? FL_Yes : FL_No);
}
-MDNode *MDNode::getIfExists(LLVMContext &Context, Value *const *Vals,
- unsigned NumVals) {
- return getMDNode(Context, Vals, NumVals, FL_Unknown, false);
+MDNode *MDNode::getIfExists(LLVMContext &Context, ArrayRef<Value*> Vals) {
+ return getMDNode(Context, Vals, FL_Unknown, false);
}
-MDNode *MDNode::getTemporary(LLVMContext &Context, Value *const *Vals,
- unsigned NumVals) {
- MDNode *N = (MDNode *)malloc(sizeof(MDNode)+NumVals*sizeof(MDNodeOperand));
- N = new (N) MDNode(Context, Vals, NumVals, FL_No);
+MDNode *MDNode::getTemporary(LLVMContext &Context, ArrayRef<Value*> Vals) {
+ MDNode *N =
+ (MDNode *)malloc(sizeof(MDNode)+Vals.size()*sizeof(MDNodeOperand));
+ N = new (N) MDNode(Context, Vals, FL_No);
N->setValueSubclassData(N->getSubclassDataFromValue() |
NotUniquedBit);
LeakDetector::addGarbageObject(N);
diff --git a/lib/VMCore/PassManager.cpp b/lib/VMCore/PassManager.cpp
index ca4455a..5cf2905 100644
--- a/lib/VMCore/PassManager.cpp
+++ b/lib/VMCore/PassManager.cpp
@@ -449,9 +449,9 @@ namespace {
static DebugInfoProbeInfo *TheDebugProbe;
static void createDebugInfoProbe() {
if (TheDebugProbe) return;
-
- // Constructed the first time this is called. This guarantees that the
- // object will be constructed, if -enable-debug-info-probe is set,
+
+ // Constructed the first time this is called. This guarantees that the
+ // object will be constructed, if -enable-debug-info-probe is set,
// before static globals, thus it will be destroyed before them.
static ManagedStatic<DebugInfoProbeInfo> DIP;
TheDebugProbe = &*DIP;
@@ -632,6 +632,7 @@ void PMTopLevelManager::schedulePass(Pass *P) {
Pass *AnalysisPass = findAnalysisPass(*I);
if (!AnalysisPass) {
const PassInfo *PI = PassRegistry::getPassRegistry()->getPassInfo(*I);
+ assert(PI && "Expected required passes to be initialized");
AnalysisPass = PI->createPass();
if (P->getPotentialPassManagerType () ==
AnalysisPass->getPotentialPassManagerType())
@@ -686,6 +687,7 @@ Pass *PMTopLevelManager::findAnalysisPass(AnalysisID AID) {
// If Pass not found then check the interfaces implemented by Immutable Pass
const PassInfo *PassInf =
PassRegistry::getPassRegistry()->getPassInfo(PI);
+ assert(PassInf && "Expected all immutable passes to be initialized");
const std::vector<const PassInfo*> &ImmPI =
PassInf->getInterfacesImplemented();
for (std::vector<const PassInfo*>::const_iterator II = ImmPI.begin(),
@@ -727,9 +729,11 @@ void PMTopLevelManager::dumpArguments() const {
for (SmallVector<ImmutablePass *, 8>::const_iterator I =
ImmutablePasses.begin(), E = ImmutablePasses.end(); I != E; ++I)
if (const PassInfo *PI =
- PassRegistry::getPassRegistry()->getPassInfo((*I)->getPassID()))
+ PassRegistry::getPassRegistry()->getPassInfo((*I)->getPassID())) {
+ assert(PI && "Expected all immutable passes to be initialized");
if (!PI->isAnalysisGroup())
dbgs() << " -" << PI->getPassArgument();
+ }
for (SmallVector<PMDataManager *, 8>::const_iterator I = PassManagers.begin(),
E = PassManagers.end(); I != E; ++I)
(*I)->dumpPassArguments();
@@ -982,7 +986,7 @@ void PMDataManager::add(Pass *P, bool ProcessAnalysis) {
// Keep track of higher level analysis used by this manager.
HigherLevelAnalysis.push_back(PRequired);
} else
- llvm_unreachable("Unable to accomodate Required Pass");
+ llvm_unreachable("Unable to accommodate Required Pass");
}
// Set P as P's last user until someone starts using P.
@@ -1183,6 +1187,12 @@ void PMDataManager::dumpAnalysisUsage(StringRef Msg, const Pass *P,
for (unsigned i = 0; i != Set.size(); ++i) {
if (i) dbgs() << ',';
const PassInfo *PInf = PassRegistry::getPassRegistry()->getPassInfo(Set[i]);
+ if (!PInf) {
+ // Some preserved passes, such as AliasAnalysis, may not be initialized by
+ // all drivers.
+ dbgs() << " Uninitialized Pass";
+ continue;
+ }
dbgs() << ' ' << PInf->getPassName();
}
dbgs() << '\n';
diff --git a/lib/VMCore/PassRegistry.cpp b/lib/VMCore/PassRegistry.cpp
index c97a170..fa92620 100644
--- a/lib/VMCore/PassRegistry.cpp
+++ b/lib/VMCore/PassRegistry.cpp
@@ -26,7 +26,7 @@ using namespace llvm;
// FIXME: We use ManagedStatic to erase the pass registrar on shutdown.
// Unfortunately, passes are registered with static ctors, and having
-// llvm_shutdown clear this map prevents successful ressurection after
+// llvm_shutdown clear this map prevents successful resurrection after
// llvm_shutdown is run. Ideally we should find a solution so that we don't
// leak the map, AND can still resurrect after shutdown.
static ManagedStatic<PassRegistry> PassRegistryObj;
diff --git a/lib/VMCore/Type.cpp b/lib/VMCore/Type.cpp
index b15304c..566bb28 100644
--- a/lib/VMCore/Type.cpp
+++ b/lib/VMCore/Type.cpp
@@ -12,23 +12,7 @@
//===----------------------------------------------------------------------===//
#include "LLVMContextImpl.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Constants.h"
-#include "llvm/Assembly/Writer.h"
-#include "llvm/LLVMContext.h"
-#include "llvm/Metadata.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/DepthFirstIterator.h"
-#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/SCCIterator.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/ManagedStatic.h"
-#include "llvm/Support/MathExtras.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/Threading.h"
#include <algorithm>
#include <cstdarg>
using namespace llvm;
@@ -87,7 +71,9 @@ void Type::destroy() const {
operator delete(const_cast<Type *>(this));
return;
- } else if (const OpaqueType *opaque_this = dyn_cast<OpaqueType>(this)) {
+ }
+
+ if (const OpaqueType *opaque_this = dyn_cast<OpaqueType>(this)) {
LLVMContextImpl *pImpl = this->getContext().pImpl;
pImpl->OpaqueTypes.erase(opaque_this);
}
@@ -116,15 +102,6 @@ const Type *Type::getPrimitiveType(LLVMContext &C, TypeID IDNumber) {
}
}
-const Type *Type::getVAArgsPromotedType(LLVMContext &C) const {
- if (ID == IntegerTyID && getSubclassData() < 32)
- return Type::getInt32Ty(C);
- else if (ID == FloatTyID)
- return Type::getDoubleTy(C);
- else
- return this;
-}
-
/// getScalarType - If this is a vector type, return the element type,
/// otherwise return this.
const Type *Type::getScalarType() const {
@@ -197,6 +174,25 @@ bool Type::canLosslesslyBitCastTo(const Type *Ty) const {
return false; // Other types have no identity values
}
+bool Type::isEmptyTy() const {
+ const ArrayType *ATy = dyn_cast<ArrayType>(this);
+ if (ATy) {
+ unsigned NumElements = ATy->getNumElements();
+ return NumElements == 0 || ATy->getElementType()->isEmptyTy();
+ }
+
+ const StructType *STy = dyn_cast<StructType>(this);
+ if (STy) {
+ unsigned NumElements = STy->getNumElements();
+ for (unsigned i = 0; i < NumElements; ++i)
+ if (!STy->getElementType(i)->isEmptyTy())
+ return false;
+ return true;
+ }
+
+ return false;
+}
+
unsigned Type::getPrimitiveSizeInBits() const {
switch (getTypeID()) {
case Type::FloatTyID: return 32;
@@ -243,8 +239,8 @@ bool Type::isSizedDerivedType() const {
if (const ArrayType *ATy = dyn_cast<ArrayType>(this))
return ATy->getElementType()->isSized();
- if (const VectorType *PTy = dyn_cast<VectorType>(this))
- return PTy->getElementType()->isSized();
+ if (const VectorType *VTy = dyn_cast<VectorType>(this))
+ return VTy->getElementType()->isSized();
if (!this->isStructTy())
return false;
@@ -463,11 +459,11 @@ bool FunctionType::isValidArgumentType(const Type *ArgTy) {
FunctionType::FunctionType(const Type *Result,
ArrayRef<const Type*> Params,
bool IsVarArgs)
- : DerivedType(Result->getContext(), FunctionTyID), isVarArgs(IsVarArgs) {
+ : DerivedType(Result->getContext(), FunctionTyID) {
ContainedTys = reinterpret_cast<PATypeHandle*>(this+1);
NumContainedTys = Params.size() + 1; // + 1 for result type
assert(isValidReturnType(Result) && "invalid return type for function");
-
+ setSubclassData(IsVarArgs);
bool isAbstract = Result->isAbstract();
new (&ContainedTys[0]) PATypeHandle(Result, this);
@@ -523,7 +519,7 @@ VectorType::VectorType(const Type *ElType, unsigned NumEl)
PointerType::PointerType(const Type *E, unsigned AddrSpace)
: SequentialType(PointerTyID, E) {
- AddressSpace = AddrSpace;
+ setSubclassData(AddrSpace);
// Calculate whether or not this type is abstract
setAbstract(E->isAbstract());
}
@@ -836,6 +832,9 @@ FunctionValType FunctionValType::get(const FunctionType *FT) {
return FunctionValType(FT->getReturnType(), ParamTypes, FT->isVarArg());
}
+FunctionType *FunctionType::get(const Type *Result, bool isVarArg) {
+ return get(Result, ArrayRef<const Type *>(), isVarArg);
+}
// FunctionType::get - The factory function for the FunctionType class...
FunctionType *FunctionType::get(const Type *ReturnType,
@@ -912,9 +911,14 @@ bool VectorType::isValidElementType(const Type *ElemTy) {
}
//===----------------------------------------------------------------------===//
-// Struct Type Factory...
+// Struct Type Factory.
//
+StructType *StructType::get(LLVMContext &Context, bool isPacked) {
+ return get(Context, llvm::ArrayRef<const Type*>(), isPacked);
+}
+
+
StructType *StructType::get(LLVMContext &Context,
ArrayRef<const Type*> ETypes,
bool isPacked) {
diff --git a/lib/VMCore/TypesContext.h b/lib/VMCore/TypesContext.h
index 6fb53be..ad09478 100644
--- a/lib/VMCore/TypesContext.h
+++ b/lib/VMCore/TypesContext.h
@@ -370,7 +370,7 @@ public:
// Remove the old entry form TypesByHash. If the hash values differ
// now, remove it from the old place. Otherwise, continue scanning
- // withing this hashcode to reduce work.
+ // within this hashcode to reduce work.
if (NewTypeHash != OldTypeHash) {
RemoveFromTypesByHash(OldTypeHash, Ty);
} else {
diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp
index 8b89110..139e035 100644
--- a/lib/VMCore/Verifier.cpp
+++ b/lib/VMCore/Verifier.cpp
@@ -1645,6 +1645,9 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) {
Assert1(isa<ConstantInt>(CI.getArgOperand(3)),
"alignment argument of memory intrinsics must be a constant int",
&CI);
+ Assert1(isa<ConstantInt>(CI.getArgOperand(4)),
+ "isvolatile argument of memory intrinsics must be a constant int",
+ &CI);
break;
case Intrinsic::gcroot:
case Intrinsic::gcwrite: