aboutsummaryrefslogtreecommitdiffstats
path: root/lib/VMCore
diff options
context:
space:
mode:
authorNowar Gu <nowar100@gmail.com>2011-06-23 11:08:11 +0800
committerNowar Gu <nowar100@gmail.com>2011-06-23 11:09:52 +0800
commitbb5c18c80e7ae4ce49eb9067b664f0559ec50965 (patch)
tree4f610e4e03d1c14658e597ce789cb0244fd9f4f8 /lib/VMCore
parent71fea9a88608e9c8fe8a8a523367878e279c3e90 (diff)
parent2fa82bc3da45d272f12a96a61074b637faa62e0b (diff)
downloadexternal_llvm-bb5c18c80e7ae4ce49eb9067b664f0559ec50965.zip
external_llvm-bb5c18c80e7ae4ce49eb9067b664f0559ec50965.tar.gz
external_llvm-bb5c18c80e7ae4ce49eb9067b664f0559ec50965.tar.bz2
Merge upstream to r133679 at Thu. 23th Jun 2011.
Diffstat (limited to 'lib/VMCore')
-rw-r--r--lib/VMCore/AsmWriter.cpp133
-rw-r--r--lib/VMCore/AutoUpgrade.cpp1287
-rw-r--r--lib/VMCore/BasicBlock.cpp20
-rw-r--r--lib/VMCore/ConstantFold.cpp8
-rw-r--r--lib/VMCore/Constants.cpp88
-rw-r--r--lib/VMCore/ConstantsContext.h6
-rw-r--r--lib/VMCore/Core.cpp12
-rw-r--r--lib/VMCore/Function.cpp2
-rw-r--r--lib/VMCore/Instructions.cpp56
-rw-r--r--lib/VMCore/LLVMContextImpl.h34
-rw-r--r--lib/VMCore/Type.cpp86
-rw-r--r--lib/VMCore/TypeSymbolTable.cpp15
-rw-r--r--lib/VMCore/Use.cpp8
-rw-r--r--lib/VMCore/User.cpp12
-rw-r--r--lib/VMCore/Value.cpp3
-rw-r--r--lib/VMCore/ValueSymbolTable.cpp2
-rw-r--r--lib/VMCore/ValueTypes.cpp1
-rw-r--r--lib/VMCore/Verifier.cpp14
18 files changed, 275 insertions, 1512 deletions
diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp
index cfcffeb..496f500 100644
--- a/lib/VMCore/AsmWriter.cpp
+++ b/lib/VMCore/AsmWriter.cpp
@@ -32,7 +32,6 @@
#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"
@@ -42,11 +41,6 @@
#include <cctype>
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() {}
@@ -140,30 +134,45 @@ static void PrintLLVMName(raw_ostream &OS, const Value *V) {
// TypePrinting Class: Type printing machinery
//===----------------------------------------------------------------------===//
-static DenseMap<const Type *, std::string> &getTypeNamesMap(void *M) {
- return *static_cast<DenseMap<const Type *, std::string>*>(M);
-}
-
-void TypePrinting::clear() {
- getTypeNamesMap(TypeNames).clear();
-}
-
-bool TypePrinting::hasTypeName(const Type *Ty) const {
- return getTypeNamesMap(TypeNames).count(Ty);
-}
-
-void TypePrinting::addTypeName(const Type *Ty, const std::string &N) {
- getTypeNamesMap(TypeNames).insert(std::make_pair(Ty, N));
-}
-
-
-TypePrinting::TypePrinting() {
- TypeNames = new DenseMap<const Type *, std::string>();
-}
+/// TypePrinting - Type printing machinery.
+namespace {
+class TypePrinting {
+ DenseMap<const Type *, std::string> TypeNames;
+ TypePrinting(const TypePrinting &); // DO NOT IMPLEMENT
+ void operator=(const TypePrinting&); // DO NOT IMPLEMENT
+public:
+ TypePrinting() {}
+ ~TypePrinting() {}
+
+ void clear() {
+ TypeNames.clear();
+ }
+
+ void print(const Type *Ty, raw_ostream &OS, bool IgnoreTopLevelName = false);
+
+ void printAtLeastOneLevel(const Type *Ty, raw_ostream &OS) {
+ print(Ty, OS, true);
+ }
+
+ /// hasTypeName - Return true if the type has a name in TypeNames, false
+ /// otherwise.
+ bool hasTypeName(const Type *Ty) const {
+ return TypeNames.count(Ty);
+ }
-TypePrinting::~TypePrinting() {
- delete &getTypeNamesMap(TypeNames);
-}
+
+ /// addTypeName - Add a name for the specified type if it doesn't already have
+ /// one. This name will be printed instead of the structural version of the
+ /// type in order to make the output more concise.
+ void addTypeName(const Type *Ty, const std::string &N) {
+ TypeNames.insert(std::make_pair(Ty, N));
+ }
+
+private:
+ void CalcTypeName(const Type *Ty, SmallVectorImpl<const Type *> &TypeStack,
+ raw_ostream &OS, bool IgnoreTopLevelName = false);
+};
+} // end anonymous namespace.
/// CalcTypeName - Write the specified type to the specified raw_ostream, making
/// use of type names or up references to shorten the type name where possible.
@@ -172,7 +181,7 @@ void TypePrinting::CalcTypeName(const Type *Ty,
raw_ostream &OS, bool IgnoreTopLevelName) {
// Check to see if the type is named.
if (!IgnoreTopLevelName) {
- DenseMap<const Type *, std::string> &TM = getTypeNamesMap(TypeNames);
+ DenseMap<const Type *, std::string> &TM = TypeNames;
DenseMap<const Type *, std::string>::iterator I = TM.find(Ty);
if (I != TM.end()) {
OS << I->second;
@@ -283,10 +292,9 @@ void TypePrinting::CalcTypeName(const Type *Ty,
void TypePrinting::print(const Type *Ty, raw_ostream &OS,
bool IgnoreTopLevelName) {
// Check to see if the type is named.
- DenseMap<const Type*, std::string> &TM = getTypeNamesMap(TypeNames);
if (!IgnoreTopLevelName) {
- DenseMap<const Type*, std::string>::iterator I = TM.find(Ty);
- if (I != TM.end()) {
+ DenseMap<const Type*, std::string>::iterator I = TypeNames.find(Ty);
+ if (I != TypeNames.end()) {
OS << I->second;
return;
}
@@ -304,7 +312,7 @@ void TypePrinting::print(const Type *Ty, raw_ostream &OS,
// Cache type name for later use.
if (!IgnoreTopLevelName)
- TM.insert(std::make_pair(Ty, TypeOS.str()));
+ TypeNames.insert(std::make_pair(Ty, TypeOS.str()));
}
namespace {
@@ -1753,18 +1761,6 @@ 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.
///
@@ -1772,43 +1768,6 @@ 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() << "]";
- }
- }
}
}
@@ -1891,16 +1850,16 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
writeOperand(I.getOperand(i), true);
}
Out << ']';
- } else if (isa<PHINode>(I)) {
+ } else if (const PHINode *PN = dyn_cast<PHINode>(&I)) {
Out << ' ';
TypePrinter.print(I.getType(), Out);
Out << ' ';
- for (unsigned op = 0, Eop = I.getNumOperands(); op < Eop; op += 2) {
+ for (unsigned op = 0, Eop = PN->getNumIncomingValues(); op < Eop; ++op) {
if (op) Out << ", ";
Out << "[ ";
- writeOperand(I.getOperand(op ), false); Out << ", ";
- writeOperand(I.getOperand(op+1), false); Out << " ]";
+ writeOperand(PN->getIncomingValue(op), false); Out << ", ";
+ writeOperand(PN->getIncomingBlock(op), false); Out << " ]";
}
} else if (const ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(&I)) {
Out << ' ';
diff --git a/lib/VMCore/AutoUpgrade.cpp b/lib/VMCore/AutoUpgrade.cpp
index 9d4543d..cb7d2ac 100644
--- a/lib/VMCore/AutoUpgrade.cpp
+++ b/lib/VMCore/AutoUpgrade.cpp
@@ -28,266 +28,22 @@ using namespace llvm;
static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
assert(F && "Illegal to upgrade a non-existent Function.");
- // Get the Function's name.
- const std::string& Name = F->getName();
-
- // Convenience
- const FunctionType *FTy = F->getFunctionType();
-
// Quickly eliminate it, if it's not a candidate.
- if (Name.length() <= 8 || Name[0] != 'l' || Name[1] != 'l' ||
- Name[2] != 'v' || Name[3] != 'm' || Name[4] != '.')
+ StringRef Name = F->getName();
+ if (Name.size() <= 8 || !Name.startswith("llvm."))
return false;
+ Name = Name.substr(5); // Strip off "llvm."
+ const FunctionType *FTy = F->getFunctionType();
Module *M = F->getParent();
- switch (Name[5]) {
+
+ switch (Name[0]) {
default: break;
- case 'a':
- // This upgrades the llvm.atomic.lcs, llvm.atomic.las, llvm.atomic.lss,
- // and atomics with default address spaces to their new names to their new
- // function name (e.g. llvm.atomic.add.i32 => llvm.atomic.add.i32.p0i32)
- if (Name.compare(5,7,"atomic.",7) == 0) {
- if (Name.compare(12,3,"lcs",3) == 0) {
- std::string::size_type delim = Name.find('.',12);
- F->setName("llvm.atomic.cmp.swap" + Name.substr(delim) +
- ".p0" + Name.substr(delim+1));
- NewFn = F;
- return true;
- }
- else if (Name.compare(12,3,"las",3) == 0) {
- std::string::size_type delim = Name.find('.',12);
- F->setName("llvm.atomic.load.add"+Name.substr(delim)
- + ".p0" + Name.substr(delim+1));
- NewFn = F;
- return true;
- }
- else if (Name.compare(12,3,"lss",3) == 0) {
- std::string::size_type delim = Name.find('.',12);
- F->setName("llvm.atomic.load.sub"+Name.substr(delim)
- + ".p0" + Name.substr(delim+1));
- NewFn = F;
- return true;
- }
- else if (Name.rfind(".p") == std::string::npos) {
- // We don't have an address space qualifier so this has be upgraded
- // to the new name. Copy the type name at the end of the intrinsic
- // and add to it
- std::string::size_type delim = Name.find_last_of('.');
- assert(delim != std::string::npos && "can not find type");
- F->setName(Name + ".p0" + Name.substr(delim+1));
- NewFn = F;
- return true;
- }
- } else if (Name.compare(5, 9, "arm.neon.", 9) == 0) {
- if (((Name.compare(14, 5, "vmovl", 5) == 0 ||
- Name.compare(14, 5, "vaddl", 5) == 0 ||
- Name.compare(14, 5, "vsubl", 5) == 0 ||
- Name.compare(14, 5, "vaddw", 5) == 0 ||
- Name.compare(14, 5, "vsubw", 5) == 0 ||
- Name.compare(14, 5, "vmlal", 5) == 0 ||
- Name.compare(14, 5, "vmlsl", 5) == 0 ||
- Name.compare(14, 5, "vabdl", 5) == 0 ||
- Name.compare(14, 5, "vabal", 5) == 0) &&
- (Name.compare(19, 2, "s.", 2) == 0 ||
- Name.compare(19, 2, "u.", 2) == 0)) ||
-
- (Name.compare(14, 4, "vaba", 4) == 0 &&
- (Name.compare(18, 2, "s.", 2) == 0 ||
- Name.compare(18, 2, "u.", 2) == 0)) ||
-
- (Name.compare(14, 6, "vmovn.", 6) == 0)) {
-
- // Calls to these are transformed into IR without intrinsics.
- NewFn = 0;
- return true;
- }
- // Old versions of NEON ld/st intrinsics are missing alignment arguments.
- bool isVLd = (Name.compare(14, 3, "vld", 3) == 0);
- bool isVSt = (Name.compare(14, 3, "vst", 3) == 0);
- if (isVLd || isVSt) {
- unsigned NumVecs = Name.at(17) - '0';
- if (NumVecs == 0 || NumVecs > 4)
- return false;
- bool isLaneOp = (Name.compare(18, 5, "lane.", 5) == 0);
- if (!isLaneOp && Name.at(18) != '.')
- return false;
- unsigned ExpectedArgs = 2; // for the address and alignment
- if (isVSt || isLaneOp)
- ExpectedArgs += NumVecs;
- if (isLaneOp)
- ExpectedArgs += 1; // for the lane number
- unsigned NumP = FTy->getNumParams();
- if (NumP != ExpectedArgs - 1)
- return false;
-
- // Change the name of the old (bad) intrinsic, because
- // its type is incorrect, but we cannot overload that name.
- F->setName("");
-
- // One argument is missing: add the alignment argument.
- std::vector<const Type*> NewParams;
- for (unsigned p = 0; p < NumP; ++p)
- NewParams.push_back(FTy->getParamType(p));
- NewParams.push_back(Type::getInt32Ty(F->getContext()));
- FunctionType *NewFTy = FunctionType::get(FTy->getReturnType(),
- NewParams, false);
- NewFn = cast<Function>(M->getOrInsertFunction(Name, NewFTy));
- return true;
- }
- }
- break;
- case 'b':
- // This upgrades the name of the llvm.bswap intrinsic function to only use
- // a single type name for overloading. We only care about the old format
- // 'llvm.bswap.i*.i*', so check for 'bswap.' and then for there being
- // a '.' after 'bswap.'
- if (Name.compare(5,6,"bswap.",6) == 0) {
- std::string::size_type delim = Name.find('.',11);
-
- if (delim != std::string::npos) {
- // Construct the new name as 'llvm.bswap' + '.i*'
- F->setName(Name.substr(0,10)+Name.substr(delim));
- NewFn = F;
- return true;
- }
- }
- break;
-
- case 'c':
- // We only want to fix the 'llvm.ct*' intrinsics which do not have the
- // correct return type, so we check for the name, and then check if the
- // return type does not match the parameter type.
- if ( (Name.compare(5,5,"ctpop",5) == 0 ||
- Name.compare(5,4,"ctlz",4) == 0 ||
- Name.compare(5,4,"cttz",4) == 0) &&
- FTy->getReturnType() != FTy->getParamType(0)) {
- // 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("");
-
- // Now construct the new intrinsic with the correct name and type. We
- // leave the old function around in order to query its type, whatever it
- // may be, and correctly convert up to the new type.
- NewFn = cast<Function>(M->getOrInsertFunction(Name,
- FTy->getParamType(0),
- FTy->getParamType(0),
- (Type *)0));
- return true;
- }
- break;
-
- case 'e':
- // The old llvm.eh.selector.i32 is equivalent to the new llvm.eh.selector.
- if (Name.compare("llvm.eh.selector.i32") == 0) {
- F->setName("llvm.eh.selector");
- NewFn = F;
- return true;
- }
- // The old llvm.eh.typeid.for.i32 is equivalent to llvm.eh.typeid.for.
- if (Name.compare("llvm.eh.typeid.for.i32") == 0) {
- F->setName("llvm.eh.typeid.for");
- NewFn = F;
- return true;
- }
- // Convert the old llvm.eh.selector.i64 to a call to llvm.eh.selector.
- if (Name.compare("llvm.eh.selector.i64") == 0) {
- NewFn = Intrinsic::getDeclaration(M, Intrinsic::eh_selector);
- return true;
- }
- // Convert the old llvm.eh.typeid.for.i64 to a call to llvm.eh.typeid.for.
- if (Name.compare("llvm.eh.typeid.for.i64") == 0) {
- NewFn = Intrinsic::getDeclaration(M, Intrinsic::eh_typeid_for);
- return true;
- }
- break;
-
- case 'm': {
- // This upgrades the llvm.memcpy, llvm.memmove, and llvm.memset to the
- // new format that allows overloading the pointer for different address
- // space (e.g., llvm.memcpy.i16 => llvm.memcpy.p0i8.p0i8.i16)
- const char* NewFnName = NULL;
- if (Name.compare(5,8,"memcpy.i",8) == 0) {
- if (Name[13] == '8')
- NewFnName = "llvm.memcpy.p0i8.p0i8.i8";
- else if (Name.compare(13,2,"16") == 0)
- NewFnName = "llvm.memcpy.p0i8.p0i8.i16";
- else if (Name.compare(13,2,"32") == 0)
- NewFnName = "llvm.memcpy.p0i8.p0i8.i32";
- else if (Name.compare(13,2,"64") == 0)
- NewFnName = "llvm.memcpy.p0i8.p0i8.i64";
- } else if (Name.compare(5,9,"memmove.i",9) == 0) {
- if (Name[14] == '8')
- NewFnName = "llvm.memmove.p0i8.p0i8.i8";
- else if (Name.compare(14,2,"16") == 0)
- NewFnName = "llvm.memmove.p0i8.p0i8.i16";
- else if (Name.compare(14,2,"32") == 0)
- NewFnName = "llvm.memmove.p0i8.p0i8.i32";
- else if (Name.compare(14,2,"64") == 0)
- NewFnName = "llvm.memmove.p0i8.p0i8.i64";
- }
- else if (Name.compare(5,8,"memset.i",8) == 0) {
- if (Name[13] == '8')
- NewFnName = "llvm.memset.p0i8.i8";
- else if (Name.compare(13,2,"16") == 0)
- NewFnName = "llvm.memset.p0i8.i16";
- else if (Name.compare(13,2,"32") == 0)
- NewFnName = "llvm.memset.p0i8.i32";
- else if (Name.compare(13,2,"64") == 0)
- NewFnName = "llvm.memset.p0i8.i64";
- }
- if (NewFnName) {
- NewFn = cast<Function>(M->getOrInsertFunction(NewFnName,
- FTy->getReturnType(),
- FTy->getParamType(0),
- FTy->getParamType(1),
- FTy->getParamType(2),
- FTy->getParamType(3),
- Type::getInt1Ty(F->getContext()),
- (Type *)0));
- return true;
- }
- break;
- }
case 'p':
- // This upgrades the llvm.part.select overloaded intrinsic names to only
- // use one type specifier in the name. We only care about the old format
- // 'llvm.part.select.i*.i*', and solve as above with bswap.
- if (Name.compare(5,12,"part.select.",12) == 0) {
- std::string::size_type delim = Name.find('.',17);
-
- if (delim != std::string::npos) {
- // Construct a new name as 'llvm.part.select' + '.i*'
- F->setName(Name.substr(0,16)+Name.substr(delim));
- NewFn = F;
- return true;
- }
- break;
- }
-
- // This upgrades the llvm.part.set intrinsics similarly as above, however
- // we care about 'llvm.part.set.i*.i*.i*', but only the first two types
- // must match. There is an additional type specifier after these two
- // matching types that we must retain when upgrading. Thus, we require
- // finding 2 periods, not just one, after the intrinsic name.
- if (Name.compare(5,9,"part.set.",9) == 0) {
- std::string::size_type delim = Name.find('.',14);
-
- if (delim != std::string::npos &&
- Name.find('.',delim+1) != std::string::npos) {
- // Construct a new name as 'llvm.part.select' + '.i*.i*'
- F->setName(Name.substr(0,13)+Name.substr(delim));
- NewFn = F;
- return true;
- }
- 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) {
+ if (Name == "prefetch") {
// Don't do anything if it has the correct number of arguments already
if (FTy->getNumParams() == 4)
break;
@@ -297,8 +53,9 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
// 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.
+ std::string NameTmp = F->getName();
F->setName("");
- NewFn = cast<Function>(M->getOrInsertFunction(Name,
+ NewFn = cast<Function>(M->getOrInsertFunction(NameTmp,
FTy->getReturnType(),
FTy->getParamType(0),
FTy->getParamType(1),
@@ -309,301 +66,39 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
}
break;
- 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;
- }
+ case 'x': {
+ const char *NewFnName = NULL;
+ // This fixes the poorly named crc32 intrinsics.
+ if (Name == "x86.sse42.crc32.8")
+ NewFnName = "llvm.x86.sse42.crc32.32.8";
+ else if (Name == "x86.sse42.crc32.16")
+ NewFnName = "llvm.x86.sse42.crc32.32.16";
+ else if (Name == "x86.sse42.crc32.32")
+ NewFnName = "llvm.x86.sse42.crc32.32.32";
+ else if (Name == "x86.sse42.crc64.8")
+ NewFnName = "llvm.x86.sse42.crc32.64.8";
+ else if (Name == "x86.sse42.crc64.64")
+ 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) {
- const Type *X86_MMXTy = VectorType::getX86_MMXTy(FTy->getContext());
-
- if (Name.compare(13, 4, "padd", 4) == 0 ||
- Name.compare(13, 4, "psub", 4) == 0 ||
- Name.compare(13, 4, "pmul", 4) == 0 ||
- Name.compare(13, 5, "pmadd", 5) == 0 ||
- Name.compare(13, 4, "pand", 4) == 0 ||
- Name.compare(13, 3, "por", 3) == 0 ||
- Name.compare(13, 4, "pxor", 4) == 0 ||
- Name.compare(13, 4, "pavg", 4) == 0 ||
- Name.compare(13, 4, "pmax", 4) == 0 ||
- Name.compare(13, 4, "pmin", 4) == 0 ||
- Name.compare(13, 4, "psad", 4) == 0 ||
- Name.compare(13, 4, "psll", 4) == 0 ||
- Name.compare(13, 4, "psrl", 4) == 0 ||
- Name.compare(13, 4, "psra", 4) == 0 ||
- Name.compare(13, 4, "pack", 4) == 0 ||
- Name.compare(13, 6, "punpck", 6) == 0 ||
- Name.compare(13, 4, "pcmp", 4) == 0) {
- assert(FTy->getNumParams() == 2 && "MMX intrinsic takes 2 args!");
- const Type *SecondParamTy = X86_MMXTy;
-
- if (Name.compare(13, 5, "pslli", 5) == 0 ||
- Name.compare(13, 5, "psrli", 5) == 0 ||
- Name.compare(13, 5, "psrai", 5) == 0)
- SecondParamTy = FTy->getParamType(1);
-
- // Don't do anything if it has the correct types.
- if (FTy->getReturnType() == X86_MMXTy &&
- FTy->getParamType(0) == X86_MMXTy &&
- FTy->getParamType(1) == SecondParamTy)
- break;
-
- // 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("");
-
- // Now construct the new intrinsic with the correct name and type. We
- // leave the old function around in order to query its type, whatever it
- // may be, and correctly convert up to the new type.
- NewFn = cast<Function>(M->getOrInsertFunction(Name,
- X86_MMXTy, X86_MMXTy,
- SecondParamTy, (Type*)0));
- return true;
- }
-
- if (Name.compare(13, 8, "maskmovq", 8) == 0) {
- // Don't do anything if it has the correct types.
- if (FTy->getParamType(0) == X86_MMXTy &&
- FTy->getParamType(1) == X86_MMXTy)
- break;
-
- F->setName("");
- NewFn = cast<Function>(M->getOrInsertFunction(Name,
- FTy->getReturnType(),
- X86_MMXTy,
- X86_MMXTy,
- FTy->getParamType(2),
- (Type*)0));
- return true;
- }
-
- if (Name.compare(13, 8, "pmovmskb", 8) == 0) {
- if (FTy->getParamType(0) == X86_MMXTy)
- break;
-
- F->setName("");
- NewFn = cast<Function>(M->getOrInsertFunction(Name,
- FTy->getReturnType(),
- X86_MMXTy,
- (Type*)0));
- return true;
- }
-
- if (Name.compare(13, 5, "movnt", 5) == 0) {
- if (FTy->getParamType(1) == X86_MMXTy)
- break;
-
- F->setName("");
- NewFn = cast<Function>(M->getOrInsertFunction(Name,
- FTy->getReturnType(),
- FTy->getParamType(0),
- X86_MMXTy,
- (Type*)0));
- return true;
- }
-
- if (Name.compare(13, 7, "palignr", 7) == 0) {
- if (FTy->getReturnType() == X86_MMXTy &&
- FTy->getParamType(0) == X86_MMXTy &&
- FTy->getParamType(1) == X86_MMXTy)
- break;
-
- F->setName("");
- NewFn = cast<Function>(M->getOrInsertFunction(Name,
- X86_MMXTy,
- X86_MMXTy,
- X86_MMXTy,
- FTy->getParamType(2),
- (Type*)0));
- return true;
- }
-
- if (Name.compare(13, 5, "pextr", 5) == 0) {
- if (FTy->getParamType(0) == X86_MMXTy)
- break;
-
- F->setName("");
- NewFn = cast<Function>(M->getOrInsertFunction(Name,
- FTy->getReturnType(),
- X86_MMXTy,
- FTy->getParamType(1),
- (Type*)0));
- return true;
- }
-
- if (Name.compare(13, 5, "pinsr", 5) == 0) {
- if (FTy->getReturnType() == X86_MMXTy &&
- FTy->getParamType(0) == X86_MMXTy)
- break;
-
- F->setName("");
- NewFn = cast<Function>(M->getOrInsertFunction(Name,
- X86_MMXTy,
- X86_MMXTy,
- FTy->getParamType(1),
- FTy->getParamType(2),
- (Type*)0));
- return true;
- }
-
- if (Name.compare(13, 12, "cvtsi32.si64", 12) == 0) {
- if (FTy->getReturnType() == X86_MMXTy)
- break;
-
- F->setName("");
- NewFn = cast<Function>(M->getOrInsertFunction(Name,
- X86_MMXTy,
- FTy->getParamType(0),
- (Type*)0));
- return true;
- }
-
- if (Name.compare(13, 12, "cvtsi64.si32", 12) == 0) {
- if (FTy->getParamType(0) == X86_MMXTy)
- break;
-
- F->setName("");
- NewFn = cast<Function>(M->getOrInsertFunction(Name,
- FTy->getReturnType(),
- X86_MMXTy,
- (Type*)0));
- return true;
- }
-
- if (Name.compare(13, 8, "vec.init", 8) == 0) {
- if (FTy->getReturnType() == X86_MMXTy)
- break;
-
- F->setName("");
-
- if (Name.compare(21, 2, ".b", 2) == 0)
- NewFn = cast<Function>(M->getOrInsertFunction(Name,
- X86_MMXTy,
- FTy->getParamType(0),
- FTy->getParamType(1),
- FTy->getParamType(2),
- FTy->getParamType(3),
- FTy->getParamType(4),
- FTy->getParamType(5),
- FTy->getParamType(6),
- FTy->getParamType(7),
- (Type*)0));
- else if (Name.compare(21, 2, ".w", 2) == 0)
- NewFn = cast<Function>(M->getOrInsertFunction(Name,
- X86_MMXTy,
- FTy->getParamType(0),
- FTy->getParamType(1),
- FTy->getParamType(2),
- FTy->getParamType(3),
- (Type*)0));
- else if (Name.compare(21, 2, ".d", 2) == 0)
- NewFn = cast<Function>(M->getOrInsertFunction(Name,
- X86_MMXTy,
- FTy->getParamType(0),
- FTy->getParamType(1),
- (Type*)0));
- return true;
- }
-
-
- if (Name.compare(13, 9, "vec.ext.d", 9) == 0) {
- if (FTy->getReturnType() == X86_MMXTy &&
- FTy->getParamType(0) == X86_MMXTy)
- break;
-
- F->setName("");
- NewFn = cast<Function>(M->getOrInsertFunction(Name,
- X86_MMXTy,
- X86_MMXTy,
- FTy->getParamType(1),
- (Type*)0));
- return true;
- }
-
- if (Name.compare(13, 9, "emms", 4) == 0 ||
- Name.compare(13, 9, "femms", 5) == 0) {
- NewFn = 0;
- break;
- }
-
- // We really shouldn't get here ever.
- assert(0 && "Invalid MMX intrinsic!");
- break;
- } else if (Name.compare(5,17,"x86.sse2.loadh.pd",17) == 0 ||
- Name.compare(5,17,"x86.sse2.loadl.pd",17) == 0 ||
- Name.compare(5,16,"x86.sse2.movl.dq",16) == 0 ||
- Name.compare(5,15,"x86.sse2.movs.d",15) == 0 ||
- Name.compare(5,16,"x86.sse2.shuf.pd",16) == 0 ||
- Name.compare(5,18,"x86.sse2.unpckh.pd",18) == 0 ||
- Name.compare(5,18,"x86.sse2.unpckl.pd",18) == 0 ||
- Name.compare(5,20,"x86.sse2.punpckh.qdq",20) == 0 ||
- Name.compare(5,20,"x86.sse2.punpckl.qdq",20) == 0) {
- // Calls to these intrinsics are transformed into ShuffleVector's.
- NewFn = 0;
- return true;
- } else if (Name.compare(5, 16, "x86.sse41.pmulld", 16) == 0) {
- // Calls to these intrinsics are transformed into vector multiplies.
- NewFn = 0;
- return true;
- } else if (Name.compare(5, 18, "x86.ssse3.palign.r", 18) == 0 ||
- Name.compare(5, 22, "x86.ssse3.palign.r.128", 22) == 0) {
- // Calls to these intrinsics are transformed into vector shuffles, shifts,
- // or 0.
- NewFn = 0;
- return true;
- } 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;
+ // Calls to these instructions are transformed into unaligned loads.
+ if (Name == "x86.sse.loadu.ps" || Name == "x86.sse2.loadu.dq" ||
+ Name == "x86.sse2.loadu.pd")
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());
- NewFn =
- cast<Function>(M->getOrInsertFunction("llvm.x86.sse.pshuf.w",
- X86_MMXTy,
- X86_MMXTy,
- Type::getInt8Ty(F->getContext()),
- (Type*)0));
+
+ // Calls to these instructions are transformed into nontemporal stores.
+ if (Name == "x86.sse.movnt.ps" || Name == "x86.sse2.movnt.dq" ||
+ Name == "x86.sse2.movnt.pd" || Name == "x86.sse2.movnt.i")
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
@@ -625,105 +120,10 @@ bool llvm::UpgradeIntrinsicFunction(Function *F, Function *&NewFn) {
}
bool llvm::UpgradeGlobalVariable(GlobalVariable *GV) {
- StringRef Name(GV->getName());
-
- // We are only upgrading one symbol here.
- if (Name == ".llvm.eh.catch.all.value") {
- GV->setName("llvm.eh.catch.all.value");
- return true;
- }
-
+ // Nothing to do yet.
return false;
}
-/// ExtendNEONArgs - For NEON "long" and "wide" operations, where the results
-/// have vector elements twice as big as one or both source operands, do the
-/// sign- or zero-extension that used to be handled by intrinsics. The
-/// extended values are returned via V0 and V1.
-static void ExtendNEONArgs(CallInst *CI, Value *Arg0, Value *Arg1,
- Value *&V0, Value *&V1) {
- Function *F = CI->getCalledFunction();
- const std::string& Name = F->getName();
- bool isLong = (Name.at(18) == 'l');
- bool isSigned = (Name.at(19) == 's');
-
- if (isSigned) {
- if (isLong)
- V0 = new SExtInst(Arg0, CI->getType(), "", CI);
- else
- V0 = Arg0;
- V1 = new SExtInst(Arg1, CI->getType(), "", CI);
- } else {
- if (isLong)
- V0 = new ZExtInst(Arg0, CI->getType(), "", CI);
- else
- V0 = Arg0;
- V1 = new ZExtInst(Arg1, CI->getType(), "", CI);
- }
-}
-
-/// CallVABD - As part of expanding a call to one of the old NEON vabdl, vaba,
-/// or vabal intrinsics, construct a call to a vabd intrinsic. Examine the
-/// name of the old intrinsic to determine whether to use a signed or unsigned
-/// vabd intrinsic. Get the type from the old call instruction, adjusted for
-/// half-size vector elements if the old intrinsic was vabdl or vabal.
-static Instruction *CallVABD(CallInst *CI, Value *Arg0, Value *Arg1) {
- Function *F = CI->getCalledFunction();
- const std::string& Name = F->getName();
- bool isLong = (Name.at(18) == 'l');
- bool isSigned = (Name.at(isLong ? 19 : 18) == 's');
-
- Intrinsic::ID intID;
- if (isSigned)
- intID = Intrinsic::arm_neon_vabds;
- else
- intID = Intrinsic::arm_neon_vabdu;
-
- const Type *Ty = CI->getType();
- if (isLong)
- Ty = VectorType::getTruncatedElementVectorType(cast<const VectorType>(Ty));
-
- Function *VABD = Intrinsic::getDeclaration(F->getParent(), intID, &Ty, 1);
- Value *Operands[2];
- Operands[0] = Arg0;
- Operands[1] = Arg1;
- return CallInst::Create(VABD, Operands, Operands+2,
- "upgraded."+CI->getName(), CI);
-}
-
-/// ConstructNewCallInst - Construct a new CallInst with the signature of NewFn.
-static void ConstructNewCallInst(Function *NewFn, CallInst *OldCI,
- Value **Operands, unsigned NumOps,
- bool AssignName = true) {
- // Construct a new CallInst.
- CallInst *NewCI =
- CallInst::Create(NewFn, Operands, Operands + NumOps,
- AssignName ? "upgraded." + OldCI->getName() : "", OldCI);
-
- NewCI->setTailCall(OldCI->isTailCall());
- NewCI->setCallingConv(OldCI->getCallingConv());
-
- // Handle any uses of the old CallInst. If the type has changed, add a cast.
- if (!OldCI->use_empty()) {
- if (OldCI->getType() != NewCI->getType()) {
- Function *OldFn = OldCI->getCalledFunction();
- CastInst *RetCast =
- CastInst::Create(CastInst::getCastOpcode(NewCI, true,
- OldFn->getReturnType(), true),
- NewCI, OldFn->getReturnType(), NewCI->getName(),OldCI);
-
- // Replace all uses of the old call with the new cast which has the
- // correct type.
- OldCI->replaceAllUsesWith(RetCast);
- } else {
- OldCI->replaceAllUsesWith(NewCI);
- }
- }
-
- // Clean up the old call now that it has been completely upgraded.
- OldCI->eraseFromParent();
-}
-
// 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.
@@ -735,284 +135,9 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
assert(F && "CallInst has no function associated with it.");
if (!NewFn) {
- // Get the Function's name.
- const std::string& Name = F->getName();
-
- // Upgrade ARM NEON intrinsics.
- if (Name.compare(5, 9, "arm.neon.", 9) == 0) {
- Instruction *NewI;
- Value *V0, *V1;
- if (Name.compare(14, 7, "vmovls.", 7) == 0) {
- NewI = new SExtInst(CI->getArgOperand(0), CI->getType(),
- "upgraded." + CI->getName(), CI);
- } else if (Name.compare(14, 7, "vmovlu.", 7) == 0) {
- NewI = new ZExtInst(CI->getArgOperand(0), CI->getType(),
- "upgraded." + CI->getName(), CI);
- } else if (Name.compare(14, 4, "vadd", 4) == 0) {
- ExtendNEONArgs(CI, CI->getArgOperand(0), CI->getArgOperand(1), V0, V1);
- NewI = BinaryOperator::CreateAdd(V0, V1, "upgraded."+CI->getName(), CI);
- } else if (Name.compare(14, 4, "vsub", 4) == 0) {
- ExtendNEONArgs(CI, CI->getArgOperand(0), CI->getArgOperand(1), V0, V1);
- NewI = BinaryOperator::CreateSub(V0, V1,"upgraded."+CI->getName(),CI);
- } else if (Name.compare(14, 4, "vmul", 4) == 0) {
- ExtendNEONArgs(CI, CI->getArgOperand(0), CI->getArgOperand(1), V0, V1);
- NewI = BinaryOperator::CreateMul(V0, V1,"upgraded."+CI->getName(),CI);
- } else if (Name.compare(14, 4, "vmla", 4) == 0) {
- ExtendNEONArgs(CI, CI->getArgOperand(1), CI->getArgOperand(2), V0, V1);
- Instruction *MulI = BinaryOperator::CreateMul(V0, V1, "", CI);
- NewI = BinaryOperator::CreateAdd(CI->getArgOperand(0), MulI,
- "upgraded."+CI->getName(), CI);
- } else if (Name.compare(14, 4, "vmls", 4) == 0) {
- ExtendNEONArgs(CI, CI->getArgOperand(1), CI->getArgOperand(2), V0, V1);
- Instruction *MulI = BinaryOperator::CreateMul(V0, V1, "", CI);
- NewI = BinaryOperator::CreateSub(CI->getArgOperand(0), MulI,
- "upgraded."+CI->getName(), CI);
- } else if (Name.compare(14, 4, "vabd", 4) == 0) {
- NewI = CallVABD(CI, CI->getArgOperand(0), CI->getArgOperand(1));
- NewI = new ZExtInst(NewI, CI->getType(), "upgraded."+CI->getName(), CI);
- } else if (Name.compare(14, 4, "vaba", 4) == 0) {
- NewI = CallVABD(CI, CI->getArgOperand(1), CI->getArgOperand(2));
- if (Name.at(18) == 'l')
- NewI = new ZExtInst(NewI, CI->getType(), "", CI);
- NewI = BinaryOperator::CreateAdd(CI->getArgOperand(0), NewI,
- "upgraded."+CI->getName(), CI);
- } else if (Name.compare(14, 6, "vmovn.", 6) == 0) {
- NewI = new TruncInst(CI->getArgOperand(0), CI->getType(),
- "upgraded." + CI->getName(), CI);
- } else {
- llvm_unreachable("Unknown arm.neon function for CallInst upgrade.");
- }
- // Replace any uses of the old CallInst.
- if (!CI->use_empty())
- CI->replaceAllUsesWith(NewI);
- CI->eraseFromParent();
- return;
- }
-
- bool isLoadH = false, isLoadL = false, isMovL = false;
- bool isMovSD = false, isShufPD = false;
- bool isUnpckhPD = false, isUnpcklPD = false;
- bool isPunpckhQPD = false, isPunpcklQPD = false;
- if (F->getName() == "llvm.x86.sse2.loadh.pd")
- isLoadH = true;
- else if (F->getName() == "llvm.x86.sse2.loadl.pd")
- isLoadL = true;
- else if (F->getName() == "llvm.x86.sse2.movl.dq")
- isMovL = true;
- else if (F->getName() == "llvm.x86.sse2.movs.d")
- isMovSD = true;
- else if (F->getName() == "llvm.x86.sse2.shuf.pd")
- isShufPD = true;
- else if (F->getName() == "llvm.x86.sse2.unpckh.pd")
- isUnpckhPD = true;
- else if (F->getName() == "llvm.x86.sse2.unpckl.pd")
- isUnpcklPD = true;
- else if (F->getName() == "llvm.x86.sse2.punpckh.qdq")
- isPunpckhQPD = true;
- else if (F->getName() == "llvm.x86.sse2.punpckl.qdq")
- isPunpcklQPD = true;
-
- if (isLoadH || isLoadL || isMovL || isMovSD || isShufPD ||
- isUnpckhPD || isUnpcklPD || isPunpckhQPD || isPunpcklQPD) {
- std::vector<Constant*> Idxs;
- Value *Op0 = CI->getArgOperand(0);
- ShuffleVectorInst *SI = NULL;
- if (isLoadH || isLoadL) {
- Value *Op1 = UndefValue::get(Op0->getType());
- Value *Addr = new BitCastInst(CI->getArgOperand(1),
- Type::getDoublePtrTy(C),
- "upgraded.", CI);
- Value *Load = new LoadInst(Addr, "upgraded.", false, 8, CI);
- Value *Idx = ConstantInt::get(Type::getInt32Ty(C), 0);
- Op1 = InsertElementInst::Create(Op1, Load, Idx, "upgraded.", CI);
-
- if (isLoadH) {
- Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 0));
- Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 2));
- } else {
- Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 2));
- Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 1));
- }
- Value *Mask = ConstantVector::get(Idxs);
- SI = new ShuffleVectorInst(Op0, Op1, Mask, "upgraded.", CI);
- } else if (isMovL) {
- Constant *Zero = ConstantInt::get(Type::getInt32Ty(C), 0);
- Idxs.push_back(Zero);
- Idxs.push_back(Zero);
- Idxs.push_back(Zero);
- Idxs.push_back(Zero);
- Value *ZeroV = ConstantVector::get(Idxs);
-
- Idxs.clear();
- Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 4));
- Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 5));
- Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 2));
- Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 3));
- Value *Mask = ConstantVector::get(Idxs);
- SI = new ShuffleVectorInst(ZeroV, Op0, Mask, "upgraded.", CI);
- } else if (isMovSD ||
- isUnpckhPD || isUnpcklPD || isPunpckhQPD || isPunpcklQPD) {
- Value *Op1 = CI->getArgOperand(1);
- if (isMovSD) {
- Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 2));
- Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 1));
- } else if (isUnpckhPD || isPunpckhQPD) {
- Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 1));
- Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 3));
- } else {
- Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 0));
- Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 2));
- }
- Value *Mask = ConstantVector::get(Idxs);
- SI = new ShuffleVectorInst(Op0, Op1, Mask, "upgraded.", CI);
- } else if (isShufPD) {
- Value *Op1 = CI->getArgOperand(1);
- unsigned MaskVal =
- cast<ConstantInt>(CI->getArgOperand(2))->getZExtValue();
- Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), MaskVal & 1));
- Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C),
- ((MaskVal >> 1) & 1)+2));
- Value *Mask = ConstantVector::get(Idxs);
- SI = new ShuffleVectorInst(Op0, Op1, Mask, "upgraded.", CI);
- }
-
- assert(SI && "Unexpected!");
-
- // 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(SI);
-
- // Clean up the old call now that it has been completely upgraded.
- CI->eraseFromParent();
- } else if (F->getName() == "llvm.x86.sse41.pmulld") {
- // Upgrade this set of intrinsics into vector multiplies.
- Instruction *Mul = BinaryOperator::CreateMul(CI->getArgOperand(0),
- CI->getArgOperand(1),
- CI->getName(),
- CI);
- // Fix up all the uses with our new multiply.
- if (!CI->use_empty())
- CI->replaceAllUsesWith(Mul);
-
- // Remove upgraded multiply.
- CI->eraseFromParent();
- } else if (F->getName() == "llvm.x86.ssse3.palign.r") {
- Value *Op1 = CI->getArgOperand(0);
- Value *Op2 = CI->getArgOperand(1);
- Value *Op3 = CI->getArgOperand(2);
- unsigned shiftVal = cast<ConstantInt>(Op3)->getZExtValue();
- Value *Rep;
- IRBuilder<> Builder(C);
- Builder.SetInsertPoint(CI->getParent(), CI);
-
- // If palignr is shifting the pair of input vectors less than 9 bytes,
- // emit a shuffle instruction.
- if (shiftVal <= 8) {
- const Type *IntTy = Type::getInt32Ty(C);
- const Type *EltTy = Type::getInt8Ty(C);
- const Type *VecTy = VectorType::get(EltTy, 8);
-
- Op2 = Builder.CreateBitCast(Op2, VecTy);
- Op1 = Builder.CreateBitCast(Op1, VecTy);
-
- llvm::SmallVector<llvm::Constant*, 8> Indices;
- for (unsigned i = 0; i != 8; ++i)
- Indices.push_back(ConstantInt::get(IntTy, shiftVal + i));
-
- Value *SV = ConstantVector::get(Indices);
- Rep = Builder.CreateShuffleVector(Op2, Op1, SV, "palignr");
- Rep = Builder.CreateBitCast(Rep, F->getReturnType());
- }
-
- // If palignr is shifting the pair of input vectors more than 8 but less
- // than 16 bytes, emit a logical right shift of the destination.
- else if (shiftVal < 16) {
- // MMX has these as 1 x i64 vectors for some odd optimization reasons.
- const Type *EltTy = Type::getInt64Ty(C);
- const Type *VecTy = VectorType::get(EltTy, 1);
-
- Op1 = Builder.CreateBitCast(Op1, VecTy, "cast");
- Op2 = ConstantInt::get(VecTy, (shiftVal-8) * 8);
-
- // create i32 constant
- Function *I =
- Intrinsic::getDeclaration(F->getParent(), Intrinsic::x86_mmx_psrl_q);
- Rep = Builder.CreateCall2(I, Op1, Op2, "palignr");
- }
-
- // If palignr is shifting the pair of vectors more than 32 bytes, emit zero.
- else {
- Rep = Constant::getNullValue(F->getReturnType());
- }
-
- // Replace any uses with our new instruction.
- if (!CI->use_empty())
- CI->replaceAllUsesWith(Rep);
-
- // Remove upgraded instruction.
- CI->eraseFromParent();
-
- } else if (F->getName() == "llvm.x86.ssse3.palign.r.128") {
- Value *Op1 = CI->getArgOperand(0);
- Value *Op2 = CI->getArgOperand(1);
- Value *Op3 = CI->getArgOperand(2);
- unsigned shiftVal = cast<ConstantInt>(Op3)->getZExtValue();
- Value *Rep;
- IRBuilder<> Builder(C);
- Builder.SetInsertPoint(CI->getParent(), CI);
-
- // If palignr is shifting the pair of input vectors less than 17 bytes,
- // emit a shuffle instruction.
- if (shiftVal <= 16) {
- const Type *IntTy = Type::getInt32Ty(C);
- const Type *EltTy = Type::getInt8Ty(C);
- const Type *VecTy = VectorType::get(EltTy, 16);
-
- Op2 = Builder.CreateBitCast(Op2, VecTy);
- Op1 = Builder.CreateBitCast(Op1, VecTy);
-
- llvm::SmallVector<llvm::Constant*, 16> Indices;
- for (unsigned i = 0; i != 16; ++i)
- Indices.push_back(ConstantInt::get(IntTy, shiftVal + i));
-
- Value *SV = ConstantVector::get(Indices);
- Rep = Builder.CreateShuffleVector(Op2, Op1, SV, "palignr");
- Rep = Builder.CreateBitCast(Rep, F->getReturnType());
- }
-
- // If palignr is shifting the pair of input vectors more than 16 but less
- // than 32 bytes, emit a logical right shift of the destination.
- else if (shiftVal < 32) {
- const Type *EltTy = Type::getInt64Ty(C);
- const Type *VecTy = VectorType::get(EltTy, 2);
- const Type *IntTy = Type::getInt32Ty(C);
-
- Op1 = Builder.CreateBitCast(Op1, VecTy, "cast");
- Op2 = ConstantInt::get(IntTy, (shiftVal-16) * 8);
-
- // create i32 constant
- Function *I =
- Intrinsic::getDeclaration(F->getParent(), Intrinsic::x86_sse2_psrl_dq);
- Rep = Builder.CreateCall2(I, Op1, Op2, "palignr");
- }
-
- // If palignr is shifting the pair of vectors more than 32 bytes, emit zero.
- else {
- Rep = Constant::getNullValue(F->getReturnType());
- }
-
- // Replace any uses with our new instruction.
- if (!CI->use_empty())
- CI->replaceAllUsesWith(Rep);
-
- // Remove upgraded instruction.
- CI->eraseFromParent();
-
- } else if (F->getName() == "llvm.x86.sse.loadu.ps" ||
- F->getName() == "llvm.x86.sse2.loadu.dq" ||
- F->getName() == "llvm.x86.sse2.loadu.pd") {
+ 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);
@@ -1064,310 +189,6 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
}
switch (NewFn->getIntrinsicID()) {
- default: llvm_unreachable("Unknown function for CallInst upgrade.");
- case Intrinsic::arm_neon_vld1:
- case Intrinsic::arm_neon_vld2:
- case Intrinsic::arm_neon_vld3:
- case Intrinsic::arm_neon_vld4:
- case Intrinsic::arm_neon_vst1:
- case Intrinsic::arm_neon_vst2:
- case Intrinsic::arm_neon_vst3:
- case Intrinsic::arm_neon_vst4:
- case Intrinsic::arm_neon_vld2lane:
- case Intrinsic::arm_neon_vld3lane:
- case Intrinsic::arm_neon_vld4lane:
- case Intrinsic::arm_neon_vst2lane:
- case Intrinsic::arm_neon_vst3lane:
- case Intrinsic::arm_neon_vst4lane: {
- // Add a default alignment argument of 1.
- SmallVector<Value*, 8> Operands(CS.arg_begin(), CS.arg_end());
- Operands.push_back(ConstantInt::get(Type::getInt32Ty(C), 1));
- CallInst *NewCI = CallInst::Create(NewFn, Operands.begin(), Operands.end(),
- 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;
- }
-
- case Intrinsic::x86_mmx_padd_b:
- case Intrinsic::x86_mmx_padd_w:
- case Intrinsic::x86_mmx_padd_d:
- case Intrinsic::x86_mmx_padd_q:
- case Intrinsic::x86_mmx_padds_b:
- case Intrinsic::x86_mmx_padds_w:
- case Intrinsic::x86_mmx_paddus_b:
- case Intrinsic::x86_mmx_paddus_w:
- case Intrinsic::x86_mmx_psub_b:
- case Intrinsic::x86_mmx_psub_w:
- case Intrinsic::x86_mmx_psub_d:
- case Intrinsic::x86_mmx_psub_q:
- case Intrinsic::x86_mmx_psubs_b:
- case Intrinsic::x86_mmx_psubs_w:
- case Intrinsic::x86_mmx_psubus_b:
- case Intrinsic::x86_mmx_psubus_w:
- case Intrinsic::x86_mmx_pmulh_w:
- case Intrinsic::x86_mmx_pmull_w:
- case Intrinsic::x86_mmx_pmulhu_w:
- case Intrinsic::x86_mmx_pmulu_dq:
- case Intrinsic::x86_mmx_pmadd_wd:
- case Intrinsic::x86_mmx_pand:
- case Intrinsic::x86_mmx_pandn:
- case Intrinsic::x86_mmx_por:
- case Intrinsic::x86_mmx_pxor:
- case Intrinsic::x86_mmx_pavg_b:
- case Intrinsic::x86_mmx_pavg_w:
- case Intrinsic::x86_mmx_pmaxu_b:
- case Intrinsic::x86_mmx_pmaxs_w:
- case Intrinsic::x86_mmx_pminu_b:
- case Intrinsic::x86_mmx_pmins_w:
- case Intrinsic::x86_mmx_psad_bw:
- case Intrinsic::x86_mmx_psll_w:
- case Intrinsic::x86_mmx_psll_d:
- case Intrinsic::x86_mmx_psll_q:
- case Intrinsic::x86_mmx_pslli_w:
- case Intrinsic::x86_mmx_pslli_d:
- case Intrinsic::x86_mmx_pslli_q:
- case Intrinsic::x86_mmx_psrl_w:
- case Intrinsic::x86_mmx_psrl_d:
- case Intrinsic::x86_mmx_psrl_q:
- case Intrinsic::x86_mmx_psrli_w:
- case Intrinsic::x86_mmx_psrli_d:
- case Intrinsic::x86_mmx_psrli_q:
- case Intrinsic::x86_mmx_psra_w:
- case Intrinsic::x86_mmx_psra_d:
- case Intrinsic::x86_mmx_psrai_w:
- case Intrinsic::x86_mmx_psrai_d:
- case Intrinsic::x86_mmx_packsswb:
- case Intrinsic::x86_mmx_packssdw:
- case Intrinsic::x86_mmx_packuswb:
- case Intrinsic::x86_mmx_punpckhbw:
- case Intrinsic::x86_mmx_punpckhwd:
- case Intrinsic::x86_mmx_punpckhdq:
- case Intrinsic::x86_mmx_punpcklbw:
- case Intrinsic::x86_mmx_punpcklwd:
- case Intrinsic::x86_mmx_punpckldq:
- case Intrinsic::x86_mmx_pcmpeq_b:
- case Intrinsic::x86_mmx_pcmpeq_w:
- case Intrinsic::x86_mmx_pcmpeq_d:
- case Intrinsic::x86_mmx_pcmpgt_b:
- case Intrinsic::x86_mmx_pcmpgt_w:
- case Intrinsic::x86_mmx_pcmpgt_d: {
- Value *Operands[2];
-
- // Cast the operand to the X86 MMX type.
- Operands[0] = new BitCastInst(CI->getArgOperand(0),
- NewFn->getFunctionType()->getParamType(0),
- "upgraded.", CI);
-
- switch (NewFn->getIntrinsicID()) {
- default:
- // Cast to the X86 MMX type.
- Operands[1] = new BitCastInst(CI->getArgOperand(1),
- NewFn->getFunctionType()->getParamType(1),
- "upgraded.", CI);
- break;
- case Intrinsic::x86_mmx_pslli_w:
- case Intrinsic::x86_mmx_pslli_d:
- case Intrinsic::x86_mmx_pslli_q:
- case Intrinsic::x86_mmx_psrli_w:
- case Intrinsic::x86_mmx_psrli_d:
- case Intrinsic::x86_mmx_psrli_q:
- case Intrinsic::x86_mmx_psrai_w:
- case Intrinsic::x86_mmx_psrai_d:
- // These take an i32 as their second parameter.
- Operands[1] = CI->getArgOperand(1);
- break;
- }
-
- ConstructNewCallInst(NewFn, CI, Operands, 2);
- break;
- }
- case Intrinsic::x86_mmx_maskmovq: {
- Value *Operands[3];
-
- // Cast the operands to the X86 MMX type.
- Operands[0] = new BitCastInst(CI->getArgOperand(0),
- NewFn->getFunctionType()->getParamType(0),
- "upgraded.", CI);
- Operands[1] = new BitCastInst(CI->getArgOperand(1),
- NewFn->getFunctionType()->getParamType(1),
- "upgraded.", CI);
- Operands[2] = CI->getArgOperand(2);
-
- ConstructNewCallInst(NewFn, CI, Operands, 3, false);
- break;
- }
- case Intrinsic::x86_mmx_pmovmskb: {
- Value *Operands[1];
-
- // Cast the operand to the X86 MMX type.
- Operands[0] = new BitCastInst(CI->getArgOperand(0),
- NewFn->getFunctionType()->getParamType(0),
- "upgraded.", CI);
-
- ConstructNewCallInst(NewFn, CI, Operands, 1);
- break;
- }
- case Intrinsic::x86_mmx_movnt_dq: {
- Value *Operands[2];
-
- Operands[0] = CI->getArgOperand(0);
-
- // Cast the operand to the X86 MMX type.
- Operands[1] = new BitCastInst(CI->getArgOperand(1),
- NewFn->getFunctionType()->getParamType(1),
- "upgraded.", CI);
-
- ConstructNewCallInst(NewFn, CI, Operands, 2, false);
- break;
- }
- case Intrinsic::x86_mmx_palignr_b: {
- Value *Operands[3];
-
- // Cast the operands to the X86 MMX type.
- Operands[0] = new BitCastInst(CI->getArgOperand(0),
- NewFn->getFunctionType()->getParamType(0),
- "upgraded.", CI);
- Operands[1] = new BitCastInst(CI->getArgOperand(1),
- NewFn->getFunctionType()->getParamType(1),
- "upgraded.", CI);
- Operands[2] = CI->getArgOperand(2);
-
- ConstructNewCallInst(NewFn, CI, Operands, 3);
- break;
- }
- case Intrinsic::x86_mmx_pextr_w: {
- Value *Operands[2];
-
- // Cast the operands to the X86 MMX type.
- Operands[0] = new BitCastInst(CI->getArgOperand(0),
- NewFn->getFunctionType()->getParamType(0),
- "upgraded.", CI);
- Operands[1] = CI->getArgOperand(1);
-
- ConstructNewCallInst(NewFn, CI, Operands, 2);
- break;
- }
- case Intrinsic::x86_mmx_pinsr_w: {
- Value *Operands[3];
-
- // Cast the operands to the X86 MMX type.
- Operands[0] = new BitCastInst(CI->getArgOperand(0),
- NewFn->getFunctionType()->getParamType(0),
- "upgraded.", CI);
- Operands[1] = CI->getArgOperand(1);
- Operands[2] = CI->getArgOperand(2);
-
- ConstructNewCallInst(NewFn, CI, Operands, 3);
- break;
- }
- case Intrinsic::x86_sse_pshuf_w: {
- IRBuilder<> Builder(C);
- Builder.SetInsertPoint(CI->getParent(), CI);
-
- // Cast the operand to the X86 MMX type.
- Value *Operands[2];
- Operands[0] =
- Builder.CreateBitCast(CI->getArgOperand(0),
- NewFn->getFunctionType()->getParamType(0),
- "upgraded.");
- Operands[1] =
- Builder.CreateTrunc(CI->getArgOperand(1),
- Type::getInt8Ty(C),
- "upgraded.");
-
- ConstructNewCallInst(NewFn, CI, Operands, 2);
- break;
- }
-
- case Intrinsic::ctlz:
- case Intrinsic::ctpop:
- case Intrinsic::cttz: {
- // Build a small vector of the original arguments.
- SmallVector<Value*, 8> Operands(CS.arg_begin(), CS.arg_end());
-
- // Construct a new CallInst
- CallInst *NewCI = CallInst::Create(NewFn, Operands.begin(), Operands.end(),
- "upgraded."+CI->getName(), CI);
- NewCI->setTailCall(CI->isTailCall());
- NewCI->setCallingConv(CI->getCallingConv());
-
- // Handle any uses of the old CallInst.
- if (!CI->use_empty()) {
- // Check for sign extend parameter attributes on the return values.
- bool SrcSExt = NewFn->getAttributes().paramHasAttr(0, Attribute::SExt);
- bool DestSExt = F->getAttributes().paramHasAttr(0, Attribute::SExt);
-
- // Construct an appropriate cast from the new return type to the old.
- CastInst *RetCast = CastInst::Create(
- CastInst::getCastOpcode(NewCI, SrcSExt,
- F->getReturnType(),
- DestSExt),
- NewCI, F->getReturnType(),
- NewCI->getName(), CI);
- NewCI->moveBefore(RetCast);
-
- // Replace all uses of the old call with the new cast which has the
- // correct type.
- CI->replaceAllUsesWith(RetCast);
- }
-
- // Clean up the old call now that it has been completely upgraded.
- CI->eraseFromParent();
- }
- break;
- case Intrinsic::eh_selector:
- case Intrinsic::eh_typeid_for: {
- // Only the return type changed.
- SmallVector<Value*, 8> Operands(CS.arg_begin(), CS.arg_end());
- CallInst *NewCI = CallInst::Create(NewFn, Operands.begin(), Operands.end(),
- "upgraded." + CI->getName(), CI);
- NewCI->setTailCall(CI->isTailCall());
- NewCI->setCallingConv(CI->getCallingConv());
-
- // Handle any uses of the old CallInst.
- if (!CI->use_empty()) {
- // Construct an appropriate cast from the new return type to the old.
- CastInst *RetCast =
- CastInst::Create(CastInst::getCastOpcode(NewCI, true,
- F->getReturnType(), true),
- NewCI, F->getReturnType(), NewCI->getName(), CI);
- CI->replaceAllUsesWith(RetCast);
- }
- CI->eraseFromParent();
- }
- break;
- case Intrinsic::memcpy:
- case Intrinsic::memmove:
- case Intrinsic::memset: {
- // Add isVolatile
- const llvm::Type *I1Ty = llvm::Type::getInt1Ty(CI->getContext());
- Value *Operands[5] = { CI->getArgOperand(0), CI->getArgOperand(1),
- CI->getArgOperand(2), CI->getArgOperand(3),
- llvm::ConstantInt::get(I1Ty, 0) };
- CallInst *NewCI = CallInst::Create(NewFn, Operands, Operands+5,
- CI->getName(), CI);
- NewCI->setTailCall(CI->isTailCall());
- NewCI->setCallingConv(CI->getCallingConv());
- // Handle any uses of the old CallInst.
- if (!CI->use_empty())
- // Replace all uses of the old call with the new cast which has the
- // correct type.
- CI->replaceAllUsesWith(NewCI);
-
- // Clean up the old call now that it has been completely upgraded.
- CI->eraseFromParent();
- break;
- }
case Intrinsic::prefetch: {
IRBuilder<> Builder(C);
Builder.SetInsertPoint(CI->getParent(), CI);
@@ -1401,13 +222,13 @@ void llvm::UpgradeCallsToIntrinsic(Function* F) {
assert(F && "Illegal attempt to upgrade a non-existent intrinsic.");
// Upgrade the function and check if it is a totaly new function.
- Function* NewFn;
+ Function *NewFn;
if (UpgradeIntrinsicFunction(F, NewFn)) {
if (NewFn != F) {
// Replace all uses to the old function with the new one if necessary.
for (Value::use_iterator UI = F->use_begin(), UE = F->use_end();
UI != UE; ) {
- if (CallInst* CI = dyn_cast<CallInst>(*UI++))
+ if (CallInst *CI = dyn_cast<CallInst>(*UI++))
UpgradeIntrinsicCall(CI, NewFn);
}
// Remove old function, no longer used, from the module.
@@ -1420,37 +241,27 @@ void llvm::UpgradeCallsToIntrinsic(Function* F) {
/// If an llvm.dbg.declare intrinsic is invalid, then this function simply
/// strips that use.
void llvm::CheckDebugInfoIntrinsics(Module *M) {
-
-
if (Function *FuncStart = M->getFunction("llvm.dbg.func.start")) {
- while (!FuncStart->use_empty()) {
- CallInst *CI = cast<CallInst>(FuncStart->use_back());
- CI->eraseFromParent();
- }
+ while (!FuncStart->use_empty())
+ cast<CallInst>(FuncStart->use_back())->eraseFromParent();
FuncStart->eraseFromParent();
}
if (Function *StopPoint = M->getFunction("llvm.dbg.stoppoint")) {
- while (!StopPoint->use_empty()) {
- CallInst *CI = cast<CallInst>(StopPoint->use_back());
- CI->eraseFromParent();
- }
+ while (!StopPoint->use_empty())
+ cast<CallInst>(StopPoint->use_back())->eraseFromParent();
StopPoint->eraseFromParent();
}
if (Function *RegionStart = M->getFunction("llvm.dbg.region.start")) {
- while (!RegionStart->use_empty()) {
- CallInst *CI = cast<CallInst>(RegionStart->use_back());
- CI->eraseFromParent();
- }
+ while (!RegionStart->use_empty())
+ cast<CallInst>(RegionStart->use_back())->eraseFromParent();
RegionStart->eraseFromParent();
}
if (Function *RegionEnd = M->getFunction("llvm.dbg.region.end")) {
- while (!RegionEnd->use_empty()) {
- CallInst *CI = cast<CallInst>(RegionEnd->use_back());
- CI->eraseFromParent();
- }
+ while (!RegionEnd->use_empty())
+ cast<CallInst>(RegionEnd->use_back())->eraseFromParent();
RegionEnd->eraseFromParent();
}
diff --git a/lib/VMCore/BasicBlock.cpp b/lib/VMCore/BasicBlock.cpp
index 955a028..7d47044 100644
--- a/lib/VMCore/BasicBlock.cpp
+++ b/lib/VMCore/BasicBlock.cpp
@@ -227,8 +227,8 @@ void BasicBlock::removePredecessor(BasicBlock *Pred,
// If the PHI _HAD_ two uses, replace PHI node with its now *single* value
if (max_idx == 2) {
- if (PN->getOperand(0) != PN)
- PN->replaceAllUsesWith(PN->getOperand(0));
+ if (PN->getIncomingValue(0) != PN)
+ PN->replaceAllUsesWith(PN->getIncomingValue(0));
else
// We are left with an infinite loop with no entries: kill the PHI.
PN->replaceAllUsesWith(UndefValue::get(PN->getType()));
@@ -308,3 +308,19 @@ BasicBlock *BasicBlock::splitBasicBlock(iterator I, const Twine &BBName) {
return New;
}
+void BasicBlock::replaceSuccessorsPhiUsesWith(BasicBlock *New) {
+ TerminatorInst *TI = getTerminator();
+ if (!TI)
+ // Cope with being called on a BasicBlock that doesn't have a terminator
+ // yet. Clang's CodeGenFunction::EmitReturnBlock() likes to do this.
+ return;
+ for (unsigned i = 0, e = TI->getNumSuccessors(); i != e; ++i) {
+ BasicBlock *Succ = TI->getSuccessor(i);
+ for (iterator II = Succ->begin(); PHINode *PN = dyn_cast<PHINode>(II);
+ ++II) {
+ int i;
+ while ((i = PN->getBasicBlockIndex(this)) >= 0)
+ PN->setIncomingBlock(i, New);
+ }
+ }
+}
diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp
index 9985ada..579d356 100644
--- a/lib/VMCore/ConstantFold.cpp
+++ b/lib/VMCore/ConstantFold.cpp
@@ -559,7 +559,7 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, Constant *V,
for (unsigned i = 0, e = CV->getType()->getNumElements(); i != e; ++i)
res.push_back(ConstantExpr::getCast(opc,
CV->getOperand(i), DstEltTy));
- return ConstantVector::get(DestVecTy, res);
+ return ConstantVector::get(res);
}
// We actually have to do a cast now. Perform the cast according to the
@@ -942,7 +942,7 @@ Constant *llvm::ConstantFoldInsertValueInstruction(Constant *Agg,
}
if (const StructType* ST = dyn_cast<StructType>(AggTy))
- return ConstantStruct::get(ST->getContext(), Ops, ST->isPacked());
+ return ConstantStruct::get(ST, Ops);
return ConstantArray::get(cast<ArrayType>(AggTy), Ops);
}
@@ -973,7 +973,7 @@ Constant *llvm::ConstantFoldInsertValueInstruction(Constant *Agg,
}
if (const StructType *ST = dyn_cast<StructType>(AggTy))
- return ConstantStruct::get(ST->getContext(), Ops, ST->isPacked());
+ return ConstantStruct::get(ST, Ops);
return ConstantArray::get(cast<ArrayType>(AggTy), Ops);
}
@@ -988,7 +988,7 @@ Constant *llvm::ConstantFoldInsertValueInstruction(Constant *Agg,
}
if (const StructType* ST = dyn_cast<StructType>(Agg->getType()))
- return ConstantStruct::get(ST->getContext(), Ops, ST->isPacked());
+ return ConstantStruct::get(ST, Ops);
return ConstantArray::get(cast<ArrayType>(Agg->getType()), Ops);
}
diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp
index 15d7793..87f2fe6 100644
--- a/lib/VMCore/Constants.cpp
+++ b/lib/VMCore/Constants.cpp
@@ -571,8 +571,7 @@ ConstantArray::ConstantArray(const ArrayType *T,
}
}
-Constant *ConstantArray::get(const ArrayType *Ty,
- const std::vector<Constant*> &V) {
+Constant *ConstantArray::get(const ArrayType *Ty, ArrayRef<Constant*> V) {
for (unsigned i = 0, e = V.size(); i != e; ++i) {
assert(V[i]->getType() == Ty->getElementType() &&
"Wrong type in array element initializer");
@@ -592,13 +591,6 @@ Constant *ConstantArray::get(const ArrayType *Ty,
return ConstantAggregateZero::get(Ty);
}
-
-Constant *ConstantArray::get(const ArrayType* T, Constant *const* Vals,
- unsigned NumVals) {
- // FIXME: make this the primary ctor method.
- return get(T, std::vector<Constant*>(Vals, Vals+NumVals));
-}
-
/// ConstantArray::get(const string&) - Return an array that is initialized to
/// contain the specified string. If length is zero then a null terminator is
/// added to the specified string so that it may be used in a natural way.
@@ -621,6 +613,27 @@ Constant *ConstantArray::get(LLVMContext &Context, StringRef Str,
return get(ATy, ElementVals);
}
+/// getTypeForElements - Return an anonymous struct type to use for a constant
+/// with the specified set of elements. The list must not be empty.
+StructType *ConstantStruct::getTypeForElements(LLVMContext &Context,
+ ArrayRef<Constant*> V,
+ bool Packed) {
+ SmallVector<const Type*, 16> EltTypes;
+ for (unsigned i = 0, e = V.size(); i != e; ++i)
+ EltTypes.push_back(V[i]->getType());
+
+ return StructType::get(Context, EltTypes, Packed);
+}
+
+
+StructType *ConstantStruct::getTypeForElements(ArrayRef<Constant*> V,
+ bool Packed) {
+ assert(!V.empty() &&
+ "ConstantStruct::getTypeForElements cannot be called on empty list");
+ return getTypeForElements(V[0]->getContext(), V, Packed);
+}
+
+
ConstantStruct::ConstantStruct(const StructType *T,
const std::vector<Constant*> &V)
: Constant(T, ConstantStructVal,
@@ -639,45 +652,26 @@ ConstantStruct::ConstantStruct(const StructType *T,
}
// ConstantStruct accessors.
-Constant *ConstantStruct::get(const StructType* T,
- const std::vector<Constant*>& V) {
- LLVMContextImpl* pImpl = T->getContext().pImpl;
+Constant *ConstantStruct::get(const StructType *ST, ArrayRef<Constant*> V) {
+ assert(ST->getNumElements() == V.size() &&
+ "Incorrect # elements specified to ConstantStruct::get");
- // Create a ConstantAggregateZero value if all elements are zeros...
+ // Create a ConstantAggregateZero value if all elements are zeros.
for (unsigned i = 0, e = V.size(); i != e; ++i)
if (!V[i]->isNullValue())
- return pImpl->StructConstants.getOrCreate(T, V);
+ return ST->getContext().pImpl->StructConstants.getOrCreate(ST, V);
- return ConstantAggregateZero::get(T);
+ return ConstantAggregateZero::get(ST);
}
-Constant *ConstantStruct::get(LLVMContext &Context,
- const std::vector<Constant*>& V, bool packed) {
- std::vector<const Type*> StructEls;
- StructEls.reserve(V.size());
- for (unsigned i = 0, e = V.size(); i != e; ++i)
- StructEls.push_back(V[i]->getType());
- return get(StructType::get(Context, StructEls, packed), V);
-}
-
-Constant *ConstantStruct::get(LLVMContext &Context,
- Constant *const *Vals, unsigned NumVals,
- bool Packed) {
- // FIXME: make this the primary ctor method.
- return get(Context, std::vector<Constant*>(Vals, Vals+NumVals), Packed);
-}
-
-Constant* ConstantStruct::get(LLVMContext &Context, bool Packed,
- Constant * Val, ...) {
+Constant* ConstantStruct::get(const StructType *T, ...) {
va_list ap;
- std::vector<Constant*> Values;
- va_start(ap, Val);
- while (Val) {
+ SmallVector<Constant*, 8> Values;
+ va_start(ap, T);
+ while (Constant *Val = va_arg(ap, llvm::Constant*))
Values.push_back(Val);
- Val = va_arg(ap, llvm::Constant*);
- }
va_end(ap);
- return get(Context, Values, Packed);
+ return get(T, Values);
}
ConstantVector::ConstantVector(const VectorType *T,
@@ -696,9 +690,9 @@ ConstantVector::ConstantVector(const VectorType *T,
}
// ConstantVector accessors.
-Constant *ConstantVector::get(const VectorType *T,
- const std::vector<Constant*> &V) {
+Constant *ConstantVector::get(ArrayRef<Constant*> V) {
assert(!V.empty() && "Vectors can't be empty");
+ const VectorType *T = VectorType::get(V.front()->getType(), V.size());
LLVMContextImpl *pImpl = T->getContext().pImpl;
// If this is an all-undef or all-zero vector, return a
@@ -723,12 +717,6 @@ Constant *ConstantVector::get(const VectorType *T,
return pImpl->VectorConstants.getOrCreate(T, V);
}
-Constant *ConstantVector::get(ArrayRef<Constant*> V) {
- // FIXME: make this the primary ctor method.
- assert(!V.empty() && "Vectors cannot be empty");
- return get(VectorType::get(V.front()->getType(), V.size()), V.vec());
-}
-
// Utility function for determining if a ConstantExpr is a CastOp or not. This
// can't be inline because we don't want to #include Instruction.h into
// Constant.h
@@ -1537,8 +1525,8 @@ Constant *ConstantExpr::getSizeOf(const Type* Ty) {
Constant *ConstantExpr::getAlignOf(const Type* Ty) {
// alignof is implemented as: (i64) gep ({i1,Ty}*)null, 0, 1
// Note that a non-inbounds gep is used, as null isn't within any object.
- const Type *AligningTy = StructType::get(Ty->getContext(),
- Type::getInt1Ty(Ty->getContext()), Ty, NULL);
+ const Type *AligningTy =
+ StructType::get(Type::getInt1Ty(Ty->getContext()), Ty, NULL);
Constant *NullPtr = Constant::getNullValue(AligningTy->getPointerTo());
Constant *Zero = ConstantInt::get(Type::getInt64Ty(Ty->getContext()), 0);
Constant *One = ConstantInt::get(Type::getInt32Ty(Ty->getContext()), 1);
@@ -2116,7 +2104,7 @@ void ConstantVector::replaceUsesOfWithOnConstant(Value *From, Value *To,
Values.push_back(Val);
}
- Constant *Replacement = get(cast<VectorType>(getRawType()), Values);
+ Constant *Replacement = get(Values);
assert(Replacement != this && "I didn't contain From!");
// Everyone using this now uses the replacement.
diff --git a/lib/VMCore/ConstantsContext.h b/lib/VMCore/ConstantsContext.h
index 1395754..ea6ebe9 100644
--- a/lib/VMCore/ConstantsContext.h
+++ b/lib/VMCore/ConstantsContext.h
@@ -568,7 +568,7 @@ struct ConstantKeyData<InlineAsm> {
}
};
-template<class ValType, class TypeClass, class ConstantClass,
+template<class ValType, class ValRefType, class TypeClass, class ConstantClass,
bool HasLargeKey = false /*true for arrays and structs*/ >
class ConstantUniqueMap : public AbstractTypeUser {
public:
@@ -656,7 +656,7 @@ private:
}
}
- ConstantClass* Create(const TypeClass *Ty, const ValType &V,
+ ConstantClass* Create(const TypeClass *Ty, ValRefType V,
typename MapTy::iterator I) {
ConstantClass* Result =
ConstantCreator<ConstantClass,TypeClass,ValType>::create(Ty, V);
@@ -675,7 +675,7 @@ public:
/// getOrCreate - Return the specified constant from the map, creating it if
/// necessary.
- ConstantClass *getOrCreate(const TypeClass *Ty, const ValType &V) {
+ ConstantClass *getOrCreate(const TypeClass *Ty, ValRefType V) {
MapKey Lookup(Ty, V);
ConstantClass* Result = 0;
diff --git a/lib/VMCore/Core.cpp b/lib/VMCore/Core.cpp
index 92f9440..bdd988e 100644
--- a/lib/VMCore/Core.cpp
+++ b/lib/VMCore/Core.cpp
@@ -612,9 +612,10 @@ LLVMValueRef LLVMConstStringInContext(LLVMContextRef C, const char *Str,
LLVMValueRef LLVMConstStructInContext(LLVMContextRef C,
LLVMValueRef *ConstantVals,
unsigned Count, LLVMBool Packed) {
- return wrap(ConstantStruct::get(*unwrap(C),
- unwrap<Constant>(ConstantVals, Count),
- Count, Packed != 0));
+ Constant **Elements = unwrap<Constant>(ConstantVals, Count);
+ return wrap(ConstantStruct::getAnon(*unwrap(C),
+ ArrayRef<Constant*>(Elements, Count),
+ Packed != 0));
}
LLVMValueRef LLVMConstString(const char *Str, unsigned Length,
@@ -624,9 +625,8 @@ LLVMValueRef LLVMConstString(const char *Str, unsigned Length,
}
LLVMValueRef LLVMConstArray(LLVMTypeRef ElementTy,
LLVMValueRef *ConstantVals, unsigned Length) {
- return wrap(ConstantArray::get(ArrayType::get(unwrap(ElementTy), Length),
- unwrap<Constant>(ConstantVals, Length),
- Length));
+ ArrayRef<Constant*> V(unwrap<Constant>(ConstantVals, Length), Length);
+ return wrap(ConstantArray::get(ArrayType::get(unwrap(ElementTy), Length), V));
}
LLVMValueRef LLVMConstStruct(LLVMValueRef *ConstantVals, unsigned Count,
LLVMBool Packed) {
diff --git a/lib/VMCore/Function.cpp b/lib/VMCore/Function.cpp
index 0ae0bdb..b8fa60a 100644
--- a/lib/VMCore/Function.cpp
+++ b/lib/VMCore/Function.cpp
@@ -417,7 +417,7 @@ bool Function::hasAddressTaken(const User* *PutOffender) const {
/// setjmp or other function that gcc recognizes as "returning twice".
///
/// FIXME: Remove after <rdar://problem/8031714> is fixed.
-/// FIXME: Is the obove FIXME valid?
+/// FIXME: Is the above FIXME valid?
bool Function::callsFunctionThatReturnsTwice() const {
const Module *M = this->getParent();
static const char *ReturnsTwiceFns[] = {
diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp
index 8f4eabe..0eddd5a 100644
--- a/lib/VMCore/Instructions.cpp
+++ b/lib/VMCore/Instructions.cpp
@@ -87,11 +87,8 @@ PHINode::PHINode(const PHINode &PN)
: Instruction(PN.getType(), Instruction::PHI,
allocHungoffUses(PN.getNumOperands()), PN.getNumOperands()),
ReservedSpace(PN.getNumOperands()) {
- Use *OL = OperandList;
- for (unsigned i = 0, e = PN.getNumOperands(); i != e; i+=2) {
- OL[i] = PN.getOperand(i);
- OL[i+1] = PN.getOperand(i+1);
- }
+ std::copy(PN.op_begin(), PN.op_end(), op_begin());
+ std::copy(PN.block_begin(), PN.block_end(), block_begin());
SubclassOptionalData = PN.SubclassOptionalData;
}
@@ -99,31 +96,37 @@ PHINode::~PHINode() {
dropHungoffUses();
}
+Use *PHINode::allocHungoffUses(unsigned N) const {
+ // Allocate the array of Uses of the incoming values, followed by a pointer
+ // (with bottom bit set) to the User, followed by the array of pointers to
+ // the incoming basic blocks.
+ size_t size = N * sizeof(Use) + sizeof(Use::UserRef)
+ + N * sizeof(BasicBlock*);
+ Use *Begin = static_cast<Use*>(::operator new(size));
+ Use *End = Begin + N;
+ (void) new(End) Use::UserRef(const_cast<PHINode*>(this), 1);
+ return Use::initTags(Begin, End);
+}
+
// removeIncomingValue - Remove an incoming value. This is useful if a
// predecessor basic block is deleted.
Value *PHINode::removeIncomingValue(unsigned Idx, bool DeletePHIIfEmpty) {
- unsigned NumOps = getNumOperands();
- Use *OL = OperandList;
- assert(Idx*2 < NumOps && "BB not in PHI node!");
- Value *Removed = OL[Idx*2];
+ Value *Removed = getIncomingValue(Idx);
// Move everything after this operand down.
//
// FIXME: we could just swap with the end of the list, then erase. However,
- // client might not expect this to happen. The code as it is thrashes the
+ // clients might not expect this to happen. The code as it is thrashes the
// use/def lists, which is kinda lame.
- for (unsigned i = (Idx+1)*2; i != NumOps; i += 2) {
- OL[i-2] = OL[i];
- OL[i-2+1] = OL[i+1];
- }
+ std::copy(op_begin() + Idx + 1, op_end(), op_begin() + Idx);
+ std::copy(block_begin() + Idx + 1, block_end(), block_begin() + Idx);
// Nuke the last value.
- OL[NumOps-2].set(0);
- OL[NumOps-2+1].set(0);
- NumOperands = NumOps-2;
+ Op<-1>().set(0);
+ --NumOperands;
// If the PHI node is dead, because it has zero entries, nuke it now.
- if (NumOps == 2 && DeletePHIIfEmpty) {
+ if (getNumOperands() == 0 && DeletePHIIfEmpty) {
// If anyone is using this PHI, make them use a dummy value instead...
replaceAllUsesWith(UndefValue::get(getType()));
eraseFromParent();
@@ -137,15 +140,18 @@ Value *PHINode::removeIncomingValue(unsigned Idx, bool DeletePHIIfEmpty) {
///
void PHINode::growOperands() {
unsigned e = getNumOperands();
- // 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.
+ unsigned NumOps = e + e / 2;
+ if (NumOps < 2) NumOps = 2; // 2 op PHI nodes are VERY common.
+
+ Use *OldOps = op_begin();
+ BasicBlock **OldBlocks = block_begin();
ReservedSpace = NumOps;
- Use *OldOps = OperandList;
- Use *NewOps = allocHungoffUses(NumOps);
- std::copy(OldOps, OldOps + e, NewOps);
- OperandList = NewOps;
+ OperandList = allocHungoffUses(ReservedSpace);
+
+ std::copy(OldOps, OldOps + e, op_begin());
+ std::copy(OldBlocks, OldBlocks + e, block_begin());
+
Use::zap(OldOps, OldOps + e, true);
}
diff --git a/lib/VMCore/LLVMContextImpl.h b/lib/VMCore/LLVMContextImpl.h
index 6ea4b48e..d8808b0 100644
--- a/lib/VMCore/LLVMContextImpl.h
+++ b/lib/VMCore/LLVMContextImpl.h
@@ -22,10 +22,10 @@
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Metadata.h"
-#include "llvm/Assembly/Writer.h"
#include "llvm/Support/ValueHandle.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/SmallPtrSet.h"
@@ -139,27 +139,30 @@ public:
// on Context destruction.
SmallPtrSet<MDNode*, 1> NonUniquedMDNodes;
- ConstantUniqueMap<char, Type, ConstantAggregateZero> AggZeroConstants;
+ ConstantUniqueMap<char, char, Type, ConstantAggregateZero> AggZeroConstants;
- typedef ConstantUniqueMap<std::vector<Constant*>, ArrayType,
- ConstantArray, true /*largekey*/> ArrayConstantsTy;
+ typedef ConstantUniqueMap<std::vector<Constant*>, ArrayRef<Constant*>,
+ ArrayType, ConstantArray, true /*largekey*/> ArrayConstantsTy;
ArrayConstantsTy ArrayConstants;
- typedef ConstantUniqueMap<std::vector<Constant*>, StructType,
- ConstantStruct, true /*largekey*/> StructConstantsTy;
+ typedef ConstantUniqueMap<std::vector<Constant*>, ArrayRef<Constant*>,
+ StructType, ConstantStruct, true /*largekey*/> StructConstantsTy;
StructConstantsTy StructConstants;
- typedef ConstantUniqueMap<std::vector<Constant*>, VectorType,
- ConstantVector> VectorConstantsTy;
+ typedef ConstantUniqueMap<std::vector<Constant*>, ArrayRef<Constant*>,
+ VectorType, ConstantVector> VectorConstantsTy;
VectorConstantsTy VectorConstants;
- ConstantUniqueMap<char, PointerType, ConstantPointerNull> NullPtrConstants;
- ConstantUniqueMap<char, Type, UndefValue> UndefValueConstants;
+ ConstantUniqueMap<char, char, PointerType, ConstantPointerNull>
+ NullPtrConstants;
+ ConstantUniqueMap<char, char, Type, UndefValue> UndefValueConstants;
DenseMap<std::pair<Function*, BasicBlock*> , BlockAddress*> BlockAddresses;
- ConstantUniqueMap<ExprMapKeyType, Type, ConstantExpr> ExprConstants;
+ ConstantUniqueMap<ExprMapKeyType, const ExprMapKeyType&, Type, ConstantExpr>
+ ExprConstants;
- ConstantUniqueMap<InlineAsmKeyType, PointerType, InlineAsm> InlineAsms;
+ ConstantUniqueMap<InlineAsmKeyType, const InlineAsmKeyType&, PointerType,
+ InlineAsm> InlineAsms;
ConstantInt *TheTrueVal;
ConstantInt *TheFalseVal;
@@ -182,13 +185,6 @@ public:
const IntegerType Int32Ty;
const IntegerType Int64Ty;
- // 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 separate map to
- // make this easy.
- TypePrinting ConcreteTypeDescriptions;
- TypePrinting AbstractTypeDescriptions;
-
TypeMap<ArrayValType, ArrayType> ArrayTypes;
TypeMap<VectorValType, VectorType> VectorTypes;
TypeMap<PointerValType, PointerType> PointerTypes;
diff --git a/lib/VMCore/Type.cpp b/lib/VMCore/Type.cpp
index 566bb28..9299070 100644
--- a/lib/VMCore/Type.cpp
+++ b/lib/VMCore/Type.cpp
@@ -286,44 +286,41 @@ void Type::typeBecameConcrete(const DerivedType *AbsTy) {
llvm_unreachable("DerivedType is already a concrete type!");
}
-
-std::string Type::getDescription() const {
- LLVMContextImpl *pImpl = getContext().pImpl;
- TypePrinting &Map =
- isAbstract() ?
- pImpl->AbstractTypeDescriptions :
- pImpl->ConcreteTypeDescriptions;
-
- std::string DescStr;
- raw_string_ostream DescOS(DescStr);
- Map.print(this, DescOS);
- return DescOS.str();
-}
-
-
-bool StructType::indexValid(const Value *V) const {
- // Structure indexes require 32-bit integer constants.
- if (V->getType()->isIntegerTy(32))
- if (const ConstantInt *CU = dyn_cast<ConstantInt>(V))
- return indexValid(CU->getZExtValue());
- return false;
-}
-
-bool StructType::indexValid(unsigned V) const {
- return V < NumContainedTys;
+const Type *CompositeType::getTypeAtIndex(const Value *V) const {
+ if (const StructType *STy = dyn_cast<StructType>(this)) {
+ unsigned Idx = (unsigned)cast<ConstantInt>(V)->getZExtValue();
+ assert(indexValid(Idx) && "Invalid structure index!");
+ return STy->getElementType(Idx);
+ }
+
+ return cast<SequentialType>(this)->getElementType();
}
-
-// getTypeAtIndex - Given an index value into the type, return the type of the
-// element. For a structure type, this must be a constant value...
-//
-const Type *StructType::getTypeAtIndex(const Value *V) const {
- unsigned Idx = (unsigned)cast<ConstantInt>(V)->getZExtValue();
- return getTypeAtIndex(Idx);
+const Type *CompositeType::getTypeAtIndex(unsigned Idx) const {
+ if (const StructType *STy = dyn_cast<StructType>(this)) {
+ assert(indexValid(Idx) && "Invalid structure index!");
+ return STy->getElementType(Idx);
+ }
+
+ return cast<SequentialType>(this)->getElementType();
+}
+bool CompositeType::indexValid(const Value *V) const {
+ if (const StructType *STy = dyn_cast<StructType>(this)) {
+ // Structure indexes require 32-bit integer constants.
+ if (V->getType()->isIntegerTy(32))
+ if (const ConstantInt *CU = dyn_cast<ConstantInt>(V))
+ return CU->getZExtValue() < STy->getNumElements();
+ return false;
+ }
+
+ // Sequential types can be indexed by any integer.
+ return V->getType()->isIntegerTy();
}
-const Type *StructType::getTypeAtIndex(unsigned Idx) const {
- assert(indexValid(Idx) && "Invalid structure index!");
- return ContainedTys[Idx];
+bool CompositeType::indexValid(unsigned Idx) const {
+ if (const StructType *STy = dyn_cast<StructType>(this))
+ return Idx < STy->getNumElements();
+ // Sequential types can be indexed by any integer.
+ return true;
}
@@ -942,15 +939,17 @@ StructType *StructType::get(LLVMContext &Context,
return ST;
}
-StructType *StructType::get(LLVMContext &Context, const Type *type, ...) {
+StructType *StructType::get(const Type *type, ...) {
+ assert(type != 0 && "Cannot create a struct type with no elements with this");
+ LLVMContext &Ctx = type->getContext();
va_list ap;
- std::vector<const llvm::Type*> StructFields;
+ SmallVector<const llvm::Type*, 8> StructFields;
va_start(ap, type);
while (type) {
StructFields.push_back(type);
type = va_arg(ap, llvm::Type*);
}
- return llvm::StructType::get(Context, StructFields);
+ return llvm::StructType::get(Ctx, StructFields);
}
bool StructType::isValidElementType(const Type *ElemTy) {
@@ -1067,11 +1066,6 @@ void DerivedType::refineAbstractTypeTo(const Type *NewType) {
assert(this != NewType && "Can't refine to myself!");
assert(ForwardType == 0 && "This type has already been refined!");
- LLVMContextImpl *pImpl = getContext().pImpl;
-
- // The descriptions may be out of date. Conservatively clear them all!
- pImpl->AbstractTypeDescriptions.clear();
-
#ifdef DEBUG_MERGE_TYPES
DEBUG(dbgs() << "REFINING abstract type [" << (void*)this << " "
<< *this << "] to [" << (void*)NewType << " "
@@ -1221,12 +1215,6 @@ void PointerType::typeBecameConcrete(const DerivedType *AbsTy) {
pImpl->PointerTypes.TypeBecameConcrete(this, AbsTy);
}
-bool SequentialType::indexValid(const Value *V) const {
- if (V->getType()->isIntegerTy())
- return true;
- return false;
-}
-
namespace llvm {
raw_ostream &operator<<(raw_ostream &OS, const Type &T) {
T.print(OS);
diff --git a/lib/VMCore/TypeSymbolTable.cpp b/lib/VMCore/TypeSymbolTable.cpp
index d68a44b..80c6a74 100644
--- a/lib/VMCore/TypeSymbolTable.cpp
+++ b/lib/VMCore/TypeSymbolTable.cpp
@@ -59,7 +59,7 @@ Type* TypeSymbolTable::remove(iterator Entry) {
#if DEBUG_SYMBOL_TABLE
dump();
- dbgs() << " Removing Value: " << Result->getDescription() << "\n";
+ dbgs() << " Removing Value: " << *Result << "\n";
#endif
tmap.erase(Entry);
@@ -69,8 +69,7 @@ Type* TypeSymbolTable::remove(iterator Entry) {
if (Result->isAbstract()) {
#if DEBUG_ABSTYPE
dbgs() << "Removing abstract type from symtab"
- << Result->getDescription()
- << "\n";
+ << *Result << "\n";
#endif
cast<DerivedType>(Result)->removeAbstractTypeUser(this);
}
@@ -88,7 +87,7 @@ void TypeSymbolTable::insert(StringRef Name, const Type* T) {
#if DEBUG_SYMBOL_TABLE
dump();
- dbgs() << " Inserted type: " << Name << ": " << T->getDescription() << "\n";
+ dbgs() << " Inserted type: " << Name << ": " << *T << "\n";
#endif
} else {
// If there is a name conflict...
@@ -101,7 +100,7 @@ void TypeSymbolTable::insert(StringRef Name, const Type* T) {
#if DEBUG_SYMBOL_TABLE
dump();
dbgs() << " Inserting type: " << UniqueName << ": "
- << T->getDescription() << "\n";
+ << *T << "\n";
#endif
// Insert the tmap entry
@@ -112,7 +111,7 @@ void TypeSymbolTable::insert(StringRef Name, const Type* T) {
if (T->isAbstract()) {
cast<DerivedType>(T)->addAbstractTypeUser(this);
#if DEBUG_ABSTYPE
- dbgs() << "Added abstract type to ST: " << T->getDescription() << "\n";
+ dbgs() << "Added abstract type to ST: " << *T << "\n";
#endif
}
}
@@ -129,7 +128,7 @@ void TypeSymbolTable::refineAbstractType(const DerivedType *OldType,
// FIXME when Types aren't const.
if (I->second == const_cast<DerivedType *>(OldType)) {
#if DEBUG_ABSTYPE
- dbgs() << "Removing type " << OldType->getDescription() << "\n";
+ dbgs() << "Removing type " << *OldType << "\n";
#endif
OldType->removeAbstractTypeUser(this);
@@ -137,7 +136,7 @@ void TypeSymbolTable::refineAbstractType(const DerivedType *OldType,
I->second = const_cast<Type *>(NewType);
if (NewType->isAbstract()) {
#if DEBUG_ABSTYPE
- dbgs() << "Added type " << NewType->getDescription() << "\n";
+ dbgs() << "Added type " << *NewType << "\n";
#endif
cast<DerivedType>(NewType)->addAbstractTypeUser(this);
}
diff --git a/lib/VMCore/Use.cpp b/lib/VMCore/Use.cpp
index 2258b8d..359a151 100644
--- a/lib/VMCore/Use.cpp
+++ b/lib/VMCore/Use.cpp
@@ -135,11 +135,9 @@ void Use::zap(Use *Start, const Use *Stop, bool del) {
User *Use::getUser() const {
const Use *End = getImpliedUser();
- const PointerIntPair<User*, 1, unsigned>&
- ref(static_cast<const AugmentedUse*>(End - 1)->ref);
- User *She = ref.getPointer();
- return ref.getInt()
- ? She
+ const UserRef *ref = reinterpret_cast<const UserRef*>(End);
+ return ref->getInt()
+ ? ref->getPointer()
: (User*)End;
}
diff --git a/lib/VMCore/User.cpp b/lib/VMCore/User.cpp
index 2f4587d..f01fa34 100644
--- a/lib/VMCore/User.cpp
+++ b/lib/VMCore/User.cpp
@@ -40,14 +40,12 @@ void User::replaceUsesOfWith(Value *From, Value *To) {
//===----------------------------------------------------------------------===//
Use *User::allocHungoffUses(unsigned N) const {
- Use *Begin = static_cast<Use*>(::operator new(sizeof(Use) * N
- + sizeof(AugmentedUse)
- - sizeof(Use)));
+ // Allocate the array of Uses, followed by a pointer (with bottom bit set) to
+ // the User.
+ size_t size = N * sizeof(Use) + sizeof(Use::UserRef);
+ Use *Begin = static_cast<Use*>(::operator new(size));
Use *End = Begin + N;
- PointerIntPair<User*, 1, unsigned>&
- ref(static_cast<AugmentedUse&>(End[-1]).ref);
- ref.setPointer(const_cast<User*>(this));
- ref.setInt(1);
+ (void) new(End) Use::UserRef(const_cast<User*>(this), 1);
return Use::initTags(Begin, End);
}
diff --git a/lib/VMCore/Value.cpp b/lib/VMCore/Value.cpp
index 29f6a80..a03cddc 100644
--- a/lib/VMCore/Value.cpp
+++ b/lib/VMCore/Value.cpp
@@ -305,6 +305,9 @@ void Value::uncheckedReplaceAllUsesWith(Value *New) {
U.set(New);
}
+
+ if (BasicBlock *BB = dyn_cast<BasicBlock>(this))
+ BB->replaceSuccessorsPhiUsesWith(cast<BasicBlock>(New));
}
void Value::replaceAllUsesWith(Value *New) {
diff --git a/lib/VMCore/ValueSymbolTable.cpp b/lib/VMCore/ValueSymbolTable.cpp
index 254bf06..f1c9703 100644
--- a/lib/VMCore/ValueSymbolTable.cpp
+++ b/lib/VMCore/ValueSymbolTable.cpp
@@ -25,7 +25,7 @@ ValueSymbolTable::~ValueSymbolTable() {
#ifndef NDEBUG // Only do this in -g mode...
for (iterator VI = vmap.begin(), VE = vmap.end(); VI != VE; ++VI)
dbgs() << "Value still in symbol table! Type = '"
- << VI->getValue()->getType()->getDescription() << "' Name = '"
+ << *VI->getValue()->getType() << "' Name = '"
<< VI->getKeyData() << "'\n";
assert(vmap.empty() && "Values remain in symbol table!");
#endif
diff --git a/lib/VMCore/ValueTypes.cpp b/lib/VMCore/ValueTypes.cpp
index c054ae4..21a1f03 100644
--- a/lib/VMCore/ValueTypes.cpp
+++ b/lib/VMCore/ValueTypes.cpp
@@ -133,6 +133,7 @@ std::string EVT::getEVTString() const {
case MVT::v2f64: return "v2f64";
case MVT::v4f64: return "v4f64";
case MVT::Metadata:return "Metadata";
+ case MVT::untyped: return "untyped";
}
}
diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp
index 139e035..18de671 100644
--- a/lib/VMCore/Verifier.cpp
+++ b/lib/VMCore/Verifier.cpp
@@ -1139,9 +1139,6 @@ void Verifier::visitPHINode(PHINode &PN) {
for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) {
Assert1(PN.getType() == PN.getIncomingValue(i)->getType(),
"PHI node operands are not the same type as the result!", &PN);
- Assert1(isa<BasicBlock>(PN.getOperand(
- PHINode::getOperandNumForIncomingBlock(i))),
- "PHI node incoming block is not a BasicBlock!", &PN);
}
// All other PHI node constraints are checked in the visitBasicBlock method.
@@ -1482,8 +1479,10 @@ void Verifier::visitInstruction(Instruction &I) {
// PHI nodes differ from other nodes because they actually "use" the
// value in the predecessor basic blocks they correspond to.
BasicBlock *UseBlock = BB;
- if (isa<PHINode>(I))
- UseBlock = dyn_cast<BasicBlock>(I.getOperand(i+1));
+ if (PHINode *PN = dyn_cast<PHINode>(&I)) {
+ unsigned j = PHINode::getIncomingValueNumForOperand(i);
+ UseBlock = PN->getIncomingBlock(j);
+ }
Assert2(UseBlock, "Invoke operand is PHI node with bad incoming-BB",
Op, &I);
@@ -1515,10 +1514,11 @@ void Verifier::visitInstruction(Instruction &I) {
return;
}
}
- } else if (isa<PHINode>(I)) {
+ } else if (PHINode *PN = dyn_cast<PHINode>(&I)) {
// PHI nodes are more difficult than other nodes because they actually
// "use" the value in the predecessor basic blocks they correspond to.
- BasicBlock *PredBB = dyn_cast<BasicBlock>(I.getOperand(i+1));
+ unsigned j = PHINode::getIncomingValueNumForOperand(i);
+ BasicBlock *PredBB = PN->getIncomingBlock(j);
Assert2(PredBB && (DT->dominates(OpBlock, PredBB) ||
!DT->isReachableFromEntry(PredBB)),
"Instruction does not dominate all uses!", Op, &I);