aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm/lib/IR
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/IR')
-rw-r--r--contrib/llvm/lib/IR/AsmWriter.cpp407
-rw-r--r--contrib/llvm/lib/IR/AttributeImpl.h37
-rw-r--r--contrib/llvm/lib/IR/Attributes.cpp213
-rw-r--r--contrib/llvm/lib/IR/AttributesCompatFunc.td1
-rw-r--r--contrib/llvm/lib/IR/AutoUpgrade.cpp103
-rw-r--r--contrib/llvm/lib/IR/BasicBlock.cpp42
-rw-r--r--contrib/llvm/lib/IR/ConstantFold.cpp35
-rw-r--r--contrib/llvm/lib/IR/ConstantRange.cpp53
-rw-r--r--contrib/llvm/lib/IR/Constants.cpp326
-rw-r--r--contrib/llvm/lib/IR/ConstantsContext.h47
-rw-r--r--contrib/llvm/lib/IR/Core.cpp113
-rw-r--r--contrib/llvm/lib/IR/DIBuilder.cpp124
-rw-r--r--contrib/llvm/lib/IR/DataLayout.cpp13
-rw-r--r--contrib/llvm/lib/IR/DebugInfo.cpp55
-rw-r--r--contrib/llvm/lib/IR/DebugInfoMetadata.cpp90
-rw-r--r--contrib/llvm/lib/IR/DiagnosticInfo.cpp41
-rw-r--r--contrib/llvm/lib/IR/Dominators.cpp32
-rw-r--r--contrib/llvm/lib/IR/Function.cpp211
-rw-r--r--contrib/llvm/lib/IR/FunctionInfo.cpp67
-rw-r--r--contrib/llvm/lib/IR/GCOV.cpp4
-rw-r--r--contrib/llvm/lib/IR/Globals.cpp78
-rw-r--r--contrib/llvm/lib/IR/IRBuilder.cpp107
-rw-r--r--contrib/llvm/lib/IR/InlineAsm.cpp27
-rw-r--r--contrib/llvm/lib/IR/Instruction.cpp40
-rw-r--r--contrib/llvm/lib/IR/Instructions.cpp420
-rw-r--r--contrib/llvm/lib/IR/LLVMContext.cpp48
-rw-r--r--contrib/llvm/lib/IR/LLVMContextImpl.cpp24
-rw-r--r--contrib/llvm/lib/IR/LLVMContextImpl.h170
-rw-r--r--contrib/llvm/lib/IR/LegacyPassManager.cpp157
-rw-r--r--contrib/llvm/lib/IR/MDBuilder.cpp48
-rw-r--r--contrib/llvm/lib/IR/Metadata.cpp89
-rw-r--r--contrib/llvm/lib/IR/MetadataImpl.h13
-rw-r--r--contrib/llvm/lib/IR/MetadataTracking.cpp55
-rw-r--r--contrib/llvm/lib/IR/Module.cpp60
-rw-r--r--contrib/llvm/lib/IR/Statepoint.cpp5
-rw-r--r--contrib/llvm/lib/IR/SymbolTableListTraitsImpl.h50
-rw-r--r--contrib/llvm/lib/IR/Type.cpp154
-rw-r--r--contrib/llvm/lib/IR/TypeFinder.cpp14
-rw-r--r--contrib/llvm/lib/IR/User.cpp64
-rw-r--r--contrib/llvm/lib/IR/Value.cpp13
-rw-r--r--contrib/llvm/lib/IR/ValueSymbolTable.cpp50
-rw-r--r--contrib/llvm/lib/IR/ValueTypes.cpp27
-rw-r--r--contrib/llvm/lib/IR/Verifier.cpp682
43 files changed, 2855 insertions, 1554 deletions
diff --git a/contrib/llvm/lib/IR/AsmWriter.cpp b/contrib/llvm/lib/IR/AsmWriter.cpp
index b553f11018c7..185db47f07e5 100644
--- a/contrib/llvm/lib/IR/AsmWriter.cpp
+++ b/contrib/llvm/lib/IR/AsmWriter.cpp
@@ -39,6 +39,7 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/Format.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
@@ -102,17 +103,9 @@ static OrderMap orderModule(const Module *M) {
orderValue(&A, OM);
}
for (const Function &F : *M) {
- if (F.hasPrefixData())
- if (!isa<GlobalValue>(F.getPrefixData()))
- orderValue(F.getPrefixData(), OM);
-
- if (F.hasPrologueData())
- if (!isa<GlobalValue>(F.getPrologueData()))
- orderValue(F.getPrologueData(), OM);
-
- if (F.hasPersonalityFn())
- if (!isa<GlobalValue>(F.getPersonalityFn()))
- orderValue(F.getPersonalityFn(), OM);
+ for (const Use &U : F.operands())
+ if (!isa<GlobalValue>(U.get()))
+ orderValue(U.get(), OM);
orderValue(&F, OM);
@@ -232,8 +225,7 @@ static UseListOrderStack predictUseListOrder(const Module *M) {
// We want to visit the functions backward now so we can list function-local
// constants in the last Function they're used in. Module-level constants
// have already been visited above.
- for (auto I = M->rbegin(), E = M->rend(); I != E; ++I) {
- const Function &F = *I;
+ for (const Function &F : make_range(M->rbegin(), M->rend())) {
if (F.isDeclaration())
continue;
for (const BasicBlock &BB : F)
@@ -263,8 +255,8 @@ static UseListOrderStack predictUseListOrder(const Module *M) {
for (const GlobalAlias &A : M->aliases())
predictValueUseListOrder(A.getAliasee(), nullptr, OM, Stack);
for (const Function &F : *M)
- if (F.hasPrefixData())
- predictValueUseListOrder(F.getPrefixData(), nullptr, OM, Stack);
+ for (const Use &U : F.operands())
+ predictValueUseListOrder(U.get(), nullptr, OM, Stack);
return Stack;
}
@@ -304,6 +296,7 @@ static void PrintCallingConv(unsigned cc, raw_ostream &Out) {
case CallingConv::AnyReg: Out << "anyregcc"; break;
case CallingConv::PreserveMost: Out << "preserve_mostcc"; break;
case CallingConv::PreserveAll: Out << "preserve_allcc"; break;
+ case CallingConv::CXX_FAST_TLS: Out << "cxx_fast_tlscc"; break;
case CallingConv::GHC: Out << "ghccc"; break;
case CallingConv::X86_StdCall: Out << "x86_stdcallcc"; break;
case CallingConv::X86_FastCall: Out << "x86_fastcallcc"; break;
@@ -320,6 +313,9 @@ static void PrintCallingConv(unsigned cc, raw_ostream &Out) {
case CallingConv::X86_64_Win64: Out << "x86_64_win64cc"; break;
case CallingConv::SPIR_FUNC: Out << "spir_func"; break;
case CallingConv::SPIR_KERNEL: Out << "spir_kernel"; break;
+ case CallingConv::X86_INTR: Out << "x86_intrcc"; break;
+ case CallingConv::HHVM: Out << "hhvmcc"; break;
+ case CallingConv::HHVM_C: Out << "hhvm_ccc"; break;
}
}
@@ -343,18 +339,8 @@ enum PrefixType {
NoPrefix
};
-/// PrintLLVMName - Turn the specified name into an 'LLVM name', which is either
-/// 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) {
+void llvm::printLLVMNameWithoutPrefix(raw_ostream &OS, StringRef Name) {
assert(!Name.empty() && "Cannot get empty name!");
- switch (Prefix) {
- case NoPrefix: break;
- case GlobalPrefix: OS << '@'; break;
- case ComdatPrefix: OS << '$'; break;
- case LabelPrefix: break;
- case LocalPrefix: OS << '%'; break;
- }
// Scan the name to see if it needs quotes first.
bool NeedsQuotes = isdigit(static_cast<unsigned char>(Name[0]));
@@ -386,9 +372,31 @@ static void PrintLLVMName(raw_ostream &OS, StringRef Name, PrefixType Prefix) {
OS << '"';
}
-/// PrintLLVMName - Turn the specified name into an 'LLVM name', which is either
-/// prefixed with % (if the string only contains simple characters) or is
-/// surrounded with ""'s (if it has special chars in it). Print it out.
+/// Turn the specified name into an 'LLVM name', which is either 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) {
+ switch (Prefix) {
+ case NoPrefix:
+ break;
+ case GlobalPrefix:
+ OS << '@';
+ break;
+ case ComdatPrefix:
+ OS << '$';
+ break;
+ case LabelPrefix:
+ break;
+ case LocalPrefix:
+ OS << '%';
+ break;
+ }
+ printLLVMNameWithoutPrefix(OS, Name);
+}
+
+/// Turn the specified name into an 'LLVM name', which is either 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, const Value *V) {
PrintLLVMName(OS, V->getName(),
isa<GlobalValue>(V) ? GlobalPrefix : LocalPrefix);
@@ -456,6 +464,7 @@ void TypePrinting::print(Type *Ty, raw_ostream &OS) {
case Type::LabelTyID: OS << "label"; return;
case Type::MetadataTyID: OS << "metadata"; return;
case Type::X86_MMXTyID: OS << "x86_mmx"; return;
+ case Type::TokenTyID: OS << "token"; return;
case Type::IntegerTyID:
OS << 'i' << cast<IntegerType>(Ty)->getBitWidth();
return;
@@ -691,8 +700,9 @@ void ModuleSlotTracker::incorporateFunction(const Function &F) {
this->F = &F;
}
-static SlotTracker *createSlotTracker(const Module *M) {
- return new SlotTracker(M);
+int ModuleSlotTracker::getLocalSlot(const Value *V) {
+ assert(F && "No function incorporated");
+ return Machine->getLocalSlot(V);
}
static SlotTracker *createSlotTracker(const Value *V) {
@@ -802,7 +812,7 @@ void SlotTracker::processFunction() {
for(Function::const_arg_iterator AI = TheFunction->arg_begin(),
AE = TheFunction->arg_end(); AI != AE; ++AI)
if (!AI->hasName())
- CreateFunctionSlot(AI);
+ CreateFunctionSlot(&*AI);
ST_DEBUG("Inserting Instructions:\n");
@@ -1093,11 +1103,10 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV,
// the value back and get the same value.
//
bool ignored;
- bool isHalf = &CFP->getValueAPF().getSemantics()==&APFloat::IEEEhalf;
bool isDouble = &CFP->getValueAPF().getSemantics()==&APFloat::IEEEdouble;
bool isInf = CFP->getValueAPF().isInfinity();
bool isNaN = CFP->getValueAPF().isNaN();
- if (!isHalf && !isInf && !isNaN) {
+ if (!isInf && !isNaN) {
double Val = isDouble ? CFP->getValueAPF().convertToDouble() :
CFP->getValueAPF().convertToFloat();
SmallString<128> StrVal;
@@ -1123,15 +1132,12 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV,
// x86, so we must not use these types.
static_assert(sizeof(double) == sizeof(uint64_t),
"assuming that double is 64 bits!");
- char Buffer[40];
APFloat apf = CFP->getValueAPF();
- // Halves and floats are represented in ASCII IR as double, convert.
+ // Floats are represented in ASCII IR as double, convert.
if (!isDouble)
apf.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven,
&ignored);
- Out << "0x" <<
- utohex_buffer(uint64_t(apf.bitcastToAPInt().getZExtValue()),
- Buffer+40);
+ Out << format_hex(apf.bitcastToAPInt().getZExtValue(), 0, /*Upper=*/true);
return;
}
@@ -1139,60 +1145,32 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV,
// These appear as a magic letter identifying the type, then a
// fixed number of hex digits.
Out << "0x";
- // Bit position, in the current word, of the next nibble to print.
- int shiftcount;
-
+ APInt API = CFP->getValueAPF().bitcastToAPInt();
if (&CFP->getValueAPF().getSemantics() == &APFloat::x87DoubleExtended) {
Out << 'K';
- // api needed to prevent premature destruction
- APInt api = CFP->getValueAPF().bitcastToAPInt();
- const uint64_t* p = api.getRawData();
- uint64_t word = p[1];
- shiftcount = 12;
- int width = api.getBitWidth();
- for (int j=0; j<width; j+=4, shiftcount-=4) {
- unsigned int nibble = (word>>shiftcount) & 15;
- if (nibble < 10)
- Out << (unsigned char)(nibble + '0');
- else
- Out << (unsigned char)(nibble - 10 + 'A');
- if (shiftcount == 0 && j+4 < width) {
- word = *p;
- shiftcount = 64;
- if (width-j-4 < 64)
- shiftcount = width-j-4;
- }
- }
+ Out << format_hex_no_prefix(API.getHiBits(16).getZExtValue(), 4,
+ /*Upper=*/true);
+ Out << format_hex_no_prefix(API.getLoBits(64).getZExtValue(), 16,
+ /*Upper=*/true);
return;
} else if (&CFP->getValueAPF().getSemantics() == &APFloat::IEEEquad) {
- shiftcount = 60;
Out << 'L';
+ Out << format_hex_no_prefix(API.getLoBits(64).getZExtValue(), 16,
+ /*Upper=*/true);
+ Out << format_hex_no_prefix(API.getHiBits(64).getZExtValue(), 16,
+ /*Upper=*/true);
} else if (&CFP->getValueAPF().getSemantics() == &APFloat::PPCDoubleDouble) {
- shiftcount = 60;
Out << 'M';
+ Out << format_hex_no_prefix(API.getLoBits(64).getZExtValue(), 16,
+ /*Upper=*/true);
+ Out << format_hex_no_prefix(API.getHiBits(64).getZExtValue(), 16,
+ /*Upper=*/true);
} else if (&CFP->getValueAPF().getSemantics() == &APFloat::IEEEhalf) {
- shiftcount = 12;
Out << 'H';
+ Out << format_hex_no_prefix(API.getZExtValue(), 4,
+ /*Upper=*/true);
} else
llvm_unreachable("Unsupported floating point type");
- // api needed to prevent premature destruction
- APInt api = CFP->getValueAPF().bitcastToAPInt();
- const uint64_t* p = api.getRawData();
- uint64_t word = *p;
- int width = api.getBitWidth();
- for (int j=0; j<width; j+=4, shiftcount-=4) {
- unsigned int nibble = (word>>shiftcount) & 15;
- if (nibble < 10)
- Out << (unsigned char)(nibble + '0');
- else
- Out << (unsigned char)(nibble - 10 + 'A');
- if (shiftcount == 0 && j+4 < width) {
- word = *(++p);
- shiftcount = 64;
- if (width-j-4 < 64)
- shiftcount = width-j-4;
- }
- }
return;
}
@@ -1313,6 +1291,11 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV,
return;
}
+ if (isa<ConstantTokenNone>(CV)) {
+ Out << "none";
+ return;
+ }
+
if (isa<UndefValue>(CV)) {
Out << "undef";
return;
@@ -1326,10 +1309,7 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV,
Out << " (";
if (const GEPOperator *GEP = dyn_cast<GEPOperator>(CE)) {
- TypePrinter.print(
- cast<PointerType>(GEP->getPointerOperandType()->getScalarType())
- ->getElementType(),
- Out);
+ TypePrinter.print(GEP->getSourceElementType(), Out);
Out << ", ";
}
@@ -1409,6 +1389,7 @@ struct MDFieldPrinter {
: Out(Out), TypePrinter(TypePrinter), Machine(Machine), Context(Context) {
}
void printTag(const DINode *N);
+ void printMacinfoType(const DIMacroNode *N);
void printString(StringRef Name, StringRef Value,
bool ShouldSkipEmpty = true);
void printMetadata(StringRef Name, const Metadata *MD,
@@ -1431,6 +1412,14 @@ void MDFieldPrinter::printTag(const DINode *N) {
Out << N->getTag();
}
+void MDFieldPrinter::printMacinfoType(const DIMacroNode *N) {
+ Out << FS << "type: ";
+ if (const char *Type = dwarf::MacinfoString(N->getMacinfoType()))
+ Out << Type;
+ else
+ Out << N->getMacinfoType();
+}
+
void MDFieldPrinter::printString(StringRef Name, StringRef Value,
bool ShouldSkipEmpty) {
if (ShouldSkipEmpty && Value.empty())
@@ -1656,6 +1645,7 @@ static void writeDICompileUnit(raw_ostream &Out, const DICompileUnit *N,
Printer.printMetadata("subprograms", N->getRawSubprograms());
Printer.printMetadata("globals", N->getRawGlobalVariables());
Printer.printMetadata("imports", N->getRawImportedEntities());
+ Printer.printMetadata("macros", N->getRawMacros());
Printer.printInt("dwoId", N->getDWOId());
Out << ")";
}
@@ -1680,7 +1670,6 @@ static void writeDISubprogram(raw_ostream &Out, const DISubprogram *N,
Printer.printInt("virtualIndex", N->getVirtualIndex());
Printer.printDIFlags("flags", N->getFlags());
Printer.printBool("isOptimized", N->isOptimized());
- Printer.printMetadata("function", N->getRawFunction());
Printer.printMetadata("templateParams", N->getRawTemplateParams());
Printer.printMetadata("declaration", N->getRawDeclaration());
Printer.printMetadata("variables", N->getRawVariables());
@@ -1725,6 +1714,29 @@ static void writeDINamespace(raw_ostream &Out, const DINamespace *N,
Out << ")";
}
+static void writeDIMacro(raw_ostream &Out, const DIMacro *N,
+ TypePrinting *TypePrinter, SlotTracker *Machine,
+ const Module *Context) {
+ Out << "!DIMacro(";
+ MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ Printer.printMacinfoType(N);
+ Printer.printInt("line", N->getLine());
+ Printer.printString("name", N->getName());
+ Printer.printString("value", N->getValue());
+ Out << ")";
+}
+
+static void writeDIMacroFile(raw_ostream &Out, const DIMacroFile *N,
+ TypePrinting *TypePrinter, SlotTracker *Machine,
+ const Module *Context) {
+ Out << "!DIMacroFile(";
+ MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ Printer.printInt("line", N->getLine());
+ Printer.printMetadata("file", N->getRawFile(), /* ShouldSkipNull */ false);
+ Printer.printMetadata("nodes", N->getRawElements());
+ Out << ")";
+}
+
static void writeDIModule(raw_ostream &Out, const DIModule *N,
TypePrinting *TypePrinter, SlotTracker *Machine,
const Module *Context) {
@@ -1789,11 +1801,8 @@ static void writeDILocalVariable(raw_ostream &Out, const DILocalVariable *N,
SlotTracker *Machine, const Module *Context) {
Out << "!DILocalVariable(";
MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
- Printer.printTag(N);
Printer.printString("name", N->getName());
- Printer.printInt("arg", N->getArg(),
- /* ShouldSkipZero */
- N->getTag() == dwarf::DW_TAG_auto_variable);
+ Printer.printInt("arg", N->getArg());
Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
Printer.printMetadata("file", N->getRawFile());
Printer.printInt("line", N->getLine());
@@ -1998,6 +2007,7 @@ class AssemblyWriter {
TypePrinting TypePrinter;
AssemblyAnnotationWriter *AnnotationWriter;
SetVector<const Comdat *> Comdats;
+ bool IsForDebug;
bool ShouldPreserveUseListOrder;
UseListOrderStack UseListOrders;
SmallVector<StringRef, 8> MDNames;
@@ -2005,12 +2015,7 @@ class AssemblyWriter {
public:
/// Construct an AssemblyWriter with an external SlotTracker
AssemblyWriter(formatted_raw_ostream &o, SlotTracker &Mac, const Module *M,
- AssemblyAnnotationWriter *AAW,
- bool ShouldPreserveUseListOrder = false);
-
- /// Construct an AssemblyWriter with an internally allocated SlotTracker
- AssemblyWriter(formatted_raw_ostream &o, const Module *M,
- AssemblyAnnotationWriter *AAW,
+ AssemblyAnnotationWriter *AAW, bool IsForDebug,
bool ShouldPreserveUseListOrder = false);
void printMDNodeBody(const MDNode *MD);
@@ -2020,6 +2025,7 @@ public:
void writeOperand(const Value *Op, bool PrintType);
void writeParamOperand(const Value *Operand, AttributeSet Attrs,unsigned Idx);
+ void writeOperandBundles(ImmutableCallSite CS);
void writeAtomic(AtomicOrdering Ordering, SynchronizationScope SynchScope);
void writeAtomicCmpXchg(AtomicOrdering SuccessOrdering,
AtomicOrdering FailureOrdering,
@@ -2043,8 +2049,6 @@ public:
void printUseLists(const Function *F);
private:
- void init();
-
/// \brief Print out metadata attachments.
void printMetadataAttachments(
const SmallVectorImpl<std::pair<unsigned, MDNode *>> &MDs,
@@ -2060,7 +2064,12 @@ private:
};
} // namespace
-void AssemblyWriter::init() {
+AssemblyWriter::AssemblyWriter(formatted_raw_ostream &o, SlotTracker &Mac,
+ const Module *M, AssemblyAnnotationWriter *AAW,
+ bool IsForDebug, bool ShouldPreserveUseListOrder)
+ : Out(o), TheModule(M), Machine(Mac), AnnotationWriter(AAW),
+ IsForDebug(IsForDebug),
+ ShouldPreserveUseListOrder(ShouldPreserveUseListOrder) {
if (!TheModule)
return;
TypePrinter.incorporateTypes(*TheModule);
@@ -2072,23 +2081,6 @@ void AssemblyWriter::init() {
Comdats.insert(C);
}
-AssemblyWriter::AssemblyWriter(formatted_raw_ostream &o, SlotTracker &Mac,
- const Module *M, AssemblyAnnotationWriter *AAW,
- bool ShouldPreserveUseListOrder)
- : Out(o), TheModule(M), Machine(Mac), AnnotationWriter(AAW),
- ShouldPreserveUseListOrder(ShouldPreserveUseListOrder) {
- init();
-}
-
-AssemblyWriter::AssemblyWriter(formatted_raw_ostream &o, const Module *M,
- AssemblyAnnotationWriter *AAW,
- bool ShouldPreserveUseListOrder)
- : Out(o), TheModule(M), SlotTrackerStorage(createSlotTracker(M)),
- Machine(*SlotTrackerStorage), AnnotationWriter(AAW),
- ShouldPreserveUseListOrder(ShouldPreserveUseListOrder) {
- init();
-}
-
void AssemblyWriter::writeOperand(const Value *Operand, bool PrintType) {
if (!Operand) {
Out << "<null operand!>";
@@ -2170,6 +2162,43 @@ void AssemblyWriter::writeParamOperand(const Value *Operand,
WriteAsOperandInternal(Out, Operand, &TypePrinter, &Machine, TheModule);
}
+void AssemblyWriter::writeOperandBundles(ImmutableCallSite CS) {
+ if (!CS.hasOperandBundles())
+ return;
+
+ Out << " [ ";
+
+ bool FirstBundle = true;
+ for (unsigned i = 0, e = CS.getNumOperandBundles(); i != e; ++i) {
+ OperandBundleUse BU = CS.getOperandBundleAt(i);
+
+ if (!FirstBundle)
+ Out << ", ";
+ FirstBundle = false;
+
+ Out << '"';
+ PrintEscapedString(BU.getTagName(), Out);
+ Out << '"';
+
+ Out << '(';
+
+ bool FirstInput = true;
+ for (const auto &Input : BU.Inputs) {
+ if (!FirstInput)
+ Out << ", ";
+ FirstInput = false;
+
+ TypePrinter.print(Input->getType(), Out);
+ Out << " ";
+ WriteAsOperandInternal(Out, Input, &TypePrinter, &Machine, TheModule);
+ }
+
+ Out << ')';
+ }
+
+ Out << " ]";
+}
+
void AssemblyWriter::printModule(const Module *M) {
Machine.initialize();
@@ -2422,6 +2451,10 @@ void AssemblyWriter::printAlias(const GlobalAlias *GA) {
Out << "alias ";
+ TypePrinter.print(GA->getValueType(), Out);
+
+ Out << ", ";
+
const Constant *Aliasee = GA->getAliasee();
if (!Aliasee) {
@@ -2536,28 +2569,26 @@ void AssemblyWriter::printFunction(const Function *F) {
Machine.incorporateFunction(F);
// Loop over the arguments, printing them...
-
- unsigned Idx = 1;
- if (!F->isDeclaration()) {
- // If this isn't a declaration, print the argument names as well.
- for (Function::const_arg_iterator I = F->arg_begin(), E = F->arg_end();
- I != E; ++I) {
+ if (F->isDeclaration() && !IsForDebug) {
+ // We're only interested in the type here - don't print argument names.
+ for (unsigned I = 0, E = FT->getNumParams(); I != E; ++I) {
// Insert commas as we go... the first arg doesn't get a comma
- if (I != F->arg_begin()) Out << ", ";
- printArgument(I, Attrs, Idx);
- Idx++;
+ if (I)
+ Out << ", ";
+ // Output type...
+ TypePrinter.print(FT->getParamType(I), Out);
+
+ if (Attrs.hasAttributes(I + 1))
+ Out << ' ' << Attrs.getAsString(I + 1);
}
} else {
- // Otherwise, print the types from the function type.
- for (unsigned i = 0, e = FT->getNumParams(); i != e; ++i) {
+ // The arguments are meaningful here, print them in detail.
+ unsigned Idx = 1;
+ for (const Argument &Arg : F->args()) {
// Insert commas as we go... the first arg doesn't get a comma
- if (i) Out << ", ";
-
- // Output type...
- TypePrinter.print(FT->getParamType(i), Out);
-
- if (Attrs.hasAttributes(i+1))
- Out << ' ' << Attrs.getAsString(i+1);
+ if (Idx != 1)
+ Out << ", ";
+ printArgument(&Arg, Attrs, Idx++);
}
}
@@ -2604,7 +2635,7 @@ void AssemblyWriter::printFunction(const Function *F) {
Out << " {";
// Output all of the function's basic blocks.
for (Function::const_iterator I = F->begin(), E = F->end(); I != E; ++I)
- printBasicBlock(I);
+ printBasicBlock(&*I);
// Output the function's use-lists.
printUseLists(F);
@@ -2738,6 +2769,8 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
Out << "musttail ";
else if (CI->isTailCall())
Out << "tail ";
+ else if (CI->isNoTailCall())
+ Out << "notail ";
}
// Print out the opcode...
@@ -2850,8 +2883,50 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
writeOperand(LPI->getClause(i), true);
}
+ } else if (const auto *CatchSwitch = dyn_cast<CatchSwitchInst>(&I)) {
+ Out << " within ";
+ writeOperand(CatchSwitch->getParentPad(), /*PrintType=*/false);
+ Out << " [";
+ unsigned Op = 0;
+ for (const BasicBlock *PadBB : CatchSwitch->handlers()) {
+ if (Op > 0)
+ Out << ", ";
+ writeOperand(PadBB, /*PrintType=*/true);
+ ++Op;
+ }
+ Out << "] unwind ";
+ if (const BasicBlock *UnwindDest = CatchSwitch->getUnwindDest())
+ writeOperand(UnwindDest, /*PrintType=*/true);
+ else
+ Out << "to caller";
+ } else if (const auto *FPI = dyn_cast<FuncletPadInst>(&I)) {
+ Out << " within ";
+ writeOperand(FPI->getParentPad(), /*PrintType=*/false);
+ Out << " [";
+ for (unsigned Op = 0, NumOps = FPI->getNumArgOperands(); Op < NumOps;
+ ++Op) {
+ if (Op > 0)
+ Out << ", ";
+ writeOperand(FPI->getArgOperand(Op), /*PrintType=*/true);
+ }
+ Out << ']';
} else if (isa<ReturnInst>(I) && !Operand) {
Out << " void";
+ } else if (const auto *CRI = dyn_cast<CatchReturnInst>(&I)) {
+ Out << " from ";
+ writeOperand(CRI->getOperand(0), /*PrintType=*/false);
+
+ Out << " to ";
+ writeOperand(CRI->getOperand(1), /*PrintType=*/true);
+ } else if (const auto *CRI = dyn_cast<CleanupReturnInst>(&I)) {
+ Out << " from ";
+ writeOperand(CRI->getOperand(0), /*PrintType=*/false);
+
+ Out << " unwind ";
+ if (CRI->hasUnwindDest())
+ writeOperand(CRI->getOperand(1), /*PrintType=*/true);
+ else
+ Out << "to caller";
} else if (const CallInst *CI = dyn_cast<CallInst>(&I)) {
// Print the calling convention being used.
if (CI->getCallingConv() != CallingConv::C) {
@@ -2892,6 +2967,9 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
Out << ')';
if (PAL.hasAttributes(AttributeSet::FunctionIndex))
Out << " #" << Machine.getAttributeGroupSlot(PAL.getFnAttributes());
+
+ writeOperandBundles(CI);
+
} else if (const InvokeInst *II = dyn_cast<InvokeInst>(&I)) {
Operand = II->getCalledValue();
FunctionType *FTy = cast<FunctionType>(II->getFunctionType());
@@ -2926,6 +3004,8 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
if (PAL.hasAttributes(AttributeSet::FunctionIndex))
Out << " #" << Machine.getAttributeGroupSlot(PAL.getFnAttributes());
+ writeOperandBundles(II);
+
Out << "\n to ";
writeOperand(II->getNormalDest(), true);
Out << " unwind ";
@@ -3138,29 +3218,23 @@ void AssemblyWriter::printUseLists(const Function *F) {
// External Interface declarations
//===----------------------------------------------------------------------===//
-void Function::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW) const {
- SlotTracker SlotTable(this->getParent());
- formatted_raw_ostream OS(ROS);
- AssemblyWriter W(OS, SlotTable, this->getParent(), AAW);
- W.printFunction(this);
-}
-
void Module::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW,
- bool ShouldPreserveUseListOrder) const {
+ bool ShouldPreserveUseListOrder, bool IsForDebug) const {
SlotTracker SlotTable(this);
formatted_raw_ostream OS(ROS);
- AssemblyWriter W(OS, SlotTable, this, AAW, ShouldPreserveUseListOrder);
+ AssemblyWriter W(OS, SlotTable, this, AAW, IsForDebug,
+ ShouldPreserveUseListOrder);
W.printModule(this);
}
-void NamedMDNode::print(raw_ostream &ROS) const {
+void NamedMDNode::print(raw_ostream &ROS, bool IsForDebug) const {
SlotTracker SlotTable(getParent());
formatted_raw_ostream OS(ROS);
- AssemblyWriter W(OS, SlotTable, getParent(), nullptr);
+ AssemblyWriter W(OS, SlotTable, getParent(), nullptr, IsForDebug);
W.printNamedMDNode(this);
}
-void Comdat::print(raw_ostream &ROS) const {
+void Comdat::print(raw_ostream &ROS, bool /*IsForDebug*/) const {
PrintLLVMName(ROS, getName(), ComdatPrefix);
ROS << " = comdat ";
@@ -3185,7 +3259,7 @@ void Comdat::print(raw_ostream &ROS) const {
ROS << '\n';
}
-void Type::print(raw_ostream &OS) const {
+void Type::print(raw_ostream &OS, bool /*IsForDebug*/) const {
TypePrinting TP;
TP.print(const_cast<Type*>(this), OS);
@@ -3208,7 +3282,7 @@ static bool isReferencingMDNode(const Instruction &I) {
return false;
}
-void Value::print(raw_ostream &ROS) const {
+void Value::print(raw_ostream &ROS, bool IsForDebug) const {
bool ShouldInitializeAllMetadata = false;
if (auto *I = dyn_cast<Instruction>(this))
ShouldInitializeAllMetadata = isReferencingMDNode(*I);
@@ -3216,10 +3290,11 @@ void Value::print(raw_ostream &ROS) const {
ShouldInitializeAllMetadata = true;
ModuleSlotTracker MST(getModuleFromVal(this), ShouldInitializeAllMetadata);
- print(ROS, MST);
+ print(ROS, MST, IsForDebug);
}
-void Value::print(raw_ostream &ROS, ModuleSlotTracker &MST) const {
+void Value::print(raw_ostream &ROS, ModuleSlotTracker &MST,
+ bool IsForDebug) const {
formatted_raw_ostream OS(ROS);
SlotTracker EmptySlotTable(static_cast<const Module *>(nullptr));
SlotTracker &SlotTable =
@@ -3231,14 +3306,14 @@ void Value::print(raw_ostream &ROS, ModuleSlotTracker &MST) const {
if (const Instruction *I = dyn_cast<Instruction>(this)) {
incorporateFunction(I->getParent() ? I->getParent()->getParent() : nullptr);
- AssemblyWriter W(OS, SlotTable, getModuleFromVal(I), nullptr);
+ AssemblyWriter W(OS, SlotTable, getModuleFromVal(I), nullptr, IsForDebug);
W.printInstruction(*I);
} else if (const BasicBlock *BB = dyn_cast<BasicBlock>(this)) {
incorporateFunction(BB->getParent());
- AssemblyWriter W(OS, SlotTable, getModuleFromVal(BB), nullptr);
+ AssemblyWriter W(OS, SlotTable, getModuleFromVal(BB), nullptr, IsForDebug);
W.printBasicBlock(BB);
} else if (const GlobalValue *GV = dyn_cast<GlobalValue>(this)) {
- AssemblyWriter W(OS, SlotTable, GV->getParent(), nullptr);
+ AssemblyWriter W(OS, SlotTable, GV->getParent(), nullptr, IsForDebug);
if (const GlobalVariable *V = dyn_cast<GlobalVariable>(GV))
W.printGlobal(V);
else if (const Function *F = dyn_cast<Function>(GV))
@@ -3261,7 +3336,7 @@ void Value::print(raw_ostream &ROS, ModuleSlotTracker &MST) const {
/// Print without a type, skipping the TypePrinting object.
///
-/// \return \c true iff printing was succesful.
+/// \return \c true iff printing was successful.
static bool printWithoutType(const Value &V, raw_ostream &O,
SlotTracker *Machine, const Module *M) {
if (V.hasName() || isa<GlobalValue>(V) ||
@@ -3340,41 +3415,45 @@ void Metadata::printAsOperand(raw_ostream &OS, ModuleSlotTracker &MST,
printMetadataImpl(OS, *this, MST, M, /* OnlyAsOperand */ true);
}
-void Metadata::print(raw_ostream &OS, const Module *M) const {
+void Metadata::print(raw_ostream &OS, const Module *M,
+ bool /*IsForDebug*/) const {
ModuleSlotTracker MST(M, isa<MDNode>(this));
printMetadataImpl(OS, *this, MST, M, /* OnlyAsOperand */ false);
}
void Metadata::print(raw_ostream &OS, ModuleSlotTracker &MST,
- const Module *M) const {
+ const Module *M, bool /*IsForDebug*/) const {
printMetadataImpl(OS, *this, MST, M, /* OnlyAsOperand */ false);
}
// Value::dump - allow easy printing of Values from the debugger.
LLVM_DUMP_METHOD
-void Value::dump() const { print(dbgs()); dbgs() << '\n'; }
+void Value::dump() const { print(dbgs(), /*IsForDebug=*/true); dbgs() << '\n'; }
// Type::dump - allow easy printing of Types from the debugger.
LLVM_DUMP_METHOD
-void Type::dump() const { print(dbgs()); dbgs() << '\n'; }
+void Type::dump() const { print(dbgs(), /*IsForDebug=*/true); dbgs() << '\n'; }
// Module::dump() - Allow printing of Modules from the debugger.
LLVM_DUMP_METHOD
-void Module::dump() const { print(dbgs(), nullptr); }
+void Module::dump() const {
+ print(dbgs(), nullptr,
+ /*ShouldPreserveUseListOrder=*/false, /*IsForDebug=*/true);
+}
// \brief Allow printing of Comdats from the debugger.
LLVM_DUMP_METHOD
-void Comdat::dump() const { print(dbgs()); }
+void Comdat::dump() const { print(dbgs(), /*IsForDebug=*/true); }
// NamedMDNode::dump() - Allow printing of NamedMDNodes from the debugger.
LLVM_DUMP_METHOD
-void NamedMDNode::dump() const { print(dbgs()); }
+void NamedMDNode::dump() const { print(dbgs(), /*IsForDebug=*/true); }
LLVM_DUMP_METHOD
void Metadata::dump() const { dump(nullptr); }
LLVM_DUMP_METHOD
void Metadata::dump(const Module *M) const {
- print(dbgs(), M);
+ print(dbgs(), M, /*IsForDebug=*/true);
dbgs() << '\n';
}
diff --git a/contrib/llvm/lib/IR/AttributeImpl.h b/contrib/llvm/lib/IR/AttributeImpl.h
index 6f338ae835fa..659f9568b7c6 100644
--- a/contrib/llvm/lib/IR/AttributeImpl.h
+++ b/contrib/llvm/lib/IR/AttributeImpl.h
@@ -18,6 +18,7 @@
#include "llvm/ADT/FoldingSet.h"
#include "llvm/IR/Attributes.h"
+#include "llvm/Support/TrailingObjects.h"
#include <string>
namespace llvm {
@@ -141,13 +142,16 @@ public:
/// \class
/// \brief This class represents a group of attributes that apply to one
/// element: function, return type, or parameter.
-class AttributeSetNode : public FoldingSetNode {
+class AttributeSetNode final
+ : public FoldingSetNode,
+ private TrailingObjects<AttributeSetNode, Attribute> {
+ friend TrailingObjects;
+
unsigned NumAttrs; ///< Number of attributes in this node.
AttributeSetNode(ArrayRef<Attribute> Attrs) : NumAttrs(Attrs.size()) {
// There's memory after the node where we can store the entries in.
- std::copy(Attrs.begin(), Attrs.end(),
- reinterpret_cast<Attribute *>(this + 1));
+ std::copy(Attrs.begin(), Attrs.end(), getTrailingObjects<Attribute>());
}
// AttributesSetNode is uniqued, these should not be publicly available.
@@ -170,7 +174,7 @@ public:
std::string getAsString(bool InAttrGrp) const;
typedef const Attribute *iterator;
- iterator begin() const { return reinterpret_cast<iterator>(this + 1); }
+ iterator begin() const { return getTrailingObjects<Attribute>(); }
iterator end() const { return begin() + NumAttrs; }
void Profile(FoldingSetNodeID &ID) const {
@@ -181,27 +185,29 @@ public:
AttrList[I].Profile(ID);
}
};
-static_assert(
- AlignOf<AttributeSetNode>::Alignment >= AlignOf<Attribute>::Alignment,
- "Alignment is insufficient for objects appended to AttributeSetNode");
+
+typedef std::pair<unsigned, AttributeSetNode *> IndexAttrPair;
//===----------------------------------------------------------------------===//
/// \class
/// \brief This class represents a set of attributes that apply to the function,
/// return type, and parameters.
-class AttributeSetImpl : public FoldingSetNode {
+class AttributeSetImpl final
+ : public FoldingSetNode,
+ private TrailingObjects<AttributeSetImpl, IndexAttrPair> {
friend class AttributeSet;
-
-public:
- typedef std::pair<unsigned, AttributeSetNode*> IndexAttrPair;
+ friend TrailingObjects;
private:
LLVMContext &Context;
unsigned NumAttrs; ///< Number of entries in this set.
+ // Helper fn for TrailingObjects class.
+ size_t numTrailingObjects(OverloadToken<IndexAttrPair>) { return NumAttrs; }
+
/// \brief Return a pointer to the IndexAttrPair for the specified slot.
const IndexAttrPair *getNode(unsigned Slot) const {
- return reinterpret_cast<const IndexAttrPair *>(this + 1) + Slot;
+ return getTrailingObjects<IndexAttrPair>() + Slot;
}
// AttributesSet is uniqued, these should not be publicly available.
@@ -222,8 +228,7 @@ public:
}
#endif
// There's memory after the node where we can store the entries in.
- std::copy(Attrs.begin(), Attrs.end(),
- reinterpret_cast<IndexAttrPair *>(this + 1));
+ std::copy(Attrs.begin(), Attrs.end(), getTrailingObjects<IndexAttrPair>());
}
/// \brief Get the context that created this AttributeSetImpl.
@@ -273,10 +278,6 @@ public:
void dump() const;
};
-static_assert(
- AlignOf<AttributeSetImpl>::Alignment >=
- AlignOf<AttributeSetImpl::IndexAttrPair>::Alignment,
- "Alignment is insufficient for objects appended to AttributeSetImpl");
} // end llvm namespace
diff --git a/contrib/llvm/lib/IR/Attributes.cpp b/contrib/llvm/lib/IR/Attributes.cpp
index 546a98670a29..bcf7dc365ce5 100644
--- a/contrib/llvm/lib/IR/Attributes.cpp
+++ b/contrib/llvm/lib/IR/Attributes.cpp
@@ -14,6 +14,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/IR/Attributes.h"
+#include "llvm/IR/Function.h"
#include "AttributeImpl.h"
#include "LLVMContextImpl.h"
#include "llvm/ADT/STLExtras.h"
@@ -120,28 +121,28 @@ Attribute::AttrKind Attribute::getKindAsEnum() const {
if (!pImpl) return None;
assert((isEnumAttribute() || isIntAttribute()) &&
"Invalid attribute type to get the kind as an enum!");
- return pImpl ? pImpl->getKindAsEnum() : None;
+ return pImpl->getKindAsEnum();
}
uint64_t Attribute::getValueAsInt() const {
if (!pImpl) return 0;
assert(isIntAttribute() &&
"Expected the attribute to be an integer attribute!");
- return pImpl ? pImpl->getValueAsInt() : 0;
+ return pImpl->getValueAsInt();
}
StringRef Attribute::getKindAsString() const {
if (!pImpl) return StringRef();
assert(isStringAttribute() &&
"Invalid attribute type to get the kind as a string!");
- return pImpl ? pImpl->getKindAsString() : StringRef();
+ return pImpl->getKindAsString();
}
StringRef Attribute::getValueAsString() const {
if (!pImpl) return StringRef();
assert(isStringAttribute() &&
"Invalid attribute type to get the value as a string!");
- return pImpl ? pImpl->getValueAsString() : StringRef();
+ return pImpl->getValueAsString();
}
bool Attribute::hasAttribute(AttrKind Kind) const {
@@ -198,6 +199,10 @@ std::string Attribute::getAsString(bool InAttrGrp) const {
return "byval";
if (hasAttribute(Attribute::Convergent))
return "convergent";
+ if (hasAttribute(Attribute::InaccessibleMemOnly))
+ return "inaccessiblememonly";
+ if (hasAttribute(Attribute::InaccessibleMemOrArgMemOnly))
+ return "inaccessiblemem_or_argmemonly";
if (hasAttribute(Attribute::InAlloca))
return "inalloca";
if (hasAttribute(Attribute::InlineHint))
@@ -232,6 +237,8 @@ std::string Attribute::getAsString(bool InAttrGrp) const {
return "noredzone";
if (hasAttribute(Attribute::NoReturn))
return "noreturn";
+ if (hasAttribute(Attribute::NoRecurse))
+ return "norecurse";
if (hasAttribute(Attribute::NoUnwind))
return "nounwind";
if (hasAttribute(Attribute::OptimizeNone))
@@ -442,6 +449,9 @@ uint64_t AttributeImpl::getAttrMask(Attribute::AttrKind Val) {
case Attribute::JumpTable: return 1ULL << 45;
case Attribute::Convergent: return 1ULL << 46;
case Attribute::SafeStack: return 1ULL << 47;
+ case Attribute::NoRecurse: return 1ULL << 48;
+ case Attribute::InaccessibleMemOnly: return 1ULL << 49;
+ case Attribute::InaccessibleMemOrArgMemOnly: return 1ULL << 50;
case Attribute::Dereferenceable:
llvm_unreachable("dereferenceable attribute not supported in raw format");
break;
@@ -472,9 +482,8 @@ AttributeSetNode *AttributeSetNode::get(LLVMContext &C,
SmallVector<Attribute, 8> SortedAttrs(Attrs.begin(), Attrs.end());
array_pod_sort(SortedAttrs.begin(), SortedAttrs.end());
- for (SmallVectorImpl<Attribute>::iterator I = SortedAttrs.begin(),
- E = SortedAttrs.end(); I != E; ++I)
- I->Profile(ID);
+ for (Attribute Attr : SortedAttrs)
+ Attr.Profile(ID);
void *InsertPoint;
AttributeSetNode *PA =
@@ -484,8 +493,7 @@ AttributeSetNode *AttributeSetNode::get(LLVMContext &C,
// new one and insert it.
if (!PA) {
// Coallocate entries after the AttributeSetNode itself.
- void *Mem = ::operator new(sizeof(AttributeSetNode) +
- sizeof(Attribute) * SortedAttrs.size());
+ void *Mem = ::operator new(totalSizeToAlloc<Attribute>(SortedAttrs.size()));
PA = new (Mem) AttributeSetNode(SortedAttrs);
pImpl->AttrsSetNodes.InsertNode(PA, InsertPoint);
}
@@ -617,9 +625,8 @@ AttributeSet::getImpl(LLVMContext &C,
// create a new one and insert it.
if (!PA) {
// Coallocate entries after the AttributeSetImpl itself.
- void *Mem = ::operator new(sizeof(AttributeSetImpl) +
- sizeof(std::pair<unsigned, AttributeSetNode *>) *
- Attrs.size());
+ void *Mem = ::operator new(
+ AttributeSetImpl::totalSizeToAlloc<IndexAttrPair>(Attrs.size()));
PA = new (Mem) AttributeSetImpl(C, Attrs);
pImpl->AttrsLists.InsertNode(PA, InsertPoint);
}
@@ -684,22 +691,26 @@ AttributeSet AttributeSet::get(LLVMContext &C, unsigned Index,
if (!B.contains(Kind))
continue;
- if (Kind == Attribute::Alignment)
- Attrs.push_back(std::make_pair(Index, Attribute::
- getWithAlignment(C, B.getAlignment())));
- else if (Kind == Attribute::StackAlignment)
- Attrs.push_back(std::make_pair(Index, Attribute::
- getWithStackAlignment(C, B.getStackAlignment())));
- else if (Kind == Attribute::Dereferenceable)
- Attrs.push_back(std::make_pair(Index,
- Attribute::getWithDereferenceableBytes(C,
- B.getDereferenceableBytes())));
- else if (Kind == Attribute::DereferenceableOrNull)
- Attrs.push_back(
- std::make_pair(Index, Attribute::getWithDereferenceableOrNullBytes(
- C, B.getDereferenceableOrNullBytes())));
- else
- Attrs.push_back(std::make_pair(Index, Attribute::get(C, Kind)));
+ Attribute Attr;
+ switch (Kind) {
+ case Attribute::Alignment:
+ Attr = Attribute::getWithAlignment(C, B.getAlignment());
+ break;
+ case Attribute::StackAlignment:
+ Attr = Attribute::getWithStackAlignment(C, B.getStackAlignment());
+ break;
+ case Attribute::Dereferenceable:
+ Attr = Attribute::getWithDereferenceableBytes(
+ C, B.getDereferenceableBytes());
+ break;
+ case Attribute::DereferenceableOrNull:
+ Attr = Attribute::getWithDereferenceableOrNullBytes(
+ C, B.getDereferenceableOrNullBytes());
+ break;
+ default:
+ Attr = Attribute::get(C, Kind);
+ }
+ Attrs.push_back(std::make_pair(Index, Attr));
}
// Add target-dependent (string) attributes.
@@ -713,9 +724,8 @@ AttributeSet AttributeSet::get(LLVMContext &C, unsigned Index,
AttributeSet AttributeSet::get(LLVMContext &C, unsigned Index,
ArrayRef<Attribute::AttrKind> Kind) {
SmallVector<std::pair<unsigned, Attribute>, 8> Attrs;
- for (ArrayRef<Attribute::AttrKind>::iterator I = Kind.begin(),
- E = Kind.end(); I != E; ++I)
- Attrs.push_back(std::make_pair(Index, Attribute::get(C, *I)));
+ for (Attribute::AttrKind K : Kind)
+ Attrs.push_back(std::make_pair(Index, Attribute::get(C, K)));
return get(C, Attrs);
}
@@ -736,9 +746,8 @@ AttributeSet AttributeSet::get(LLVMContext &C, ArrayRef<AttributeSet> Attrs) {
if (!AS) continue;
SmallVector<std::pair<unsigned, AttributeSetNode *>, 8>::iterator
ANVI = AttrNodeVec.begin(), ANVE;
- for (const AttributeSetImpl::IndexAttrPair
- *AI = AS->getNode(0),
- *AE = AS->getNode(AS->getNumAttributes());
+ for (const IndexAttrPair *AI = AS->getNode(0),
+ *AE = AS->getNode(AS->getNumAttributes());
AI != AE; ++AI) {
ANVE = AttrNodeVec.end();
while (ANVI != ANVE && ANVI->first <= AI->first)
@@ -770,6 +779,36 @@ AttributeSet AttributeSet::addAttribute(LLVMContext &C, unsigned Index,
return addAttributes(C, Index, AttributeSet::get(C, Index, B));
}
+AttributeSet AttributeSet::addAttribute(LLVMContext &C,
+ ArrayRef<unsigned> Indices,
+ Attribute A) const {
+ unsigned I = 0, E = pImpl ? pImpl->getNumAttributes() : 0;
+ auto IdxI = Indices.begin(), IdxE = Indices.end();
+ SmallVector<AttributeSet, 4> AttrSet;
+
+ while (I != E && IdxI != IdxE) {
+ if (getSlotIndex(I) < *IdxI)
+ AttrSet.emplace_back(getSlotAttributes(I++));
+ else if (getSlotIndex(I) > *IdxI)
+ AttrSet.emplace_back(AttributeSet::get(C, std::make_pair(*IdxI++, A)));
+ else {
+ AttrBuilder B(getSlotAttributes(I), *IdxI);
+ B.addAttribute(A);
+ AttrSet.emplace_back(AttributeSet::get(C, *IdxI, B));
+ ++I;
+ ++IdxI;
+ }
+ }
+
+ while (I != E)
+ AttrSet.emplace_back(getSlotAttributes(I++));
+
+ while (IdxI != IdxE)
+ AttrSet.emplace_back(AttributeSet::get(C, std::make_pair(*IdxI++, A)));
+
+ return get(C, AttrSet);
+}
+
AttributeSet AttributeSet::addAttributes(LLVMContext &C, unsigned Index,
AttributeSet Attrs) const {
if (!pImpl) return Attrs;
@@ -955,17 +994,17 @@ AttributeSet AttributeSet::getFnAttributes() const {
bool AttributeSet::hasAttribute(unsigned Index, Attribute::AttrKind Kind) const{
AttributeSetNode *ASN = getAttributes(Index);
- return ASN ? ASN->hasAttribute(Kind) : false;
+ return ASN && ASN->hasAttribute(Kind);
}
bool AttributeSet::hasAttribute(unsigned Index, StringRef Kind) const {
AttributeSetNode *ASN = getAttributes(Index);
- return ASN ? ASN->hasAttribute(Kind) : false;
+ return ASN && ASN->hasAttribute(Kind);
}
bool AttributeSet::hasAttributes(unsigned Index) const {
AttributeSetNode *ASN = getAttributes(Index);
- return ASN ? ASN->hasAttributes() : false;
+ return ASN && ASN->hasAttributes();
}
/// \brief Return true if the specified attribute is set for at least one
@@ -1111,6 +1150,7 @@ AttrBuilder::AttrBuilder(AttributeSet AS, unsigned Index)
void AttrBuilder::clear() {
Attrs.reset();
+ TargetDepAttrs.clear();
Alignment = StackAlignment = DerefBytes = DerefOrNullBytes = 0;
}
@@ -1177,23 +1217,10 @@ AttrBuilder &AttrBuilder::removeAttributes(AttributeSet A, uint64_t Index) {
for (AttributeSet::iterator I = A.begin(Slot), E = A.end(Slot); I != E; ++I) {
Attribute Attr = *I;
if (Attr.isEnumAttribute() || Attr.isIntAttribute()) {
- Attribute::AttrKind Kind = I->getKindAsEnum();
- Attrs[Kind] = false;
-
- if (Kind == Attribute::Alignment)
- Alignment = 0;
- else if (Kind == Attribute::StackAlignment)
- StackAlignment = 0;
- else if (Kind == Attribute::Dereferenceable)
- DerefBytes = 0;
- else if (Kind == Attribute::DereferenceableOrNull)
- DerefOrNullBytes = 0;
+ removeAttribute(Attr.getKindAsEnum());
} else {
assert(Attr.isStringAttribute() && "Invalid attribute type!");
- std::map<std::string, std::string>::iterator
- Iter = TargetDepAttrs.find(Attr.getKindAsString());
- if (Iter != TargetDepAttrs.end())
- TargetDepAttrs.erase(Iter);
+ removeAttribute(Attr.getKindAsString());
}
}
@@ -1322,8 +1349,7 @@ bool AttrBuilder::hasAttributes(AttributeSet A, uint64_t Index) const {
assert(Slot != ~0U && "Couldn't find the index!");
- for (AttributeSet::iterator I = A.begin(Slot), E = A.end(Slot);
- I != E; ++I) {
+ for (AttributeSet::iterator I = A.begin(Slot), E = A.end(Slot); I != E; ++I) {
Attribute Attr = *I;
if (Attr.isEnumAttribute() || Attr.isIntAttribute()) {
if (Attrs[I->getKindAsEnum()])
@@ -1382,7 +1408,7 @@ AttrBuilder &AttrBuilder::addRawValue(uint64_t Val) {
//===----------------------------------------------------------------------===//
/// \brief Which attributes cannot be applied to a type.
-AttrBuilder AttributeFuncs::typeIncompatible(const Type *Ty) {
+AttrBuilder AttributeFuncs::typeIncompatible(Type *Ty) {
AttrBuilder Incompatible;
if (!Ty->isIntegerTy())
@@ -1406,3 +1432,80 @@ AttrBuilder AttributeFuncs::typeIncompatible(const Type *Ty) {
return Incompatible;
}
+
+template<typename AttrClass>
+static bool isEqual(const Function &Caller, const Function &Callee) {
+ return Caller.getFnAttribute(AttrClass::getKind()) ==
+ Callee.getFnAttribute(AttrClass::getKind());
+}
+
+/// \brief Compute the logical AND of the attributes of the caller and the
+/// callee.
+///
+/// This function sets the caller's attribute to false if the callee's attribute
+/// is false.
+template<typename AttrClass>
+static void setAND(Function &Caller, const Function &Callee) {
+ if (AttrClass::isSet(Caller, AttrClass::getKind()) &&
+ !AttrClass::isSet(Callee, AttrClass::getKind()))
+ AttrClass::set(Caller, AttrClass::getKind(), false);
+}
+
+/// \brief Compute the logical OR of the attributes of the caller and the
+/// callee.
+///
+/// This function sets the caller's attribute to true if the callee's attribute
+/// is true.
+template<typename AttrClass>
+static void setOR(Function &Caller, const Function &Callee) {
+ if (!AttrClass::isSet(Caller, AttrClass::getKind()) &&
+ AttrClass::isSet(Callee, AttrClass::getKind()))
+ AttrClass::set(Caller, AttrClass::getKind(), true);
+}
+
+/// \brief If the inlined function had a higher stack protection level than the
+/// calling function, then bump up the caller's stack protection level.
+static void adjustCallerSSPLevel(Function &Caller, const Function &Callee) {
+ // If upgrading the SSP attribute, clear out the old SSP Attributes first.
+ // Having multiple SSP attributes doesn't actually hurt, but it adds useless
+ // clutter to the IR.
+ AttrBuilder B;
+ B.addAttribute(Attribute::StackProtect)
+ .addAttribute(Attribute::StackProtectStrong)
+ .addAttribute(Attribute::StackProtectReq);
+ AttributeSet OldSSPAttr = AttributeSet::get(Caller.getContext(),
+ AttributeSet::FunctionIndex,
+ B);
+
+ if (Callee.hasFnAttribute(Attribute::SafeStack)) {
+ Caller.removeAttributes(AttributeSet::FunctionIndex, OldSSPAttr);
+ Caller.addFnAttr(Attribute::SafeStack);
+ } else if (Callee.hasFnAttribute(Attribute::StackProtectReq) &&
+ !Caller.hasFnAttribute(Attribute::SafeStack)) {
+ Caller.removeAttributes(AttributeSet::FunctionIndex, OldSSPAttr);
+ Caller.addFnAttr(Attribute::StackProtectReq);
+ } else if (Callee.hasFnAttribute(Attribute::StackProtectStrong) &&
+ !Caller.hasFnAttribute(Attribute::SafeStack) &&
+ !Caller.hasFnAttribute(Attribute::StackProtectReq)) {
+ Caller.removeAttributes(AttributeSet::FunctionIndex, OldSSPAttr);
+ Caller.addFnAttr(Attribute::StackProtectStrong);
+ } else if (Callee.hasFnAttribute(Attribute::StackProtect) &&
+ !Caller.hasFnAttribute(Attribute::SafeStack) &&
+ !Caller.hasFnAttribute(Attribute::StackProtectReq) &&
+ !Caller.hasFnAttribute(Attribute::StackProtectStrong))
+ Caller.addFnAttr(Attribute::StackProtect);
+}
+
+#define GET_ATTR_COMPAT_FUNC
+#include "AttributesCompatFunc.inc"
+
+bool AttributeFuncs::areInlineCompatible(const Function &Caller,
+ const Function &Callee) {
+ return hasCompatibleFnAttrs(Caller, Callee);
+}
+
+
+void AttributeFuncs::mergeAttributesForInlining(Function &Caller,
+ const Function &Callee) {
+ mergeFnAttrs(Caller, Callee);
+}
diff --git a/contrib/llvm/lib/IR/AttributesCompatFunc.td b/contrib/llvm/lib/IR/AttributesCompatFunc.td
new file mode 100644
index 000000000000..7c85b3da9ab6
--- /dev/null
+++ b/contrib/llvm/lib/IR/AttributesCompatFunc.td
@@ -0,0 +1 @@
+include "llvm/IR/Attributes.td"
diff --git a/contrib/llvm/lib/IR/AutoUpgrade.cpp b/contrib/llvm/lib/IR/AutoUpgrade.cpp
index f1c6ebd4846e..12c354c89b20 100644
--- a/contrib/llvm/lib/IR/AutoUpgrade.cpp
+++ b/contrib/llvm/lib/IR/AutoUpgrade.cpp
@@ -27,6 +27,7 @@
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/Regex.h"
#include <cstring>
using namespace llvm;
@@ -92,8 +93,42 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
F->arg_begin()->getType());
return true;
}
+ Regex vldRegex("^arm\\.neon\\.vld([1234]|[234]lane)\\.v[a-z0-9]*$");
+ if (vldRegex.match(Name)) {
+ auto fArgs = F->getFunctionType()->params();
+ SmallVector<Type *, 4> Tys(fArgs.begin(), fArgs.end());
+ // Can't use Intrinsic::getDeclaration here as the return types might
+ // then only be structurally equal.
+ FunctionType* fType = FunctionType::get(F->getReturnType(), Tys, false);
+ NewFn = Function::Create(fType, F->getLinkage(),
+ "llvm." + Name + ".p0i8", F->getParent());
+ return true;
+ }
+ Regex vstRegex("^arm\\.neon\\.vst([1234]|[234]lane)\\.v[a-z0-9]*$");
+ if (vstRegex.match(Name)) {
+ static const Intrinsic::ID StoreInts[] = {Intrinsic::arm_neon_vst1,
+ Intrinsic::arm_neon_vst2,
+ Intrinsic::arm_neon_vst3,
+ Intrinsic::arm_neon_vst4};
+
+ static const Intrinsic::ID StoreLaneInts[] = {
+ Intrinsic::arm_neon_vst2lane, Intrinsic::arm_neon_vst3lane,
+ Intrinsic::arm_neon_vst4lane
+ };
+
+ auto fArgs = F->getFunctionType()->params();
+ Type *Tys[] = {fArgs[0], fArgs[1]};
+ if (Name.find("lane") == StringRef::npos)
+ NewFn = Intrinsic::getDeclaration(F->getParent(),
+ StoreInts[fArgs.size() - 3], Tys);
+ else
+ NewFn = Intrinsic::getDeclaration(F->getParent(),
+ StoreLaneInts[fArgs.size() - 5], Tys);
+ return true;
+ }
break;
}
+
case 'c': {
if (Name.startswith("ctlz.") && F->arg_size() == 1) {
F->setName(Name + ".old");
@@ -129,7 +164,10 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
Name.startswith("x86.sse2.pcmpgt.") ||
Name.startswith("x86.avx2.pcmpeq.") ||
Name.startswith("x86.avx2.pcmpgt.") ||
+ Name.startswith("x86.avx2.vbroadcast") ||
+ Name.startswith("x86.avx2.pbroadcast") ||
Name.startswith("x86.avx.vpermil.") ||
+ Name.startswith("x86.sse41.pmovsx") ||
Name == "x86.avx.vinsertf128.pd.256" ||
Name == "x86.avx.vinsertf128.ps.256" ||
Name == "x86.avx.vinsertf128.si.256" ||
@@ -162,6 +200,7 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
Name == "x86.avx2.pblendd.128" ||
Name == "x86.avx2.pblendd.256" ||
Name == "x86.avx2.vbroadcasti128" ||
+ Name == "x86.xop.vpcmov" ||
(Name.startswith("x86.xop.vpcom") && F->arg_size() == 2)) {
NewFn = nullptr;
return true;
@@ -325,7 +364,7 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
Function *F = CI->getCalledFunction();
LLVMContext &C = CI->getContext();
IRBuilder<> Builder(C);
- Builder.SetInsertPoint(CI->getParent(), CI);
+ Builder.SetInsertPoint(CI->getParent(), CI->getIterator());
assert(F && "Intrinsic call is not direct?");
@@ -351,7 +390,7 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
Name == "llvm.x86.avx.movnt.ps.256" ||
Name == "llvm.x86.avx.movnt.pd.256") {
IRBuilder<> Builder(C);
- Builder.SetInsertPoint(CI->getParent(), CI);
+ Builder.SetInsertPoint(CI->getParent(), CI->getIterator());
Module *M = F->getParent();
SmallVector<Metadata *, 1> Elts;
@@ -368,7 +407,7 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
"cast");
StoreInst *SI = Builder.CreateStore(Arg1, BC);
SI->setMetadata(M->getMDKindID("nontemporal"), Node);
- SI->setAlignment(16);
+ SI->setAlignment(32);
// Remove intrinsic.
CI->eraseFromParent();
@@ -419,6 +458,16 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
Rep =
Builder.CreateCall(VPCOM, {CI->getArgOperand(0), CI->getArgOperand(1),
Builder.getInt8(Imm)});
+ } else if (Name == "llvm.x86.xop.vpcmov") {
+ Value *Arg0 = CI->getArgOperand(0);
+ Value *Arg1 = CI->getArgOperand(1);
+ Value *Sel = CI->getArgOperand(2);
+ unsigned NumElts = CI->getType()->getVectorNumElements();
+ Constant *MinusOne = ConstantVector::getSplat(NumElts, Builder.getInt64(-1));
+ Value *NotSel = Builder.CreateXor(Sel, MinusOne);
+ Value *Sel0 = Builder.CreateAnd(Arg0, Sel);
+ Value *Sel1 = Builder.CreateAnd(Arg1, NotSel);
+ Rep = Builder.CreateOr(Sel0, Sel1);
} else if (Name == "llvm.x86.sse42.crc32.64.8") {
Function *CRC32 = Intrinsic::getDeclaration(F->getParent(),
Intrinsic::x86_sse42_crc32_32_8);
@@ -438,6 +487,19 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
for (unsigned I = 0; I < EltNum; ++I)
Rep = Builder.CreateInsertElement(Rep, Load,
ConstantInt::get(I32Ty, I));
+ } else if (Name.startswith("llvm.x86.sse41.pmovsx")) {
+ VectorType *SrcTy = cast<VectorType>(CI->getArgOperand(0)->getType());
+ VectorType *DstTy = cast<VectorType>(CI->getType());
+ unsigned NumDstElts = DstTy->getNumElements();
+
+ // Extract a subvector of the first NumDstElts lanes and sign extend.
+ SmallVector<int, 8> ShuffleMask;
+ for (int i = 0; i != (int)NumDstElts; ++i)
+ ShuffleMask.push_back(i);
+
+ Value *SV = Builder.CreateShuffleVector(
+ CI->getArgOperand(0), UndefValue::get(SrcTy), ShuffleMask);
+ Rep = Builder.CreateSExt(SV, DstTy);
} else if (Name == "llvm.x86.avx2.vbroadcasti128") {
// Replace vbroadcasts with a vector shuffle.
Type *VT = VectorType::get(Type::getInt64Ty(C), 2);
@@ -447,6 +509,14 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
const int Idxs[4] = { 0, 1, 0, 1 };
Rep = Builder.CreateShuffleVector(Load, UndefValue::get(Load->getType()),
Idxs);
+ } else if (Name.startswith("llvm.x86.avx2.pbroadcast") ||
+ Name.startswith("llvm.x86.avx2.vbroadcast")) {
+ // Replace vp?broadcasts with a vector shuffle.
+ Value *Op = CI->getArgOperand(0);
+ unsigned NumElts = CI->getType()->getVectorNumElements();
+ Type *MaskTy = VectorType::get(Type::getInt32Ty(C), NumElts);
+ Rep = Builder.CreateShuffleVector(Op, UndefValue::get(Op->getType()),
+ Constant::getNullValue(MaskTy));
} else if (Name == "llvm.x86.sse2.psll.dq") {
// 128-bit shift left specified in bits.
unsigned Shift = cast<ConstantInt>(CI->getArgOperand(1))->getZExtValue();
@@ -517,10 +587,10 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
unsigned Imm = cast<ConstantInt>(CI->getArgOperand(2))->getZExtValue();
VectorType *VecTy = cast<VectorType>(CI->getType());
unsigned NumElts = VecTy->getNumElements();
-
+
// Mask off the high bits of the immediate value; hardware ignores those.
Imm = Imm & 1;
-
+
// Extend the second operand into a vector that is twice as big.
Value *UndefV = UndefValue::get(Op1->getType());
SmallVector<Constant*, 8> Idxs;
@@ -562,7 +632,7 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
unsigned Imm = cast<ConstantInt>(CI->getArgOperand(1))->getZExtValue();
VectorType *VecTy = cast<VectorType>(CI->getType());
unsigned NumElts = VecTy->getNumElements();
-
+
// Mask off the high bits of the immediate value; hardware ignores those.
Imm = Imm & 1;
@@ -627,6 +697,27 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
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_vld2lane:
+ case Intrinsic::arm_neon_vld3lane:
+ case Intrinsic::arm_neon_vld4lane:
+ case Intrinsic::arm_neon_vst1:
+ case Intrinsic::arm_neon_vst2:
+ case Intrinsic::arm_neon_vst3:
+ case Intrinsic::arm_neon_vst4:
+ case Intrinsic::arm_neon_vst2lane:
+ case Intrinsic::arm_neon_vst3lane:
+ case Intrinsic::arm_neon_vst4lane: {
+ SmallVector<Value *, 4> Args(CI->arg_operands().begin(),
+ CI->arg_operands().end());
+ CI->replaceAllUsesWith(Builder.CreateCall(NewFn, Args));
+ CI->eraseFromParent();
+ return;
+ }
+
case Intrinsic::ctlz:
case Intrinsic::cttz:
assert(CI->getNumArgOperands() == 1 &&
diff --git a/contrib/llvm/lib/IR/BasicBlock.cpp b/contrib/llvm/lib/IR/BasicBlock.cpp
index 0a0449434a7b..f61276fd436b 100644
--- a/contrib/llvm/lib/IR/BasicBlock.cpp
+++ b/contrib/llvm/lib/IR/BasicBlock.cpp
@@ -21,6 +21,7 @@
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Type.h"
#include <algorithm>
+
using namespace llvm;
ValueSymbolTable *BasicBlock::getValueSymbolTable() {
@@ -35,8 +36,7 @@ LLVMContext &BasicBlock::getContext() const {
// Explicit instantiation of SymbolTableListTraits since some of the methods
// are not in the public header file...
-template class llvm::SymbolTableListTraits<Instruction, BasicBlock>;
-
+template class llvm::SymbolTableListTraits<Instruction>;
BasicBlock::BasicBlock(LLVMContext &C, const Twine &Name, Function *NewParent,
BasicBlock *InsertBefore)
@@ -56,7 +56,7 @@ void BasicBlock::insertInto(Function *NewParent, BasicBlock *InsertBefore) {
assert(!Parent && "Already has a parent");
if (InsertBefore)
- NewParent->getBasicBlockList().insert(InsertBefore, this);
+ NewParent->getBasicBlockList().insert(InsertBefore->getIterator(), this);
else
NewParent->getBasicBlockList().push_back(this);
}
@@ -91,26 +91,26 @@ void BasicBlock::setParent(Function *parent) {
}
void BasicBlock::removeFromParent() {
- getParent()->getBasicBlockList().remove(this);
+ getParent()->getBasicBlockList().remove(getIterator());
}
iplist<BasicBlock>::iterator BasicBlock::eraseFromParent() {
- return getParent()->getBasicBlockList().erase(this);
+ return getParent()->getBasicBlockList().erase(getIterator());
}
/// Unlink this basic block from its current function and
/// insert it into the function that MovePos lives in, right before MovePos.
void BasicBlock::moveBefore(BasicBlock *MovePos) {
- MovePos->getParent()->getBasicBlockList().splice(MovePos,
- getParent()->getBasicBlockList(), this);
+ MovePos->getParent()->getBasicBlockList().splice(
+ MovePos->getIterator(), getParent()->getBasicBlockList(), getIterator());
}
/// Unlink this basic block from its current function and
/// insert it into the function that MovePos lives in, right after MovePos.
void BasicBlock::moveAfter(BasicBlock *MovePos) {
- Function::iterator I = MovePos;
- MovePos->getParent()->getBasicBlockList().splice(++I,
- getParent()->getBasicBlockList(), this);
+ MovePos->getParent()->getBasicBlockList().splice(
+ ++MovePos->getIterator(), getParent()->getBasicBlockList(),
+ getIterator());
}
const Module *BasicBlock::getModule() const {
@@ -196,8 +196,8 @@ BasicBlock::iterator BasicBlock::getFirstInsertionPt() {
if (!FirstNonPHI)
return end();
- iterator InsertPt = FirstNonPHI;
- if (isa<LandingPadInst>(InsertPt)) ++InsertPt;
+ iterator InsertPt = FirstNonPHI->getIterator();
+ if (InsertPt->isEHPad()) ++InsertPt;
return InsertPt;
}
@@ -245,12 +245,12 @@ BasicBlock *BasicBlock::getSingleSuccessor() {
BasicBlock *BasicBlock::getUniqueSuccessor() {
succ_iterator SI = succ_begin(this), E = succ_end(this);
- if (SI == E) return NULL; // No successors
+ if (SI == E) return nullptr; // No successors
BasicBlock *SuccBB = *SI;
++SI;
for (;SI != E; ++SI) {
if (*SI != SuccBB)
- return NULL;
+ return nullptr;
// The same successor appears multiple times in the successor list.
// This is OK.
}
@@ -333,6 +333,17 @@ void BasicBlock::removePredecessor(BasicBlock *Pred,
}
}
+bool BasicBlock::canSplitPredecessors() const {
+ const Instruction *FirstNonPHI = getFirstNonPHI();
+ if (isa<LandingPadInst>(FirstNonPHI))
+ return true;
+ // This is perhaps a little conservative because constructs like
+ // CleanupBlockInst are pretty easy to split. However, SplitBlockPredecessors
+ // cannot handle such things just yet.
+ if (FirstNonPHI->isEHPad())
+ return false;
+ return true;
+}
/// This splits a basic block into two at the specified
/// instruction. Note that all instructions BEFORE the specified iterator stay
@@ -393,8 +404,7 @@ void BasicBlock::replaceSuccessorsPhiUsesWith(BasicBlock *New) {
// 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 (BasicBlock *Succ : TI->successors()) {
// N.B. Succ might not be a complete BasicBlock, so don't assume
// that it ends with a non-phi instruction.
for (iterator II = Succ->begin(), IE = Succ->end(); II != IE; ++II) {
diff --git a/contrib/llvm/lib/IR/ConstantFold.cpp b/contrib/llvm/lib/IR/ConstantFold.cpp
index 46bb20e0d1b7..ce3fe03e2df7 100644
--- a/contrib/llvm/lib/IR/ConstantFold.cpp
+++ b/contrib/llvm/lib/IR/ConstantFold.cpp
@@ -83,7 +83,7 @@ foldConstantCastPair(
assert(DstTy && DstTy->isFirstClassType() && "Invalid cast destination type");
assert(CastInst::isCast(opc) && "Invalid cast opcode");
- // The the types and opcodes for the two Cast constant expressions
+ // The types and opcodes for the two Cast constant expressions
Type *SrcTy = Op->getOperand(0)->getType();
Type *MidTy = Op->getType();
Instruction::CastOps firstOp = Instruction::CastOps(Op->getOpcode());
@@ -109,7 +109,7 @@ static Constant *FoldBitCast(Constant *V, Type *DestTy) {
if (PointerType *PTy = dyn_cast<PointerType>(V->getType()))
if (PointerType *DPTy = dyn_cast<PointerType>(DestTy))
if (PTy->getAddressSpace() == DPTy->getAddressSpace()
- && DPTy->getElementType()->isSized()) {
+ && PTy->getElementType()->isSized()) {
SmallVector<Value*, 8> IdxList;
Value *Zero =
Constant::getNullValue(Type::getInt32Ty(DPTy->getContext()));
@@ -1187,7 +1187,7 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode,
(void)C3V.divide(C2V, APFloat::rmNearestTiesToEven);
return ConstantFP::get(C1->getContext(), C3V);
case Instruction::FRem:
- (void)C3V.mod(C2V, APFloat::rmNearestTiesToEven);
+ (void)C3V.mod(C2V);
return ConstantFP::get(C1->getContext(), C3V);
}
}
@@ -1277,9 +1277,9 @@ static bool isMaybeZeroSizedType(Type *Ty) {
}
/// IdxCompare - Compare the two constants as though they were getelementptr
-/// indices. This allows coersion of the types to be the same thing.
+/// indices. This allows coercion of the types to be the same thing.
///
-/// If the two constants are the "same" (after coersion), return 0. If the
+/// If the two constants are the "same" (after coercion), return 0. If the
/// first is less than the second, return -1, if the second is less than the
/// first, return 1. If the constants are not integral, return -2.
///
@@ -1685,7 +1685,7 @@ Constant *llvm::ConstantFoldCompareInstruction(unsigned short pred,
// Otherwise, for integer compare, pick the same value as the non-undef
// operand, and fold it to true or false.
if (isIntegerPredicate)
- return ConstantInt::get(ResultTy, CmpInst::isTrueWhenEqual(pred));
+ return ConstantInt::get(ResultTy, CmpInst::isTrueWhenEqual(Predicate));
// Choosing NaN for the undef will always make unordered comparison succeed
// and ordered comparison fails.
@@ -1869,7 +1869,8 @@ Constant *llvm::ConstantFoldCompareInstruction(unsigned short pred,
} else {
// Evaluate the relation between the two constants, per the predicate.
int Result = -1; // -1 = unknown, 0 = known false, 1 = known true.
- switch (evaluateICmpRelation(C1, C2, CmpInst::isSigned(pred))) {
+ switch (evaluateICmpRelation(C1, C2,
+ CmpInst::isSigned((CmpInst::Predicate)pred))) {
default: llvm_unreachable("Unknown relational!");
case ICmpInst::BAD_ICMP_PREDICATE:
break; // Couldn't determine anything about these constants.
@@ -1950,8 +1951,10 @@ Constant *llvm::ConstantFoldCompareInstruction(unsigned short pred,
// If the left hand side is an extension, try eliminating it.
if (ConstantExpr *CE1 = dyn_cast<ConstantExpr>(C1)) {
- if ((CE1->getOpcode() == Instruction::SExt && ICmpInst::isSigned(pred)) ||
- (CE1->getOpcode() == Instruction::ZExt && !ICmpInst::isSigned(pred))){
+ if ((CE1->getOpcode() == Instruction::SExt &&
+ ICmpInst::isSigned((ICmpInst::Predicate)pred)) ||
+ (CE1->getOpcode() == Instruction::ZExt &&
+ !ICmpInst::isSigned((ICmpInst::Predicate)pred))){
Constant *CE1Op0 = CE1->getOperand(0);
Constant *CE1Inverse = ConstantExpr::getTrunc(CE1, CE1Op0->getType());
if (CE1Inverse == CE1Op0) {
@@ -1997,17 +2000,17 @@ static bool isInBoundsIndices(ArrayRef<IndexTy> Idxs) {
}
/// \brief Test whether a given ConstantInt is in-range for a SequentialType.
-static bool isIndexInRangeOfSequentialType(const SequentialType *STy,
+static bool isIndexInRangeOfSequentialType(SequentialType *STy,
const ConstantInt *CI) {
- if (const PointerType *PTy = dyn_cast<PointerType>(STy))
- // Only handle pointers to sized types, not pointers to functions.
- return PTy->getElementType()->isSized();
+ // And indices are valid when indexing along a pointer
+ if (isa<PointerType>(STy))
+ return true;
uint64_t NumElements = 0;
// Determine the number of elements in our sequential type.
- if (const ArrayType *ATy = dyn_cast<ArrayType>(STy))
+ if (auto *ATy = dyn_cast<ArrayType>(STy))
NumElements = ATy->getNumElements();
- else if (const VectorType *VTy = dyn_cast<VectorType>(STy))
+ else if (auto *VTy = dyn_cast<VectorType>(STy))
NumElements = VTy->getNumElements();
assert((isa<ArrayType>(STy) || NumElements > 0) &&
@@ -2178,7 +2181,7 @@ static Constant *ConstantFoldGetElementPtrImpl(Type *PointeeTy, Constant *C,
// dimension.
NewIdxs.resize(Idxs.size());
uint64_t NumElements = 0;
- if (const ArrayType *ATy = dyn_cast<ArrayType>(Ty))
+ if (auto *ATy = dyn_cast<ArrayType>(Ty))
NumElements = ATy->getNumElements();
else
NumElements = cast<VectorType>(Ty)->getNumElements();
diff --git a/contrib/llvm/lib/IR/ConstantRange.cpp b/contrib/llvm/lib/IR/ConstantRange.cpp
index 91095cfe9eec..48f9b27a25ae 100644
--- a/contrib/llvm/lib/IR/ConstantRange.cpp
+++ b/contrib/llvm/lib/IR/ConstantRange.cpp
@@ -21,7 +21,9 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/IR/Instruction.h"
#include "llvm/IR/InstrTypes.h"
+#include "llvm/IR/Operator.h"
#include "llvm/IR/ConstantRange.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
@@ -125,6 +127,57 @@ ConstantRange ConstantRange::makeSatisfyingICmpRegion(CmpInst::Predicate Pred,
.inverse();
}
+ConstantRange ConstantRange::makeNoWrapRegion(Instruction::BinaryOps BinOp,
+ const APInt &C,
+ unsigned NoWrapKind) {
+ typedef OverflowingBinaryOperator OBO;
+
+ // Computes the intersection of CR0 and CR1. It is different from
+ // intersectWith in that the ConstantRange returned will only contain elements
+ // in both CR0 and CR1 (i.e. SubsetIntersect(X, Y) is a *subset*, proper or
+ // not, of both X and Y).
+ auto SubsetIntersect =
+ [](const ConstantRange &CR0, const ConstantRange &CR1) {
+ return CR0.inverse().unionWith(CR1.inverse()).inverse();
+ };
+
+ assert(BinOp >= Instruction::BinaryOpsBegin &&
+ BinOp < Instruction::BinaryOpsEnd && "Binary operators only!");
+
+ assert((NoWrapKind == OBO::NoSignedWrap ||
+ NoWrapKind == OBO::NoUnsignedWrap ||
+ NoWrapKind == (OBO::NoUnsignedWrap | OBO::NoSignedWrap)) &&
+ "NoWrapKind invalid!");
+
+ unsigned BitWidth = C.getBitWidth();
+ if (BinOp != Instruction::Add)
+ // Conservative answer: empty set
+ return ConstantRange(BitWidth, false);
+
+ if (C.isMinValue())
+ // Full set: nothing signed / unsigned wraps when added to 0.
+ return ConstantRange(BitWidth);
+
+ ConstantRange Result(BitWidth);
+
+ if (NoWrapKind & OBO::NoUnsignedWrap)
+ Result = SubsetIntersect(Result,
+ ConstantRange(APInt::getNullValue(BitWidth), -C));
+
+ if (NoWrapKind & OBO::NoSignedWrap) {
+ if (C.isStrictlyPositive())
+ Result = SubsetIntersect(
+ Result, ConstantRange(APInt::getSignedMinValue(BitWidth),
+ APInt::getSignedMinValue(BitWidth) - C));
+ else
+ Result = SubsetIntersect(
+ Result, ConstantRange(APInt::getSignedMinValue(BitWidth) - C,
+ APInt::getSignedMinValue(BitWidth)));
+ }
+
+ return Result;
+}
+
/// isFullSet - Return true if this set contains all of the elements possible
/// for this data-type
bool ConstantRange::isFullSet() const {
diff --git a/contrib/llvm/lib/IR/Constants.cpp b/contrib/llvm/lib/IR/Constants.cpp
index 308e6bde3d14..0898bf645385 100644
--- a/contrib/llvm/lib/IR/Constants.cpp
+++ b/contrib/llvm/lib/IR/Constants.cpp
@@ -53,6 +53,11 @@ bool Constant::isNegativeZeroValue() const {
if (SplatCFP && SplatCFP->isZero() && SplatCFP->isNegative())
return true;
+ if (const ConstantVector *CV = dyn_cast<ConstantVector>(this))
+ if (ConstantFP *SplatCFP = dyn_cast_or_null<ConstantFP>(CV->getSplatValue()))
+ if (SplatCFP && SplatCFP->isZero() && SplatCFP->isNegative())
+ return true;
+
// We've already handled true FP case; any other FP vectors can't represent -0.0.
if (getType()->isFPOrFPVectorTy())
return false;
@@ -68,6 +73,17 @@ bool Constant::isZeroValue() const {
if (const ConstantFP *CFP = dyn_cast<ConstantFP>(this))
return CFP->isZero();
+ // Equivalent for a vector of -0.0's.
+ if (const ConstantDataVector *CV = dyn_cast<ConstantDataVector>(this))
+ if (ConstantFP *SplatCFP = dyn_cast_or_null<ConstantFP>(CV->getSplatValue()))
+ if (SplatCFP && SplatCFP->isZero())
+ return true;
+
+ if (const ConstantVector *CV = dyn_cast<ConstantVector>(this))
+ if (ConstantFP *SplatCFP = dyn_cast_or_null<ConstantFP>(CV->getSplatValue()))
+ if (SplatCFP && SplatCFP->isZero())
+ return true;
+
// Otherwise, just use +0.0.
return isNullValue();
}
@@ -81,8 +97,10 @@ bool Constant::isNullValue() const {
if (const ConstantFP *CFP = dyn_cast<ConstantFP>(this))
return CFP->isZero() && !CFP->isNegative();
- // constant zero is zero for aggregates and cpnull is null for pointers.
- return isa<ConstantAggregateZero>(this) || isa<ConstantPointerNull>(this);
+ // constant zero is zero for aggregates, cpnull is null for pointers, none for
+ // tokens.
+ return isa<ConstantAggregateZero>(this) || isa<ConstantPointerNull>(this) ||
+ isa<ConstantTokenNone>(this);
}
bool Constant::isAllOnesValue() const {
@@ -204,6 +222,8 @@ Constant *Constant::getNullValue(Type *Ty) {
case Type::ArrayTyID:
case Type::VectorTyID:
return ConstantAggregateZero::get(Ty);
+ case Type::TokenTyID:
+ return ConstantTokenNone::get(Ty->getContext());
default:
// Function, Label, or Opaque type?
llvm_unreachable("Cannot create a null constant of that type!");
@@ -410,32 +430,13 @@ bool Constant::isConstantUsed() const {
return false;
}
+bool Constant::needsRelocation() const {
+ if (isa<GlobalValue>(this))
+ return true; // Global reference.
-
-/// getRelocationInfo - This method classifies the entry according to
-/// whether or not it may generate a relocation entry. This must be
-/// conservative, so if it might codegen to a relocatable entry, it should say
-/// so. The return values are:
-///
-/// NoRelocation: This constant pool entry is guaranteed to never have a
-/// relocation applied to it (because it holds a simple constant like
-/// '4').
-/// LocalRelocation: This entry has relocations, but the entries are
-/// guaranteed to be resolvable by the static linker, so the dynamic
-/// linker will never see them.
-/// GlobalRelocations: This entry may have arbitrary relocations.
-///
-/// FIXME: This really should not be in IR.
-Constant::PossibleRelocationsTy Constant::getRelocationInfo() const {
- if (const GlobalValue *GV = dyn_cast<GlobalValue>(this)) {
- if (GV->hasLocalLinkage() || GV->hasHiddenVisibility())
- return LocalRelocation; // Local to this file/library.
- return GlobalRelocations; // Global reference.
- }
-
if (const BlockAddress *BA = dyn_cast<BlockAddress>(this))
- return BA->getFunction()->getRelocationInfo();
-
+ return BA->getFunction()->needsRelocation();
+
// While raw uses of blockaddress need to be relocated, differences between
// two of them don't when they are for labels in the same function. This is a
// common idiom when creating a table for the indirect goto extension, so we
@@ -444,20 +445,18 @@ Constant::PossibleRelocationsTy Constant::getRelocationInfo() const {
if (CE->getOpcode() == Instruction::Sub) {
ConstantExpr *LHS = dyn_cast<ConstantExpr>(CE->getOperand(0));
ConstantExpr *RHS = dyn_cast<ConstantExpr>(CE->getOperand(1));
- if (LHS && RHS &&
- LHS->getOpcode() == Instruction::PtrToInt &&
+ if (LHS && RHS && LHS->getOpcode() == Instruction::PtrToInt &&
RHS->getOpcode() == Instruction::PtrToInt &&
isa<BlockAddress>(LHS->getOperand(0)) &&
isa<BlockAddress>(RHS->getOperand(0)) &&
cast<BlockAddress>(LHS->getOperand(0))->getFunction() ==
- cast<BlockAddress>(RHS->getOperand(0))->getFunction())
- return NoRelocation;
+ cast<BlockAddress>(RHS->getOperand(0))->getFunction())
+ return false;
}
- PossibleRelocationsTy Result = NoRelocation;
+ bool Result = false;
for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
- Result = std::max(Result,
- cast<Constant>(getOperand(i))->getRelocationInfo());
+ Result |= cast<Constant>(getOperand(i))->needsRelocation();
return Result;
}
@@ -797,10 +796,10 @@ Constant *ConstantAggregateZero::getElementValue(unsigned Idx) const {
}
unsigned ConstantAggregateZero::getNumElements() const {
- const Type *Ty = getType();
- if (const auto *AT = dyn_cast<ArrayType>(Ty))
+ Type *Ty = getType();
+ if (auto *AT = dyn_cast<ArrayType>(Ty))
return AT->getNumElements();
- if (const auto *VT = dyn_cast<VectorType>(Ty))
+ if (auto *VT = dyn_cast<VectorType>(Ty))
return VT->getNumElements();
return Ty->getStructNumElements();
}
@@ -838,10 +837,10 @@ UndefValue *UndefValue::getElementValue(unsigned Idx) const {
}
unsigned UndefValue::getNumElements() const {
- const Type *Ty = getType();
- if (const auto *AT = dyn_cast<ArrayType>(Ty))
+ Type *Ty = getType();
+ if (auto *AT = dyn_cast<ArrayType>(Ty))
return AT->getNumElements();
- if (const auto *VT = dyn_cast<VectorType>(Ty))
+ if (auto *VT = dyn_cast<VectorType>(Ty))
return VT->getNumElements();
return Ty->getStructNumElements();
}
@@ -858,6 +857,59 @@ static bool rangeOnlyContains(ItTy Start, ItTy End, EltTy Elt) {
return true;
}
+template <typename SequentialTy, typename ElementTy>
+static Constant *getIntSequenceIfElementsMatch(ArrayRef<Constant *> V) {
+ assert(!V.empty() && "Cannot get empty int sequence.");
+
+ SmallVector<ElementTy, 16> Elts;
+ for (Constant *C : V)
+ if (auto *CI = dyn_cast<ConstantInt>(C))
+ Elts.push_back(CI->getZExtValue());
+ else
+ return nullptr;
+ return SequentialTy::get(V[0]->getContext(), Elts);
+}
+
+template <typename SequentialTy, typename ElementTy>
+static Constant *getFPSequenceIfElementsMatch(ArrayRef<Constant *> V) {
+ assert(!V.empty() && "Cannot get empty FP sequence.");
+
+ SmallVector<ElementTy, 16> Elts;
+ for (Constant *C : V)
+ if (auto *CFP = dyn_cast<ConstantFP>(C))
+ Elts.push_back(CFP->getValueAPF().bitcastToAPInt().getLimitedValue());
+ else
+ return nullptr;
+ return SequentialTy::getFP(V[0]->getContext(), Elts);
+}
+
+template <typename SequenceTy>
+static Constant *getSequenceIfElementsMatch(Constant *C,
+ ArrayRef<Constant *> V) {
+ // We speculatively build the elements here even if it turns out that there is
+ // a constantexpr or something else weird, since it is so uncommon for that to
+ // happen.
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(C)) {
+ if (CI->getType()->isIntegerTy(8))
+ return getIntSequenceIfElementsMatch<SequenceTy, uint8_t>(V);
+ else if (CI->getType()->isIntegerTy(16))
+ return getIntSequenceIfElementsMatch<SequenceTy, uint16_t>(V);
+ else if (CI->getType()->isIntegerTy(32))
+ return getIntSequenceIfElementsMatch<SequenceTy, uint32_t>(V);
+ else if (CI->getType()->isIntegerTy(64))
+ return getIntSequenceIfElementsMatch<SequenceTy, uint64_t>(V);
+ } else if (ConstantFP *CFP = dyn_cast<ConstantFP>(C)) {
+ if (CFP->getType()->isHalfTy())
+ return getFPSequenceIfElementsMatch<SequenceTy, uint16_t>(V);
+ else if (CFP->getType()->isFloatTy())
+ return getFPSequenceIfElementsMatch<SequenceTy, uint32_t>(V);
+ else if (CFP->getType()->isDoubleTy())
+ return getFPSequenceIfElementsMatch<SequenceTy, uint64_t>(V);
+ }
+
+ return nullptr;
+}
+
ConstantArray::ConstantArray(ArrayType *T, ArrayRef<Constant *> V)
: Constant(T, ConstantArrayVal,
OperandTraits<ConstantArray>::op_end(this) - V.size(),
@@ -875,6 +927,7 @@ Constant *ConstantArray::get(ArrayType *Ty, ArrayRef<Constant*> V) {
return C;
return Ty->getContext().pImpl->ArrayConstants.getOrCreate(Ty, V);
}
+
Constant *ConstantArray::getImpl(ArrayType *Ty, ArrayRef<Constant*> V) {
// Empty arrays are canonicalized to ConstantAggregateZero.
if (V.empty())
@@ -897,74 +950,8 @@ Constant *ConstantArray::getImpl(ArrayType *Ty, ArrayRef<Constant*> V) {
// Check to see if all of the elements are ConstantFP or ConstantInt and if
// the element type is compatible with ConstantDataVector. If so, use it.
- if (ConstantDataSequential::isElementTypeCompatible(C->getType())) {
- // We speculatively build the elements here even if it turns out that there
- // is a constantexpr or something else weird in the array, since it is so
- // uncommon for that to happen.
- if (ConstantInt *CI = dyn_cast<ConstantInt>(C)) {
- if (CI->getType()->isIntegerTy(8)) {
- SmallVector<uint8_t, 16> Elts;
- for (unsigned i = 0, e = V.size(); i != e; ++i)
- if (ConstantInt *CI = dyn_cast<ConstantInt>(V[i]))
- Elts.push_back(CI->getZExtValue());
- else
- break;
- if (Elts.size() == V.size())
- return ConstantDataArray::get(C->getContext(), Elts);
- } else if (CI->getType()->isIntegerTy(16)) {
- SmallVector<uint16_t, 16> Elts;
- for (unsigned i = 0, e = V.size(); i != e; ++i)
- if (ConstantInt *CI = dyn_cast<ConstantInt>(V[i]))
- Elts.push_back(CI->getZExtValue());
- else
- break;
- if (Elts.size() == V.size())
- return ConstantDataArray::get(C->getContext(), Elts);
- } else if (CI->getType()->isIntegerTy(32)) {
- SmallVector<uint32_t, 16> Elts;
- for (unsigned i = 0, e = V.size(); i != e; ++i)
- if (ConstantInt *CI = dyn_cast<ConstantInt>(V[i]))
- Elts.push_back(CI->getZExtValue());
- else
- break;
- if (Elts.size() == V.size())
- return ConstantDataArray::get(C->getContext(), Elts);
- } else if (CI->getType()->isIntegerTy(64)) {
- SmallVector<uint64_t, 16> Elts;
- for (unsigned i = 0, e = V.size(); i != e; ++i)
- if (ConstantInt *CI = dyn_cast<ConstantInt>(V[i]))
- Elts.push_back(CI->getZExtValue());
- else
- break;
- if (Elts.size() == V.size())
- return ConstantDataArray::get(C->getContext(), Elts);
- }
- }
-
- if (ConstantFP *CFP = dyn_cast<ConstantFP>(C)) {
- if (CFP->getType()->isFloatTy()) {
- SmallVector<uint32_t, 16> Elts;
- for (unsigned i = 0, e = V.size(); i != e; ++i)
- if (ConstantFP *CFP = dyn_cast<ConstantFP>(V[i]))
- Elts.push_back(
- CFP->getValueAPF().bitcastToAPInt().getLimitedValue());
- else
- break;
- if (Elts.size() == V.size())
- return ConstantDataArray::getFP(C->getContext(), Elts);
- } else if (CFP->getType()->isDoubleTy()) {
- SmallVector<uint64_t, 16> Elts;
- for (unsigned i = 0, e = V.size(); i != e; ++i)
- if (ConstantFP *CFP = dyn_cast<ConstantFP>(V[i]))
- Elts.push_back(
- CFP->getValueAPF().bitcastToAPInt().getLimitedValue());
- else
- break;
- if (Elts.size() == V.size())
- return ConstantDataArray::getFP(C->getContext(), Elts);
- }
- }
- }
+ if (ConstantDataSequential::isElementTypeCompatible(C->getType()))
+ return getSequenceIfElementsMatch<ConstantDataArray>(C, V);
// Otherwise, we really do want to create a ConstantArray.
return nullptr;
@@ -1060,6 +1047,7 @@ Constant *ConstantVector::get(ArrayRef<Constant*> V) {
VectorType *Ty = VectorType::get(V.front()->getType(), V.size());
return Ty->getContext().pImpl->VectorConstants.getOrCreate(Ty, V);
}
+
Constant *ConstantVector::getImpl(ArrayRef<Constant*> V) {
assert(!V.empty() && "Vectors can't be empty");
VectorType *T = VectorType::get(V.front()->getType(), V.size());
@@ -1085,74 +1073,8 @@ Constant *ConstantVector::getImpl(ArrayRef<Constant*> V) {
// Check to see if all of the elements are ConstantFP or ConstantInt and if
// the element type is compatible with ConstantDataVector. If so, use it.
- if (ConstantDataSequential::isElementTypeCompatible(C->getType())) {
- // We speculatively build the elements here even if it turns out that there
- // is a constantexpr or something else weird in the array, since it is so
- // uncommon for that to happen.
- if (ConstantInt *CI = dyn_cast<ConstantInt>(C)) {
- if (CI->getType()->isIntegerTy(8)) {
- SmallVector<uint8_t, 16> Elts;
- for (unsigned i = 0, e = V.size(); i != e; ++i)
- if (ConstantInt *CI = dyn_cast<ConstantInt>(V[i]))
- Elts.push_back(CI->getZExtValue());
- else
- break;
- if (Elts.size() == V.size())
- return ConstantDataVector::get(C->getContext(), Elts);
- } else if (CI->getType()->isIntegerTy(16)) {
- SmallVector<uint16_t, 16> Elts;
- for (unsigned i = 0, e = V.size(); i != e; ++i)
- if (ConstantInt *CI = dyn_cast<ConstantInt>(V[i]))
- Elts.push_back(CI->getZExtValue());
- else
- break;
- if (Elts.size() == V.size())
- return ConstantDataVector::get(C->getContext(), Elts);
- } else if (CI->getType()->isIntegerTy(32)) {
- SmallVector<uint32_t, 16> Elts;
- for (unsigned i = 0, e = V.size(); i != e; ++i)
- if (ConstantInt *CI = dyn_cast<ConstantInt>(V[i]))
- Elts.push_back(CI->getZExtValue());
- else
- break;
- if (Elts.size() == V.size())
- return ConstantDataVector::get(C->getContext(), Elts);
- } else if (CI->getType()->isIntegerTy(64)) {
- SmallVector<uint64_t, 16> Elts;
- for (unsigned i = 0, e = V.size(); i != e; ++i)
- if (ConstantInt *CI = dyn_cast<ConstantInt>(V[i]))
- Elts.push_back(CI->getZExtValue());
- else
- break;
- if (Elts.size() == V.size())
- return ConstantDataVector::get(C->getContext(), Elts);
- }
- }
-
- if (ConstantFP *CFP = dyn_cast<ConstantFP>(C)) {
- if (CFP->getType()->isFloatTy()) {
- SmallVector<uint32_t, 16> Elts;
- for (unsigned i = 0, e = V.size(); i != e; ++i)
- if (ConstantFP *CFP = dyn_cast<ConstantFP>(V[i]))
- Elts.push_back(
- CFP->getValueAPF().bitcastToAPInt().getLimitedValue());
- else
- break;
- if (Elts.size() == V.size())
- return ConstantDataVector::getFP(C->getContext(), Elts);
- } else if (CFP->getType()->isDoubleTy()) {
- SmallVector<uint64_t, 16> Elts;
- for (unsigned i = 0, e = V.size(); i != e; ++i)
- if (ConstantFP *CFP = dyn_cast<ConstantFP>(V[i]))
- Elts.push_back(
- CFP->getValueAPF().bitcastToAPInt().getLimitedValue());
- else
- break;
- if (Elts.size() == V.size())
- return ConstantDataVector::getFP(C->getContext(), Elts);
- }
- }
- }
+ if (ConstantDataSequential::isElementTypeCompatible(C->getType()))
+ return getSequenceIfElementsMatch<ConstantDataVector>(C, V);
// Otherwise, the element type isn't compatible with ConstantDataVector, or
// the operand list constants a ConstantExpr or something else strange.
@@ -1170,6 +1092,17 @@ Constant *ConstantVector::getSplat(unsigned NumElts, Constant *V) {
return get(Elts);
}
+ConstantTokenNone *ConstantTokenNone::get(LLVMContext &Context) {
+ LLVMContextImpl *pImpl = Context.pImpl;
+ if (!pImpl->TheNoneToken)
+ pImpl->TheNoneToken.reset(new ConstantTokenNone(Context));
+ return pImpl->TheNoneToken.get();
+}
+
+/// Remove the constant from the constant table.
+void ConstantTokenNone::destroyConstantImpl() {
+ llvm_unreachable("You can't ConstantTokenNone->destroyConstantImpl()!");
+}
// 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
@@ -1221,8 +1154,7 @@ ArrayRef<unsigned> ConstantExpr::getIndices() const {
}
unsigned ConstantExpr::getPredicate() const {
- assert(isCompare());
- return ((const CompareConstantExpr*)this)->predicate;
+ return cast<CompareConstantExpr>(this)->predicate;
}
/// getWithOperandReplaced - Return a constant expression identical to this
@@ -1245,7 +1177,7 @@ ConstantExpr::getWithOperandReplaced(unsigned OpNo, Constant *Op) const {
/// operands replaced with the specified values. The specified array must
/// have the same number of operands as our current one.
Constant *ConstantExpr::getWithOperands(ArrayRef<Constant *> Ops, Type *Ty,
- bool OnlyIfReduced) const {
+ bool OnlyIfReduced, Type *SrcTy) const {
assert(Ops.size() == getNumOperands() && "Operand count mismatch!");
// If no operands changed return self.
@@ -1283,10 +1215,13 @@ Constant *ConstantExpr::getWithOperands(ArrayRef<Constant *> Ops, Type *Ty,
case Instruction::ShuffleVector:
return ConstantExpr::getShuffleVector(Ops[0], Ops[1], Ops[2],
OnlyIfReducedTy);
- case Instruction::GetElementPtr:
- return ConstantExpr::getGetElementPtr(nullptr, Ops[0], Ops.slice(1),
- cast<GEPOperator>(this)->isInBounds(),
- OnlyIfReducedTy);
+ case Instruction::GetElementPtr: {
+ auto *GEPO = cast<GEPOperator>(this);
+ assert(SrcTy || (Ops[0]->getType() == getOperand(0)->getType()));
+ return ConstantExpr::getGetElementPtr(
+ SrcTy ? SrcTy : GEPO->getSourceElementType(), Ops[0], Ops.slice(1),
+ GEPO->isInBounds(), OnlyIfReducedTy);
+ }
case Instruction::ICmp:
case Instruction::FCmp:
return ConstantExpr::getCompare(getPredicate(), Ops[0], Ops[1],
@@ -2430,9 +2365,9 @@ StringRef ConstantDataSequential::getRawDataValues() const {
/// formed with a vector or array of the specified element type.
/// ConstantDataArray only works with normal float and int types that are
/// stored densely in memory, not with things like i42 or x86_f80.
-bool ConstantDataSequential::isElementTypeCompatible(const Type *Ty) {
- if (Ty->isFloatTy() || Ty->isDoubleTy()) return true;
- if (const IntegerType *IT = dyn_cast<IntegerType>(Ty)) {
+bool ConstantDataSequential::isElementTypeCompatible(Type *Ty) {
+ if (Ty->isHalfTy() || Ty->isFloatTy() || Ty->isDoubleTy()) return true;
+ if (auto *IT = dyn_cast<IntegerType>(Ty)) {
switch (IT->getBitWidth()) {
case 8:
case 16:
@@ -2587,7 +2522,7 @@ Constant *ConstantDataArray::get(LLVMContext &Context, ArrayRef<double> Elts) {
/// object.
Constant *ConstantDataArray::getFP(LLVMContext &Context,
ArrayRef<uint16_t> Elts) {
- Type *Ty = VectorType::get(Type::getHalfTy(Context), Elts.size());
+ Type *Ty = ArrayType::get(Type::getHalfTy(Context), Elts.size());
const char *Data = reinterpret_cast<const char *>(Elts.data());
return getImpl(StringRef(const_cast<char *>(Data), Elts.size() * 2), Ty);
}
@@ -2703,6 +2638,11 @@ Constant *ConstantDataVector::getSplat(unsigned NumElts, Constant *V) {
}
if (ConstantFP *CFP = dyn_cast<ConstantFP>(V)) {
+ if (CFP->getType()->isHalfTy()) {
+ SmallVector<uint16_t, 16> Elts(
+ NumElts, CFP->getValueAPF().bitcastToAPInt().getLimitedValue());
+ return getFP(V->getContext(), Elts);
+ }
if (CFP->getType()->isFloatTy()) {
SmallVector<uint32_t, 16> Elts(
NumElts, CFP->getValueAPF().bitcastToAPInt().getLimitedValue());
@@ -2748,6 +2688,10 @@ APFloat ConstantDataSequential::getElementAsAPFloat(unsigned Elt) const {
switch (getElementType()->getTypeID()) {
default:
llvm_unreachable("Accessor can only be used when element is float/double!");
+ case Type::HalfTyID: {
+ auto EltVal = *reinterpret_cast<const uint16_t *>(EltPtr);
+ return APFloat(APFloat::IEEEhalf, APInt(16, EltVal));
+ }
case Type::FloatTyID: {
auto EltVal = *reinterpret_cast<const uint32_t *>(EltPtr);
return APFloat(APFloat::IEEEsingle, APInt(32, EltVal));
@@ -2782,7 +2726,8 @@ double ConstantDataSequential::getElementAsDouble(unsigned Elt) const {
/// Note that this has to compute a new constant to return, so it isn't as
/// efficient as getElementAsInteger/Float/Double.
Constant *ConstantDataSequential::getElementAsConstant(unsigned Elt) const {
- if (getElementType()->isFloatTy() || getElementType()->isDoubleTy())
+ if (getElementType()->isHalfTy() || getElementType()->isFloatTy() ||
+ getElementType()->isDoubleTy())
return ConstantFP::get(getContext(), getElementAsAPFloat(Elt));
return ConstantInt::get(getElementType(), getElementAsInteger(Elt));
@@ -2872,6 +2817,11 @@ Value *ConstantFP::handleOperandChangeImpl(Value *From, Value *To, Use *U) {
llvm_unreachable("Unsupported class for handleOperandChange()!");
}
+Value *ConstantTokenNone::handleOperandChangeImpl(Value *From, Value *To,
+ Use *U) {
+ llvm_unreachable("Unsupported class for handleOperandChange()!");
+}
+
Value *UndefValue::handleOperandChangeImpl(Value *From, Value *To, Use *U) {
llvm_unreachable("Unsupported class for handleOperandChange()!");
}
@@ -3070,7 +3020,7 @@ Instruction *ConstantExpr::getAsInstruction() {
case Instruction::ICmp:
case Instruction::FCmp:
return CmpInst::Create((Instruction::OtherOps)getOpcode(),
- getPredicate(), Ops[0], Ops[1]);
+ (CmpInst::Predicate)getPredicate(), Ops[0], Ops[1]);
default:
assert(getNumOperands() == 2 && "Must be binary operator?");
diff --git a/contrib/llvm/lib/IR/ConstantsContext.h b/contrib/llvm/lib/IR/ConstantsContext.h
index f3ddcd78d265..13fcbd2ece10 100644
--- a/contrib/llvm/lib/IR/ConstantsContext.h
+++ b/contrib/llvm/lib/IR/ConstantsContext.h
@@ -179,6 +179,13 @@ public:
/// Transparently provide more efficient getOperand methods.
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+ static bool classof(const ConstantExpr *CE) {
+ return CE->getOpcode() == Instruction::ExtractValue;
+ }
+ static bool classof(const Value *V) {
+ return isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V));
+ }
};
/// InsertValueConstantExpr - This class is private to
@@ -205,6 +212,13 @@ public:
/// Transparently provide more efficient getOperand methods.
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+ static bool classof(const ConstantExpr *CE) {
+ return CE->getOpcode() == Instruction::InsertValue;
+ }
+ static bool classof(const Value *V) {
+ return isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V));
+ }
};
/// GetElementPtrConstantExpr - This class is private to Constants.cpp, and is
@@ -235,6 +249,13 @@ public:
Type *getSourceElementType() const;
/// Transparently provide more efficient getOperand methods.
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+ static bool classof(const ConstantExpr *CE) {
+ return CE->getOpcode() == Instruction::GetElementPtr;
+ }
+ static bool classof(const Value *V) {
+ return isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V));
+ }
};
// CompareConstantExpr - This class is private to Constants.cpp, and is used
@@ -257,6 +278,14 @@ public:
}
/// Transparently provide more efficient getOperand methods.
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+ static bool classof(const ConstantExpr *CE) {
+ return CE->getOpcode() == Instruction::ICmp ||
+ CE->getOpcode() == Instruction::FCmp;
+ }
+ static bool classof(const Value *V) {
+ return isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V));
+ }
};
template <>
@@ -373,41 +402,45 @@ template <class ConstantClass> struct ConstantAggrKeyType {
struct InlineAsmKeyType {
StringRef AsmString;
StringRef Constraints;
+ FunctionType *FTy;
bool HasSideEffects;
bool IsAlignStack;
InlineAsm::AsmDialect AsmDialect;
InlineAsmKeyType(StringRef AsmString, StringRef Constraints,
- bool HasSideEffects, bool IsAlignStack,
+ FunctionType *FTy, bool HasSideEffects, bool IsAlignStack,
InlineAsm::AsmDialect AsmDialect)
- : AsmString(AsmString), Constraints(Constraints),
+ : AsmString(AsmString), Constraints(Constraints), FTy(FTy),
HasSideEffects(HasSideEffects), IsAlignStack(IsAlignStack),
AsmDialect(AsmDialect) {}
InlineAsmKeyType(const InlineAsm *Asm, SmallVectorImpl<Constant *> &)
: AsmString(Asm->getAsmString()), Constraints(Asm->getConstraintString()),
- HasSideEffects(Asm->hasSideEffects()),
+ FTy(Asm->getFunctionType()), HasSideEffects(Asm->hasSideEffects()),
IsAlignStack(Asm->isAlignStack()), AsmDialect(Asm->getDialect()) {}
bool operator==(const InlineAsmKeyType &X) const {
return HasSideEffects == X.HasSideEffects &&
IsAlignStack == X.IsAlignStack && AsmDialect == X.AsmDialect &&
- AsmString == X.AsmString && Constraints == X.Constraints;
+ AsmString == X.AsmString && Constraints == X.Constraints &&
+ FTy == X.FTy;
}
bool operator==(const InlineAsm *Asm) const {
return HasSideEffects == Asm->hasSideEffects() &&
IsAlignStack == Asm->isAlignStack() &&
AsmDialect == Asm->getDialect() &&
AsmString == Asm->getAsmString() &&
- Constraints == Asm->getConstraintString();
+ Constraints == Asm->getConstraintString() &&
+ FTy == Asm->getFunctionType();
}
unsigned getHash() const {
return hash_combine(AsmString, Constraints, HasSideEffects, IsAlignStack,
- AsmDialect);
+ AsmDialect, FTy);
}
typedef ConstantInfo<InlineAsm>::TypeClass TypeClass;
InlineAsm *create(TypeClass *Ty) const {
- return new InlineAsm(Ty, AsmString, Constraints, HasSideEffects,
+ assert(PointerType::getUnqual(FTy) == Ty);
+ return new InlineAsm(FTy, AsmString, Constraints, HasSideEffects,
IsAlignStack, AsmDialect);
}
};
diff --git a/contrib/llvm/lib/IR/Core.cpp b/contrib/llvm/lib/IR/Core.cpp
index 0eb88a967575..7f39c8085a69 100644
--- a/contrib/llvm/lib/IR/Core.cpp
+++ b/contrib/llvm/lib/IR/Core.cpp
@@ -262,6 +262,8 @@ LLVMTypeKind LLVMGetTypeKind(LLVMTypeRef Ty) {
return LLVMVectorTypeKind;
case Type::X86_MMXTyID:
return LLVMX86_MMXTypeKind;
+ case Type::TokenTyID:
+ return LLVMTokenTypeKind;
}
llvm_unreachable("Unhandled TypeID.");
}
@@ -366,6 +368,9 @@ LLVMTypeRef LLVMPPCFP128TypeInContext(LLVMContextRef C) {
LLVMTypeRef LLVMX86MMXTypeInContext(LLVMContextRef C) {
return (LLVMTypeRef) Type::getX86_MMXTy(*unwrap(C));
}
+LLVMTypeRef LLVMTokenTypeInContext(LLVMContextRef C) {
+ return (LLVMTypeRef) Type::getTokenTy(*unwrap(C));
+}
LLVMTypeRef LLVMHalfType(void) {
return LLVMHalfTypeInContext(LLVMGetGlobalContext());
@@ -1528,7 +1533,7 @@ LLVMValueRef LLVMGetFirstGlobal(LLVMModuleRef M) {
Module::global_iterator I = Mod->global_begin();
if (I == Mod->global_end())
return nullptr;
- return wrap(I);
+ return wrap(&*I);
}
LLVMValueRef LLVMGetLastGlobal(LLVMModuleRef M) {
@@ -1536,23 +1541,23 @@ LLVMValueRef LLVMGetLastGlobal(LLVMModuleRef M) {
Module::global_iterator I = Mod->global_end();
if (I == Mod->global_begin())
return nullptr;
- return wrap(--I);
+ return wrap(&*--I);
}
LLVMValueRef LLVMGetNextGlobal(LLVMValueRef GlobalVar) {
GlobalVariable *GV = unwrap<GlobalVariable>(GlobalVar);
- Module::global_iterator I = GV;
+ Module::global_iterator I(GV);
if (++I == GV->getParent()->global_end())
return nullptr;
- return wrap(I);
+ return wrap(&*I);
}
LLVMValueRef LLVMGetPreviousGlobal(LLVMValueRef GlobalVar) {
GlobalVariable *GV = unwrap<GlobalVariable>(GlobalVar);
- Module::global_iterator I = GV;
+ Module::global_iterator I(GV);
if (I == GV->getParent()->global_begin())
return nullptr;
- return wrap(--I);
+ return wrap(&*--I);
}
void LLVMDeleteGlobal(LLVMValueRef GlobalVar) {
@@ -1639,7 +1644,8 @@ void LLVMSetExternallyInitialized(LLVMValueRef GlobalVar, LLVMBool IsExtInit) {
LLVMValueRef LLVMAddAlias(LLVMModuleRef M, LLVMTypeRef Ty, LLVMValueRef Aliasee,
const char *Name) {
auto *PTy = cast<PointerType>(unwrap(Ty));
- return wrap(GlobalAlias::create(PTy, GlobalValue::ExternalLinkage, Name,
+ return wrap(GlobalAlias::create(PTy->getElementType(), PTy->getAddressSpace(),
+ GlobalValue::ExternalLinkage, Name,
unwrap<Constant>(Aliasee), unwrap(M)));
}
@@ -1660,7 +1666,7 @@ LLVMValueRef LLVMGetFirstFunction(LLVMModuleRef M) {
Module::iterator I = Mod->begin();
if (I == Mod->end())
return nullptr;
- return wrap(I);
+ return wrap(&*I);
}
LLVMValueRef LLVMGetLastFunction(LLVMModuleRef M) {
@@ -1668,23 +1674,23 @@ LLVMValueRef LLVMGetLastFunction(LLVMModuleRef M) {
Module::iterator I = Mod->end();
if (I == Mod->begin())
return nullptr;
- return wrap(--I);
+ return wrap(&*--I);
}
LLVMValueRef LLVMGetNextFunction(LLVMValueRef Fn) {
Function *Func = unwrap<Function>(Fn);
- Module::iterator I = Func;
+ Module::iterator I(Func);
if (++I == Func->getParent()->end())
return nullptr;
- return wrap(I);
+ return wrap(&*I);
}
LLVMValueRef LLVMGetPreviousFunction(LLVMValueRef Fn) {
Function *Func = unwrap<Function>(Fn);
- Module::iterator I = Func;
+ Module::iterator I(Func);
if (I == Func->getParent()->begin())
return nullptr;
- return wrap(--I);
+ return wrap(&*--I);
}
void LLVMDeleteFunction(LLVMValueRef Fn) {
@@ -1779,14 +1785,14 @@ void LLVMGetParams(LLVMValueRef FnRef, LLVMValueRef *ParamRefs) {
Function *Fn = unwrap<Function>(FnRef);
for (Function::arg_iterator I = Fn->arg_begin(),
E = Fn->arg_end(); I != E; I++)
- *ParamRefs++ = wrap(I);
+ *ParamRefs++ = wrap(&*I);
}
LLVMValueRef LLVMGetParam(LLVMValueRef FnRef, unsigned index) {
Function::arg_iterator AI = unwrap<Function>(FnRef)->arg_begin();
while (index --> 0)
AI++;
- return wrap(AI);
+ return wrap(&*AI);
}
LLVMValueRef LLVMGetParamParent(LLVMValueRef V) {
@@ -1798,7 +1804,7 @@ LLVMValueRef LLVMGetFirstParam(LLVMValueRef Fn) {
Function::arg_iterator I = Func->arg_begin();
if (I == Func->arg_end())
return nullptr;
- return wrap(I);
+ return wrap(&*I);
}
LLVMValueRef LLVMGetLastParam(LLVMValueRef Fn) {
@@ -1806,23 +1812,23 @@ LLVMValueRef LLVMGetLastParam(LLVMValueRef Fn) {
Function::arg_iterator I = Func->arg_end();
if (I == Func->arg_begin())
return nullptr;
- return wrap(--I);
+ return wrap(&*--I);
}
LLVMValueRef LLVMGetNextParam(LLVMValueRef Arg) {
Argument *A = unwrap<Argument>(Arg);
- Function::arg_iterator I = A;
+ Function::arg_iterator I(A);
if (++I == A->getParent()->arg_end())
return nullptr;
- return wrap(I);
+ return wrap(&*I);
}
LLVMValueRef LLVMGetPreviousParam(LLVMValueRef Arg) {
Argument *A = unwrap<Argument>(Arg);
- Function::arg_iterator I = A;
+ Function::arg_iterator I(A);
if (I == A->getParent()->arg_begin())
return nullptr;
- return wrap(--I);
+ return wrap(&*--I);
}
void LLVMAddAttribute(LLVMValueRef Arg, LLVMAttribute PA) {
@@ -1880,7 +1886,7 @@ unsigned LLVMCountBasicBlocks(LLVMValueRef FnRef) {
void LLVMGetBasicBlocks(LLVMValueRef FnRef, LLVMBasicBlockRef *BasicBlocksRefs){
Function *Fn = unwrap<Function>(FnRef);
for (Function::iterator I = Fn->begin(), E = Fn->end(); I != E; I++)
- *BasicBlocksRefs++ = wrap(I);
+ *BasicBlocksRefs++ = wrap(&*I);
}
LLVMBasicBlockRef LLVMGetEntryBasicBlock(LLVMValueRef Fn) {
@@ -1892,7 +1898,7 @@ LLVMBasicBlockRef LLVMGetFirstBasicBlock(LLVMValueRef Fn) {
Function::iterator I = Func->begin();
if (I == Func->end())
return nullptr;
- return wrap(I);
+ return wrap(&*I);
}
LLVMBasicBlockRef LLVMGetLastBasicBlock(LLVMValueRef Fn) {
@@ -1900,23 +1906,23 @@ LLVMBasicBlockRef LLVMGetLastBasicBlock(LLVMValueRef Fn) {
Function::iterator I = Func->end();
if (I == Func->begin())
return nullptr;
- return wrap(--I);
+ return wrap(&*--I);
}
LLVMBasicBlockRef LLVMGetNextBasicBlock(LLVMBasicBlockRef BB) {
BasicBlock *Block = unwrap(BB);
- Function::iterator I = Block;
+ Function::iterator I(Block);
if (++I == Block->getParent()->end())
return nullptr;
- return wrap(I);
+ return wrap(&*I);
}
LLVMBasicBlockRef LLVMGetPreviousBasicBlock(LLVMBasicBlockRef BB) {
BasicBlock *Block = unwrap(BB);
- Function::iterator I = Block;
+ Function::iterator I(Block);
if (I == Block->getParent()->begin())
return nullptr;
- return wrap(--I);
+ return wrap(&*--I);
}
LLVMBasicBlockRef LLVMAppendBasicBlockInContext(LLVMContextRef C,
@@ -1968,7 +1974,7 @@ LLVMValueRef LLVMGetFirstInstruction(LLVMBasicBlockRef BB) {
BasicBlock::iterator I = Block->begin();
if (I == Block->end())
return nullptr;
- return wrap(I);
+ return wrap(&*I);
}
LLVMValueRef LLVMGetLastInstruction(LLVMBasicBlockRef BB) {
@@ -1976,23 +1982,23 @@ LLVMValueRef LLVMGetLastInstruction(LLVMBasicBlockRef BB) {
BasicBlock::iterator I = Block->end();
if (I == Block->begin())
return nullptr;
- return wrap(--I);
+ return wrap(&*--I);
}
LLVMValueRef LLVMGetNextInstruction(LLVMValueRef Inst) {
Instruction *Instr = unwrap<Instruction>(Inst);
- BasicBlock::iterator I = Instr;
+ BasicBlock::iterator I(Instr);
if (++I == Instr->getParent()->end())
return nullptr;
- return wrap(I);
+ return wrap(&*I);
}
LLVMValueRef LLVMGetPreviousInstruction(LLVMValueRef Inst) {
Instruction *Instr = unwrap<Instruction>(Inst);
- BasicBlock::iterator I = Instr;
+ BasicBlock::iterator I(Instr);
if (I == Instr->getParent()->begin())
return nullptr;
- return wrap(--I);
+ return wrap(&*--I);
}
void LLVMInstructionEraseFromParent(LLVMValueRef Inst) {
@@ -2160,12 +2166,12 @@ void LLVMPositionBuilder(LLVMBuilderRef Builder, LLVMBasicBlockRef Block,
LLVMValueRef Instr) {
BasicBlock *BB = unwrap(Block);
Instruction *I = Instr? unwrap<Instruction>(Instr) : (Instruction*) BB->end();
- unwrap(Builder)->SetInsertPoint(BB, I);
+ unwrap(Builder)->SetInsertPoint(BB, I->getIterator());
}
void LLVMPositionBuilderBefore(LLVMBuilderRef Builder, LLVMValueRef Instr) {
Instruction *I = unwrap<Instruction>(Instr);
- unwrap(Builder)->SetInsertPoint(I->getParent(), I);
+ unwrap(Builder)->SetInsertPoint(I->getParent(), I->getIterator());
}
void LLVMPositionBuilderAtEnd(LLVMBuilderRef Builder, LLVMBasicBlockRef Block) {
@@ -2489,7 +2495,6 @@ LLVMValueRef LLVMBuildFree(LLVMBuilderRef B, LLVMValueRef PointerVal) {
CallInst::CreateFree(unwrap(PointerVal), unwrap(B)->GetInsertBlock())));
}
-
LLVMValueRef LLVMBuildLoad(LLVMBuilderRef B, LLVMValueRef PointerVal,
const char *Name) {
return wrap(unwrap(B)->CreateLoad(unwrap(PointerVal), Name));
@@ -2515,6 +2520,21 @@ static AtomicOrdering mapFromLLVMOrdering(LLVMAtomicOrdering Ordering) {
llvm_unreachable("Invalid LLVMAtomicOrdering value!");
}
+static LLVMAtomicOrdering mapToLLVMOrdering(AtomicOrdering Ordering) {
+ switch (Ordering) {
+ case NotAtomic: return LLVMAtomicOrderingNotAtomic;
+ case Unordered: return LLVMAtomicOrderingUnordered;
+ case Monotonic: return LLVMAtomicOrderingMonotonic;
+ case Acquire: return LLVMAtomicOrderingAcquire;
+ case Release: return LLVMAtomicOrderingRelease;
+ case AcquireRelease: return LLVMAtomicOrderingAcquireRelease;
+ case SequentiallyConsistent:
+ return LLVMAtomicOrderingSequentiallyConsistent;
+ }
+
+ llvm_unreachable("Invalid AtomicOrdering value!");
+}
+
LLVMValueRef LLVMBuildFence(LLVMBuilderRef B, LLVMAtomicOrdering Ordering,
LLVMBool isSingleThread, const char *Name) {
return wrap(
@@ -2567,6 +2587,25 @@ void LLVMSetVolatile(LLVMValueRef MemAccessInst, LLVMBool isVolatile) {
return cast<StoreInst>(P)->setVolatile(isVolatile);
}
+LLVMAtomicOrdering LLVMGetOrdering(LLVMValueRef MemAccessInst) {
+ Value *P = unwrap<Value>(MemAccessInst);
+ AtomicOrdering O;
+ if (LoadInst *LI = dyn_cast<LoadInst>(P))
+ O = LI->getOrdering();
+ else
+ O = cast<StoreInst>(P)->getOrdering();
+ return mapToLLVMOrdering(O);
+}
+
+void LLVMSetOrdering(LLVMValueRef MemAccessInst, LLVMAtomicOrdering Ordering) {
+ Value *P = unwrap<Value>(MemAccessInst);
+ AtomicOrdering O = mapFromLLVMOrdering(Ordering);
+
+ if (LoadInst *LI = dyn_cast<LoadInst>(P))
+ return LI->setOrdering(O);
+ return cast<StoreInst>(P)->setOrdering(O);
+}
+
/*--.. Casts ...............................................................--*/
LLVMValueRef LLVMBuildTrunc(LLVMBuilderRef B, LLVMValueRef Val,
diff --git a/contrib/llvm/lib/IR/DIBuilder.cpp b/contrib/llvm/lib/IR/DIBuilder.cpp
index 2a90e70af1a3..b7841fe2b85c 100644
--- a/contrib/llvm/lib/IR/DIBuilder.cpp
+++ b/contrib/llvm/lib/IR/DIBuilder.cpp
@@ -148,7 +148,7 @@ DICompileUnit *DIBuilder::createCompileUnit(
CUNode = DICompileUnit::getDistinct(
VMContext, Lang, DIFile::get(VMContext, Filename, Directory), Producer,
isOptimized, Flags, RunTimeVer, SplitName, Kind, nullptr,
- nullptr, nullptr, nullptr, nullptr, DWOId);
+ nullptr, nullptr, nullptr, nullptr, nullptr, DWOId);
// Create a named metadata so that it is easier to find cu in a module.
// Note that we only generate this when the caller wants to actually
@@ -255,10 +255,12 @@ DIDerivedType *DIBuilder::createMemberPointerType(DIType *PointeeTy,
DITypeRef::get(Base));
}
-DIDerivedType *DIBuilder::createReferenceType(unsigned Tag, DIType *RTy) {
+DIDerivedType *DIBuilder::createReferenceType(unsigned Tag, DIType *RTy,
+ uint64_t SizeInBits,
+ uint64_t AlignInBits) {
assert(RTy && "Unable to create reference type");
return DIDerivedType::get(VMContext, Tag, "", nullptr, 0, nullptr,
- DITypeRef::get(RTy), 0, 0, 0, 0);
+ DITypeRef::get(RTy), SizeInBits, AlignInBits, 0, 0);
}
DIDerivedType *DIBuilder::createTypedef(DIType *Ty, StringRef Name,
@@ -429,12 +431,23 @@ DICompositeType *DIBuilder::createUnionType(
return R;
}
-DISubroutineType *DIBuilder::createSubroutineType(DIFile *File,
- DITypeRefArray ParameterTypes,
+DISubroutineType *DIBuilder::createSubroutineType(DITypeRefArray ParameterTypes,
unsigned Flags) {
return DISubroutineType::get(VMContext, Flags, ParameterTypes);
}
+DICompositeType *DIBuilder::createExternalTypeRef(unsigned Tag, DIFile *File,
+ StringRef UniqueIdentifier) {
+ assert(!UniqueIdentifier.empty() && "external type ref without uid");
+ auto *CTy =
+ DICompositeType::get(VMContext, Tag, "", nullptr, 0, nullptr, nullptr, 0,
+ 0, 0, DINode::FlagExternalTypeRef, nullptr, 0,
+ nullptr, nullptr, UniqueIdentifier);
+ // Types with unique IDs need to be in the type map.
+ retainType(CTy);
+ return CTy;
+}
+
DICompositeType *DIBuilder::createEnumerationType(
DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber,
uint64_t SizeInBits, uint64_t AlignInBits, DINodeArray Elements,
@@ -590,18 +603,20 @@ DIGlobalVariable *DIBuilder::createTempGlobalVariableFwdDecl(
.release();
}
-DILocalVariable *DIBuilder::createLocalVariable(
- unsigned Tag, DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNo,
- DIType *Ty, bool AlwaysPreserve, unsigned Flags, unsigned ArgNo) {
+static DILocalVariable *createLocalVariable(
+ LLVMContext &VMContext,
+ DenseMap<MDNode *, std::vector<TrackingMDNodeRef>> &PreservedVariables,
+ DIScope *Scope, StringRef Name, unsigned ArgNo, DIFile *File,
+ unsigned LineNo, DIType *Ty, bool AlwaysPreserve, unsigned Flags) {
// FIXME: Why getNonCompileUnitScope()?
// FIXME: Why is "!Context" okay here?
// FIXME: Why doesn't this check for a subprogram or lexical block (AFAICT
// the only valid scopes)?
DIScope *Context = getNonCompileUnitScope(Scope);
- auto *Node = DILocalVariable::get(
- VMContext, Tag, cast_or_null<DILocalScope>(Context), Name, File, LineNo,
- DITypeRef::get(Ty), ArgNo, Flags);
+ auto *Node =
+ DILocalVariable::get(VMContext, cast_or_null<DILocalScope>(Context), Name,
+ File, LineNo, DITypeRef::get(Ty), ArgNo, Flags);
if (AlwaysPreserve) {
// The optimizer may remove local variables. If there is an interest
// to preserve variable info in such situation then stash it in a
@@ -613,6 +628,23 @@ DILocalVariable *DIBuilder::createLocalVariable(
return Node;
}
+DILocalVariable *DIBuilder::createAutoVariable(DIScope *Scope, StringRef Name,
+ DIFile *File, unsigned LineNo,
+ DIType *Ty, bool AlwaysPreserve,
+ unsigned Flags) {
+ return createLocalVariable(VMContext, PreservedVariables, Scope, Name,
+ /* ArgNo */ 0, File, LineNo, Ty, AlwaysPreserve,
+ Flags);
+}
+
+DILocalVariable *DIBuilder::createParameterVariable(
+ DIScope *Scope, StringRef Name, unsigned ArgNo, DIFile *File,
+ unsigned LineNo, DIType *Ty, bool AlwaysPreserve, unsigned Flags) {
+ assert(ArgNo && "Expected non-zero argument number for parameter");
+ return createLocalVariable(VMContext, PreservedVariables, Scope, Name, ArgNo,
+ File, LineNo, Ty, AlwaysPreserve, Flags);
+}
+
DIExpression *DIBuilder::createExpression(ArrayRef<uint64_t> Addr) {
return DIExpression::get(VMContext, Addr);
}
@@ -629,36 +661,37 @@ DIExpression *DIBuilder::createBitPieceExpression(unsigned OffsetInBytes,
return DIExpression::get(VMContext, Addr);
}
-DISubprogram *DIBuilder::createFunction(DIScopeRef Context, StringRef Name,
- StringRef LinkageName, DIFile *File,
- unsigned LineNo, DISubroutineType *Ty,
- bool isLocalToUnit, bool isDefinition,
- unsigned ScopeLine, unsigned Flags,
- bool isOptimized, Function *Fn,
- MDNode *TParams, MDNode *Decl) {
+DISubprogram *DIBuilder::createFunction(
+ DIScopeRef Context, StringRef Name, StringRef LinkageName, DIFile *File,
+ unsigned LineNo, DISubroutineType *Ty, bool isLocalToUnit,
+ bool isDefinition, unsigned ScopeLine, unsigned Flags, bool isOptimized,
+ DITemplateParameterArray TParams, DISubprogram *Decl) {
// dragonegg does not generate identifier for types, so using an empty map
// to resolve the context should be fine.
DITypeIdentifierMap EmptyMap;
return createFunction(Context.resolve(EmptyMap), Name, LinkageName, File,
LineNo, Ty, isLocalToUnit, isDefinition, ScopeLine,
- Flags, isOptimized, Fn, TParams, Decl);
-}
-
-DISubprogram *DIBuilder::createFunction(DIScope *Context, StringRef Name,
- StringRef LinkageName, DIFile *File,
- unsigned LineNo, DISubroutineType *Ty,
- bool isLocalToUnit, bool isDefinition,
- unsigned ScopeLine, unsigned Flags,
- bool isOptimized, Function *Fn,
- MDNode *TParams, MDNode *Decl) {
- assert(Ty->getTag() == dwarf::DW_TAG_subroutine_type &&
- "function types should be subroutines");
- auto *Node = DISubprogram::get(
- VMContext, DIScopeRef::get(getNonCompileUnitScope(Context)), Name,
- LinkageName, File, LineNo, Ty, isLocalToUnit, isDefinition, ScopeLine,
- nullptr, 0, 0, Flags, isOptimized, Fn, cast_or_null<MDTuple>(TParams),
- cast_or_null<DISubprogram>(Decl),
- MDTuple::getTemporary(VMContext, None).release());
+ Flags, isOptimized, TParams, Decl);
+}
+
+template <class... Ts>
+static DISubprogram *getSubprogram(bool IsDistinct, Ts &&... Args) {
+ if (IsDistinct)
+ return DISubprogram::getDistinct(std::forward<Ts>(Args)...);
+ return DISubprogram::get(std::forward<Ts>(Args)...);
+}
+
+DISubprogram *DIBuilder::createFunction(
+ DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *File,
+ unsigned LineNo, DISubroutineType *Ty, bool isLocalToUnit,
+ bool isDefinition, unsigned ScopeLine, unsigned Flags, bool isOptimized,
+ DITemplateParameterArray TParams, DISubprogram *Decl) {
+ auto *Node =
+ getSubprogram(/* IsDistinct = */ isDefinition, VMContext,
+ DIScopeRef::get(getNonCompileUnitScope(Context)), Name,
+ LinkageName, File, LineNo, Ty, isLocalToUnit, isDefinition,
+ ScopeLine, nullptr, 0, 0, Flags, isOptimized, TParams, Decl,
+ MDTuple::getTemporary(VMContext, None).release());
if (isDefinition)
AllSubprograms.push_back(Node);
@@ -670,12 +703,11 @@ DISubprogram *DIBuilder::createTempFunctionFwdDecl(
DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *File,
unsigned LineNo, DISubroutineType *Ty, bool isLocalToUnit,
bool isDefinition, unsigned ScopeLine, unsigned Flags, bool isOptimized,
- Function *Fn, MDNode *TParams, MDNode *Decl) {
+ DITemplateParameterArray TParams, DISubprogram *Decl) {
return DISubprogram::getTemporary(
VMContext, DIScopeRef::get(getNonCompileUnitScope(Context)), Name,
LinkageName, File, LineNo, Ty, isLocalToUnit, isDefinition,
- ScopeLine, nullptr, 0, 0, Flags, isOptimized, Fn,
- cast_or_null<MDTuple>(TParams), cast_or_null<DISubprogram>(Decl),
+ ScopeLine, nullptr, 0, 0, Flags, isOptimized, TParams, Decl,
nullptr)
.release();
}
@@ -685,18 +717,16 @@ DIBuilder::createMethod(DIScope *Context, StringRef Name, StringRef LinkageName,
DIFile *F, unsigned LineNo, DISubroutineType *Ty,
bool isLocalToUnit, bool isDefinition, unsigned VK,
unsigned VIndex, DIType *VTableHolder, unsigned Flags,
- bool isOptimized, Function *Fn, MDNode *TParam) {
- assert(Ty->getTag() == dwarf::DW_TAG_subroutine_type &&
- "function types should be subroutines");
+ bool isOptimized, DITemplateParameterArray TParams) {
assert(getNonCompileUnitScope(Context) &&
"Methods should have both a Context and a context that isn't "
"the compile unit.");
// FIXME: Do we want to use different scope/lines?
- auto *SP = DISubprogram::get(
- VMContext, DIScopeRef::get(cast<DIScope>(Context)), Name, LinkageName, F,
- LineNo, Ty, isLocalToUnit, isDefinition, LineNo,
- DITypeRef::get(VTableHolder), VK, VIndex, Flags, isOptimized, Fn,
- cast_or_null<MDTuple>(TParam), nullptr, nullptr);
+ auto *SP = getSubprogram(
+ /* IsDistinct = */ isDefinition, VMContext,
+ DIScopeRef::get(cast<DIScope>(Context)), Name, LinkageName, F, LineNo, Ty,
+ isLocalToUnit, isDefinition, LineNo, DITypeRef::get(VTableHolder), VK,
+ VIndex, Flags, isOptimized, TParams, nullptr, nullptr);
if (isDefinition)
AllSubprograms.push_back(SP);
diff --git a/contrib/llvm/lib/IR/DataLayout.cpp b/contrib/llvm/lib/IR/DataLayout.cpp
index 4d867efe1b3d..5468f47bbfe6 100644
--- a/contrib/llvm/lib/IR/DataLayout.cpp
+++ b/contrib/llvm/lib/IR/DataLayout.cpp
@@ -41,6 +41,7 @@ StructLayout::StructLayout(StructType *ST, const DataLayout &DL) {
assert(!ST->isOpaque() && "Cannot get layout of opaque structs");
StructAlignment = 0;
StructSize = 0;
+ IsPadded = false;
NumElements = ST->getNumElements();
// Loop over each of the elements, placing them in memory.
@@ -49,8 +50,10 @@ StructLayout::StructLayout(StructType *ST, const DataLayout &DL) {
unsigned TyAlign = ST->isPacked() ? 1 : DL.getABITypeAlignment(Ty);
// Add padding if necessary to align the data element properly.
- if ((StructSize & (TyAlign-1)) != 0)
+ if ((StructSize & (TyAlign-1)) != 0) {
+ IsPadded = true;
StructSize = RoundUpToAlignment(StructSize, TyAlign);
+ }
// Keep track of maximum alignment constraint.
StructAlignment = std::max(TyAlign, StructAlignment);
@@ -64,8 +67,10 @@ StructLayout::StructLayout(StructType *ST, const DataLayout &DL) {
// Add padding to the end of the struct so that it could be put in an array
// and all array elements would be aligned correctly.
- if ((StructSize & (StructAlignment-1)) != 0)
+ if ((StructSize & (StructAlignment-1)) != 0) {
+ IsPadded = true;
StructSize = RoundUpToAlignment(StructSize, StructAlignment);
+ }
}
@@ -461,8 +466,8 @@ unsigned DataLayout::getAlignmentInfo(AlignTypeEnum AlignType,
return ABIInfo ? Alignments[i].ABIAlign : Alignments[i].PrefAlign;
// The best match so far depends on what we're looking for.
- if (AlignType == INTEGER_ALIGN &&
- Alignments[i].AlignType == INTEGER_ALIGN) {
+ if (AlignType == INTEGER_ALIGN &&
+ Alignments[i].AlignType == INTEGER_ALIGN) {
// The "best match" for integers is the smallest size that is larger than
// the BitWidth requested.
if (Alignments[i].TypeBitWidth > BitWidth && (BestMatchIdx == -1 ||
diff --git a/contrib/llvm/lib/IR/DebugInfo.cpp b/contrib/llvm/lib/IR/DebugInfo.cpp
index 9646d1aa4d76..a2443becdd00 100644
--- a/contrib/llvm/lib/IR/DebugInfo.cpp
+++ b/contrib/llvm/lib/IR/DebugInfo.cpp
@@ -56,21 +56,6 @@ DISubprogram *llvm::getDISubprogram(const Function *F) {
return nullptr;
}
-DICompositeTypeBase *llvm::getDICompositeType(DIType *T) {
- if (auto *C = dyn_cast_or_null<DICompositeTypeBase>(T))
- return C;
-
- if (auto *D = dyn_cast_or_null<DIDerivedTypeBase>(T)) {
- // This function is currently used by dragonegg and dragonegg does
- // not generate identifier for types, so using an empty map to resolve
- // DerivedFrom should be fine.
- DITypeIdentifierMap EmptyMap;
- return getDICompositeType(D->getBaseType().resolve(EmptyMap));
- }
-
- return nullptr;
-}
-
DITypeIdentifierMap
llvm::generateDITypeIdentifierMap(const NamedMDNode *CU_Nodes) {
DITypeIdentifierMap Map;
@@ -164,20 +149,22 @@ void DebugInfoFinder::processType(DIType *DT) {
if (!addType(DT))
return;
processScope(DT->getScope().resolve(TypeIdentifierMap));
- if (auto *DCT = dyn_cast<DICompositeTypeBase>(DT)) {
+ if (auto *ST = dyn_cast<DISubroutineType>(DT)) {
+ for (DITypeRef Ref : ST->getTypeArray())
+ processType(Ref.resolve(TypeIdentifierMap));
+ return;
+ }
+ if (auto *DCT = dyn_cast<DICompositeType>(DT)) {
processType(DCT->getBaseType().resolve(TypeIdentifierMap));
- if (auto *ST = dyn_cast<DISubroutineType>(DCT)) {
- for (DITypeRef Ref : ST->getTypeArray())
- processType(Ref.resolve(TypeIdentifierMap));
- return;
- }
for (Metadata *D : DCT->getElements()) {
if (auto *T = dyn_cast<DIType>(D))
processType(T);
else if (auto *SP = dyn_cast<DISubprogram>(D))
processSubprogram(SP);
}
- } else if (auto *DDT = dyn_cast<DIDerivedTypeBase>(DT)) {
+ return;
+ }
+ if (auto *DDT = dyn_cast<DIDerivedType>(DT)) {
processType(DDT->getBaseType().resolve(TypeIdentifierMap));
}
}
@@ -313,6 +300,10 @@ bool DebugInfoFinder::addScope(DIScope *Scope) {
bool llvm::stripDebugInfo(Function &F) {
bool Changed = false;
+ if (F.getSubprogram()) {
+ Changed = true;
+ F.setSubprogram(nullptr);
+ }
for (BasicBlock &BB : F) {
for (Instruction &I : BB) {
if (I.getDebugLoc()) {
@@ -349,7 +340,7 @@ bool llvm::StripDebugInfo(Module &M) {
for (Module::named_metadata_iterator NMI = M.named_metadata_begin(),
NME = M.named_metadata_end(); NMI != NME;) {
- NamedMDNode *NMD = NMI;
+ NamedMDNode *NMD = &*NMI;
++NMI;
if (NMD->getName().startswith("llvm.dbg.")) {
NMD->eraseFromParent();
@@ -372,21 +363,3 @@ unsigned llvm::getDebugMetadataVersionFromModule(const Module &M) {
return Val->getZExtValue();
return 0;
}
-
-DenseMap<const llvm::Function *, DISubprogram *>
-llvm::makeSubprogramMap(const Module &M) {
- DenseMap<const Function *, DISubprogram *> R;
-
- NamedMDNode *CU_Nodes = M.getNamedMetadata("llvm.dbg.cu");
- if (!CU_Nodes)
- return R;
-
- for (MDNode *N : CU_Nodes->operands()) {
- auto *CUNode = cast<DICompileUnit>(N);
- for (auto *SP : CUNode->getSubprograms()) {
- if (Function *F = SP->getFunction())
- R.insert(std::make_pair(F, SP));
- }
- }
- return R;
-}
diff --git a/contrib/llvm/lib/IR/DebugInfoMetadata.cpp b/contrib/llvm/lib/IR/DebugInfoMetadata.cpp
index 5e017488c1fb..58e0abdd577c 100644
--- a/contrib/llvm/lib/IR/DebugInfoMetadata.cpp
+++ b/contrib/llvm/lib/IR/DebugInfoMetadata.cpp
@@ -295,8 +295,7 @@ DISubroutineType *DISubroutineType::getImpl(LLVMContext &Context,
StorageType Storage,
bool ShouldCreate) {
DEFINE_GETIMPL_LOOKUP(DISubroutineType, (Flags, TypeArray));
- Metadata *Ops[] = {nullptr, nullptr, nullptr, nullptr,
- TypeArray, nullptr, nullptr, nullptr};
+ Metadata *Ops[] = {nullptr, nullptr, nullptr, TypeArray};
DEFINE_GETIMPL_STORE(DISubroutineType, (Flags), Ops);
}
@@ -316,22 +315,20 @@ DICompileUnit *DICompileUnit::getImpl(
unsigned RuntimeVersion, MDString *SplitDebugFilename,
unsigned EmissionKind, Metadata *EnumTypes, Metadata *RetainedTypes,
Metadata *Subprograms, Metadata *GlobalVariables,
- Metadata *ImportedEntities, uint64_t DWOId,
+ Metadata *ImportedEntities, Metadata *Macros, uint64_t DWOId,
StorageType Storage, bool ShouldCreate) {
+ assert(Storage != Uniqued && "Cannot unique DICompileUnit");
assert(isCanonical(Producer) && "Expected canonical MDString");
assert(isCanonical(Flags) && "Expected canonical MDString");
assert(isCanonical(SplitDebugFilename) && "Expected canonical MDString");
- DEFINE_GETIMPL_LOOKUP(
- DICompileUnit,
- (SourceLanguage, File, getString(Producer), IsOptimized, getString(Flags),
- RuntimeVersion, getString(SplitDebugFilename), EmissionKind, EnumTypes,
- RetainedTypes, Subprograms, GlobalVariables, ImportedEntities, DWOId));
+
Metadata *Ops[] = {File, Producer, Flags, SplitDebugFilename, EnumTypes,
RetainedTypes, Subprograms, GlobalVariables,
- ImportedEntities};
- DEFINE_GETIMPL_STORE(
- DICompileUnit,
- (SourceLanguage, IsOptimized, RuntimeVersion, EmissionKind, DWOId), Ops);
+ ImportedEntities, Macros};
+ return storeImpl(new (ArrayRef<Metadata *>(Ops).size()) DICompileUnit(
+ Context, Storage, SourceLanguage, IsOptimized,
+ RuntimeVersion, EmissionKind, DWOId, Ops),
+ Storage);
}
DISubprogram *DILocalScope::getSubprogram() const {
@@ -345,34 +342,28 @@ DISubprogram *DISubprogram::getImpl(
MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type,
bool IsLocalToUnit, bool IsDefinition, unsigned ScopeLine,
Metadata *ContainingType, unsigned Virtuality, unsigned VirtualIndex,
- unsigned Flags, bool IsOptimized, Metadata *Function,
- Metadata *TemplateParams, Metadata *Declaration, Metadata *Variables,
- StorageType Storage, bool ShouldCreate) {
+ unsigned Flags, bool IsOptimized, Metadata *TemplateParams,
+ Metadata *Declaration, Metadata *Variables, StorageType Storage,
+ bool ShouldCreate) {
assert(isCanonical(Name) && "Expected canonical MDString");
assert(isCanonical(LinkageName) && "Expected canonical MDString");
DEFINE_GETIMPL_LOOKUP(DISubprogram,
(Scope, getString(Name), getString(LinkageName), File,
Line, Type, IsLocalToUnit, IsDefinition, ScopeLine,
ContainingType, Virtuality, VirtualIndex, Flags,
- IsOptimized, Function, TemplateParams, Declaration,
- Variables));
- Metadata *Ops[] = {File, Scope, Name, Name,
- LinkageName, Type, ContainingType, Function,
- TemplateParams, Declaration, Variables};
+ IsOptimized, TemplateParams, Declaration, Variables));
+ Metadata *Ops[] = {File, Scope, Name, Name,
+ LinkageName, Type, ContainingType, TemplateParams,
+ Declaration, Variables};
DEFINE_GETIMPL_STORE(DISubprogram,
(Line, ScopeLine, Virtuality, VirtualIndex, Flags,
IsLocalToUnit, IsDefinition, IsOptimized),
Ops);
}
-Function *DISubprogram::getFunction() const {
- // FIXME: Should this be looking through bitcasts?
- return dyn_cast_or_null<Function>(getFunctionConstant());
-}
-
bool DISubprogram::describes(const Function *F) const {
assert(F && "Invalid function");
- if (F == getFunction())
+ if (F->getSubprogram() == this)
return true;
StringRef Name = getLinkageName();
if (Name.empty())
@@ -380,15 +371,13 @@ bool DISubprogram::describes(const Function *F) const {
return F->getName() == Name;
}
-void DISubprogram::replaceFunction(Function *F) {
- replaceFunction(F ? ConstantAsMetadata::get(F)
- : static_cast<ConstantAsMetadata *>(nullptr));
-}
-
DILexicalBlock *DILexicalBlock::getImpl(LLVMContext &Context, Metadata *Scope,
Metadata *File, unsigned Line,
unsigned Column, StorageType Storage,
bool ShouldCreate) {
+ // Fixup column.
+ adjustColumn(Column);
+
assert(Scope && "Expected scope");
DEFINE_GETIMPL_LOOKUP(DILexicalBlock, (Scope, File, Line, Column));
Metadata *Ops[] = {File, Scope};
@@ -467,21 +456,21 @@ DIGlobalVariable::getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
Ops);
}
-DILocalVariable *DILocalVariable::getImpl(LLVMContext &Context, unsigned Tag,
- Metadata *Scope, MDString *Name,
- Metadata *File, unsigned Line,
- Metadata *Type, unsigned Arg,
- unsigned Flags, StorageType Storage,
+DILocalVariable *DILocalVariable::getImpl(LLVMContext &Context, Metadata *Scope,
+ MDString *Name, Metadata *File,
+ unsigned Line, Metadata *Type,
+ unsigned Arg, unsigned Flags,
+ StorageType Storage,
bool ShouldCreate) {
// 64K ought to be enough for any frontend.
assert(Arg <= UINT16_MAX && "Expected argument number to fit in 16-bits");
assert(Scope && "Expected scope");
assert(isCanonical(Name) && "Expected canonical MDString");
- DEFINE_GETIMPL_LOOKUP(DILocalVariable, (Tag, Scope, getString(Name), File,
- Line, Type, Arg, Flags));
+ DEFINE_GETIMPL_LOOKUP(DILocalVariable,
+ (Scope, getString(Name), File, Line, Type, Arg, Flags));
Metadata *Ops[] = {Scope, Name, File, Type};
- DEFINE_GETIMPL_STORE(DILocalVariable, (Tag, Line, Arg, Flags), Ops);
+ DEFINE_GETIMPL_STORE(DILocalVariable, (Line, Arg, Flags), Ops);
}
DIExpression *DIExpression::getImpl(LLVMContext &Context,
@@ -496,6 +485,7 @@ unsigned DIExpression::ExprOperand::getSize() const {
case dwarf::DW_OP_bit_piece:
return 3;
case dwarf::DW_OP_plus:
+ case dwarf::DW_OP_minus:
return 2;
default:
return 1;
@@ -516,6 +506,7 @@ bool DIExpression::isValid() const {
// Piece expressions must be at the end.
return I->get() + I->getSize() == E->get();
case dwarf::DW_OP_plus:
+ case dwarf::DW_OP_minus:
case dwarf::DW_OP_deref:
break;
}
@@ -566,3 +557,24 @@ DIImportedEntity *DIImportedEntity::getImpl(LLVMContext &Context, unsigned Tag,
Metadata *Ops[] = {Scope, Entity, Name};
DEFINE_GETIMPL_STORE(DIImportedEntity, (Tag, Line), Ops);
}
+
+DIMacro *DIMacro::getImpl(LLVMContext &Context, unsigned MIType,
+ unsigned Line, MDString *Name, MDString *Value,
+ StorageType Storage, bool ShouldCreate) {
+ assert(isCanonical(Name) && "Expected canonical MDString");
+ DEFINE_GETIMPL_LOOKUP(DIMacro,
+ (MIType, Line, getString(Name), getString(Value)));
+ Metadata *Ops[] = { Name, Value };
+ DEFINE_GETIMPL_STORE(DIMacro, (MIType, Line), Ops);
+}
+
+DIMacroFile *DIMacroFile::getImpl(LLVMContext &Context, unsigned MIType,
+ unsigned Line, Metadata *File,
+ Metadata *Elements, StorageType Storage,
+ bool ShouldCreate) {
+ DEFINE_GETIMPL_LOOKUP(DIMacroFile,
+ (MIType, Line, File, Elements));
+ Metadata *Ops[] = { File, Elements };
+ DEFINE_GETIMPL_STORE(DIMacroFile, (MIType, Line), Ops);
+}
+
diff --git a/contrib/llvm/lib/IR/DiagnosticInfo.cpp b/contrib/llvm/lib/IR/DiagnosticInfo.cpp
index b8f77eda15a6..6426f76bbaa6 100644
--- a/contrib/llvm/lib/IR/DiagnosticInfo.cpp
+++ b/contrib/llvm/lib/IR/DiagnosticInfo.cpp
@@ -49,7 +49,7 @@ struct PassRemarksOpt {
"' in -pass-remarks: " + RegexError,
false);
}
- };
+ }
};
static PassRemarksOpt PassRemarksOptLoc;
@@ -91,6 +91,8 @@ int llvm::getNextAvailablePluginDiagnosticKind() {
return ++PluginKindID;
}
+const char *DiagnosticInfo::AlwaysPrint = "";
+
DiagnosticInfoInlineAsm::DiagnosticInfoInlineAsm(const Instruction &I,
const Twine &MsgStr,
DiagnosticSeverity Severity)
@@ -121,9 +123,17 @@ void DiagnosticInfoDebugMetadataVersion::print(DiagnosticPrinter &DP) const {
}
void DiagnosticInfoSampleProfile::print(DiagnosticPrinter &DP) const {
- if (getFileName() && getLineNum() > 0)
- DP << getFileName() << ":" << getLineNum() << ": ";
- else if (getFileName())
+ if (!FileName.empty()) {
+ DP << getFileName();
+ if (LineNum > 0)
+ DP << ":" << getLineNum();
+ DP << ": ";
+ }
+ DP << getMsg();
+}
+
+void DiagnosticInfoPGOProfile::print(DiagnosticPrinter &DP) const {
+ if (getFileName())
DP << getFileName() << ": ";
DP << getMsg();
}
@@ -166,8 +176,9 @@ bool DiagnosticInfoOptimizationRemarkMissed::isEnabled() const {
}
bool DiagnosticInfoOptimizationRemarkAnalysis::isEnabled() const {
- return PassRemarksAnalysisOptLoc.Pattern &&
- PassRemarksAnalysisOptLoc.Pattern->match(getPassName());
+ return getPassName() == DiagnosticInfo::AlwaysPrint ||
+ (PassRemarksAnalysisOptLoc.Pattern &&
+ PassRemarksAnalysisOptLoc.Pattern->match(getPassName()));
}
void DiagnosticInfoMIRParser::print(DiagnosticPrinter &DP) const {
@@ -196,6 +207,24 @@ void llvm::emitOptimizationRemarkAnalysis(LLVMContext &Ctx,
DiagnosticInfoOptimizationRemarkAnalysis(PassName, Fn, DLoc, Msg));
}
+void llvm::emitOptimizationRemarkAnalysisFPCommute(LLVMContext &Ctx,
+ const char *PassName,
+ const Function &Fn,
+ const DebugLoc &DLoc,
+ const Twine &Msg) {
+ Ctx.diagnose(DiagnosticInfoOptimizationRemarkAnalysisFPCommute(PassName, Fn,
+ DLoc, Msg));
+}
+
+void llvm::emitOptimizationRemarkAnalysisAliasing(LLVMContext &Ctx,
+ const char *PassName,
+ const Function &Fn,
+ const DebugLoc &DLoc,
+ const Twine &Msg) {
+ Ctx.diagnose(DiagnosticInfoOptimizationRemarkAnalysisAliasing(PassName, Fn,
+ DLoc, Msg));
+}
+
bool DiagnosticInfoOptimizationFailure::isEnabled() const {
// Only print warnings.
return getSeverity() == DS_Warning;
diff --git a/contrib/llvm/lib/IR/Dominators.cpp b/contrib/llvm/lib/IR/Dominators.cpp
index b6a8bbcbe5fa..b9d4fb7de881 100644
--- a/contrib/llvm/lib/IR/Dominators.cpp
+++ b/contrib/llvm/lib/IR/Dominators.cpp
@@ -91,10 +91,10 @@ bool DominatorTree::dominates(const Instruction *Def,
if (Def == User)
return false;
- // The value defined by an invoke dominates an instruction only if
- // it dominates every instruction in UseBB.
- // A PHI is dominated only if the instruction dominates every possible use
- // in the UseBB.
+ // The value defined by an invoke dominates an instruction only if it
+ // dominates every instruction in UseBB.
+ // A PHI is dominated only if the instruction dominates every possible use in
+ // the UseBB.
if (isa<InvokeInst>(Def) || isa<PHINode>(User))
return dominates(Def, UseBB);
@@ -126,15 +126,15 @@ bool DominatorTree::dominates(const Instruction *Def,
if (DefBB == UseBB)
return false;
- const InvokeInst *II = dyn_cast<InvokeInst>(Def);
- if (!II)
- return dominates(DefBB, UseBB);
-
// Invoke results are only usable in the normal destination, not in the
// exceptional destination.
- BasicBlock *NormalDest = II->getNormalDest();
- BasicBlockEdge E(DefBB, NormalDest);
- return dominates(E, UseBB);
+ if (const auto *II = dyn_cast<InvokeInst>(Def)) {
+ BasicBlock *NormalDest = II->getNormalDest();
+ BasicBlockEdge E(DefBB, NormalDest);
+ return dominates(E, UseBB);
+ }
+
+ return dominates(DefBB, UseBB);
}
bool DominatorTree::dominates(const BasicBlockEdge &BBE,
@@ -142,7 +142,8 @@ bool DominatorTree::dominates(const BasicBlockEdge &BBE,
// Assert that we have a single edge. We could handle them by simply
// returning false, but since isSingleEdge is linear on the number of
// edges, the callers can normally handle them more efficiently.
- assert(BBE.isSingleEdge());
+ assert(BBE.isSingleEdge() &&
+ "This function is not efficient in handling multiple edges");
// If the BB the edge ends in doesn't dominate the use BB, then the
// edge also doesn't.
@@ -192,7 +193,8 @@ bool DominatorTree::dominates(const BasicBlockEdge &BBE, const Use &U) const {
// Assert that we have a single edge. We could handle them by simply
// returning false, but since isSingleEdge is linear on the number of
// edges, the callers can normally handle them more efficiently.
- assert(BBE.isSingleEdge());
+ assert(BBE.isSingleEdge() &&
+ "This function is not efficient in handling multiple edges");
Instruction *UserInst = cast<Instruction>(U.getUser());
// A PHI in the end of the edge is dominated by it.
@@ -232,8 +234,8 @@ bool DominatorTree::dominates(const Instruction *Def, const Use &U) const {
if (!isReachableFromEntry(DefBB))
return false;
- // Invoke instructions define their return values on the edges
- // to their normal successors, so we have to handle them specially.
+ // Invoke instructions define their return values on the edges to their normal
+ // successors, so we have to handle them specially.
// Among other things, this means they don't dominate anything in
// their own block, except possibly a phi, so we don't need to
// walk the block in any case.
diff --git a/contrib/llvm/lib/IR/Function.cpp b/contrib/llvm/lib/IR/Function.cpp
index b50ad1262c69..cfb40b19c733 100644
--- a/contrib/llvm/lib/IR/Function.cpp
+++ b/contrib/llvm/lib/IR/Function.cpp
@@ -35,8 +35,8 @@ using namespace llvm;
// Explicit instantiations of SymbolTableListTraits since some of the methods
// are not in the public header file...
-template class llvm::SymbolTableListTraits<Argument, Function>;
-template class llvm::SymbolTableListTraits<BasicBlock, Function>;
+template class llvm::SymbolTableListTraits<Argument>;
+template class llvm::SymbolTableListTraits<BasicBlock>;
//===----------------------------------------------------------------------===//
// Argument Implementation
@@ -235,11 +235,11 @@ Type *Function::getReturnType() const {
}
void Function::removeFromParent() {
- getParent()->getFunctionList().remove(this);
+ getParent()->getFunctionList().remove(getIterator());
}
void Function::eraseFromParent() {
- getParent()->getFunctionList().erase(this);
+ getParent()->getFunctionList().erase(getIterator());
}
//===----------------------------------------------------------------------===//
@@ -248,7 +248,7 @@ void Function::eraseFromParent() {
Function::Function(FunctionType *Ty, LinkageTypes Linkage, const Twine &name,
Module *ParentModule)
- : GlobalObject(PointerType::getUnqual(Ty), Value::FunctionVal,
+ : GlobalObject(Ty, Value::FunctionVal,
OperandTraits<Function>::op_begin(this), 0, Linkage, name),
Ty(Ty) {
assert(FunctionType::isValidReturnType(getReturnType()) &&
@@ -279,9 +279,6 @@ Function::~Function() {
// Remove the function from the on-the-side GC table.
clearGC();
-
- // FIXME: needed by operator delete
- setFunctionNumOperands(1);
}
void Function::BuildLazyArguments() const {
@@ -328,14 +325,15 @@ void Function::dropAllReferences() {
while (!BasicBlocks.empty())
BasicBlocks.begin()->eraseFromParent();
- // Prefix and prologue data are stored in a side table.
- setPrefixData(nullptr);
- setPrologueData(nullptr);
+ // Drop uses of any optional data (real or placeholder).
+ if (getNumOperands()) {
+ User::dropAllReferences();
+ setNumHungOffUseOperands(0);
+ setValueSubclassData(getSubclassDataFromValue() & ~0xe);
+ }
// Metadata is stored in a side-table.
clearMetadata();
-
- setPersonalityFn(nullptr);
}
void Function::addAttribute(unsigned i, Attribute::AttrKind attr) {
@@ -411,30 +409,26 @@ void Function::clearGC() {
}
}
-/// copyAttributesFrom - copy all additional attributes (those not needed to
-/// create a Function) from the Function Src to this one.
+/// Copy all additional attributes (those not needed to create a Function) from
+/// the Function Src to this one.
void Function::copyAttributesFrom(const GlobalValue *Src) {
- assert(isa<Function>(Src) && "Expected a Function!");
GlobalObject::copyAttributesFrom(Src);
- const Function *SrcF = cast<Function>(Src);
+ const Function *SrcF = dyn_cast<Function>(Src);
+ if (!SrcF)
+ return;
+
setCallingConv(SrcF->getCallingConv());
setAttributes(SrcF->getAttributes());
if (SrcF->hasGC())
setGC(SrcF->getGC());
else
clearGC();
+ if (SrcF->hasPersonalityFn())
+ setPersonalityFn(SrcF->getPersonalityFn());
if (SrcF->hasPrefixData())
setPrefixData(SrcF->getPrefixData());
- else
- setPrefixData(nullptr);
if (SrcF->hasPrologueData())
setPrologueData(SrcF->getPrologueData());
- else
- setPrologueData(nullptr);
- if (SrcF->hasPersonalityFn())
- setPersonalityFn(SrcF->getPersonalityFn());
- else
- setPersonalityFn(nullptr);
}
/// \brief This does the actual lookup of an intrinsic ID which
@@ -492,7 +486,10 @@ static std::string getMangledTypeStr(Type* Ty) {
Result += "vararg";
// Ensure nested function types are distinguishable.
Result += "f";
- } else if (Ty)
+ } else if (isa<VectorType>(Ty))
+ Result += "v" + utostr(Ty->getVectorNumElements()) +
+ getMangledTypeStr(Ty->getVectorElementType());
+ else if (Ty)
Result += EVT::getEVT(Ty).getEVTString();
return Result;
}
@@ -541,22 +538,25 @@ enum IIT_Info {
// Values from 16+ are only encodable with the inefficient encoding.
IIT_V64 = 16,
IIT_MMX = 17,
- IIT_METADATA = 18,
- IIT_EMPTYSTRUCT = 19,
- IIT_STRUCT2 = 20,
- IIT_STRUCT3 = 21,
- IIT_STRUCT4 = 22,
- IIT_STRUCT5 = 23,
- IIT_EXTEND_ARG = 24,
- IIT_TRUNC_ARG = 25,
- IIT_ANYPTR = 26,
- IIT_V1 = 27,
- IIT_VARARG = 28,
- IIT_HALF_VEC_ARG = 29,
- IIT_SAME_VEC_WIDTH_ARG = 30,
- IIT_PTR_TO_ARG = 31,
- IIT_VEC_OF_PTRS_TO_ELT = 32,
- IIT_I128 = 33
+ IIT_TOKEN = 18,
+ IIT_METADATA = 19,
+ IIT_EMPTYSTRUCT = 20,
+ IIT_STRUCT2 = 21,
+ IIT_STRUCT3 = 22,
+ IIT_STRUCT4 = 23,
+ IIT_STRUCT5 = 24,
+ IIT_EXTEND_ARG = 25,
+ IIT_TRUNC_ARG = 26,
+ IIT_ANYPTR = 27,
+ IIT_V1 = 28,
+ IIT_VARARG = 29,
+ IIT_HALF_VEC_ARG = 30,
+ IIT_SAME_VEC_WIDTH_ARG = 31,
+ IIT_PTR_TO_ARG = 32,
+ IIT_VEC_OF_PTRS_TO_ELT = 33,
+ IIT_I128 = 34,
+ IIT_V512 = 35,
+ IIT_V1024 = 36
};
@@ -576,6 +576,9 @@ static void DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos,
case IIT_MMX:
OutputTable.push_back(IITDescriptor::get(IITDescriptor::MMX, 0));
return;
+ case IIT_TOKEN:
+ OutputTable.push_back(IITDescriptor::get(IITDescriptor::Token, 0));
+ return;
case IIT_METADATA:
OutputTable.push_back(IITDescriptor::get(IITDescriptor::Metadata, 0));
return;
@@ -634,6 +637,14 @@ static void DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos,
OutputTable.push_back(IITDescriptor::get(IITDescriptor::Vector, 64));
DecodeIITType(NextElt, Infos, OutputTable);
return;
+ case IIT_V512:
+ OutputTable.push_back(IITDescriptor::get(IITDescriptor::Vector, 512));
+ DecodeIITType(NextElt, Infos, OutputTable);
+ return;
+ case IIT_V1024:
+ OutputTable.push_back(IITDescriptor::get(IITDescriptor::Vector, 1024));
+ DecodeIITType(NextElt, Infos, OutputTable);
+ return;
case IIT_PTR:
OutputTable.push_back(IITDescriptor::get(IITDescriptor::Pointer, 0));
DecodeIITType(NextElt, Infos, OutputTable);
@@ -751,6 +762,7 @@ static Type *DecodeFixedType(ArrayRef<Intrinsic::IITDescriptor> &Infos,
case IITDescriptor::Void: return Type::getVoidTy(Context);
case IITDescriptor::VarArg: return Type::getVoidTy(Context);
case IITDescriptor::MMX: return Type::getX86_MMXTy(Context);
+ case IITDescriptor::Token: return Type::getTokenTy(Context);
case IITDescriptor::Metadata: return Type::getMetadataTy(Context);
case IITDescriptor::Half: return Type::getHalfTy(Context);
case IITDescriptor::Float: return Type::getFloatTy(Context);
@@ -924,62 +936,68 @@ bool Function::callsFunctionThatReturnsTwice() const {
return false;
}
+Constant *Function::getPersonalityFn() const {
+ assert(hasPersonalityFn() && getNumOperands());
+ return cast<Constant>(Op<0>());
+}
+
+void Function::setPersonalityFn(Constant *Fn) {
+ setHungoffOperand<0>(Fn);
+ setValueSubclassDataBit(3, Fn != nullptr);
+}
+
Constant *Function::getPrefixData() const {
- assert(hasPrefixData());
- const LLVMContextImpl::PrefixDataMapTy &PDMap =
- getContext().pImpl->PrefixDataMap;
- assert(PDMap.find(this) != PDMap.end());
- return cast<Constant>(PDMap.find(this)->second->getReturnValue());
+ assert(hasPrefixData() && getNumOperands());
+ return cast<Constant>(Op<1>());
}
void Function::setPrefixData(Constant *PrefixData) {
- if (!PrefixData && !hasPrefixData())
- return;
-
- unsigned SCData = getSubclassDataFromValue();
- LLVMContextImpl::PrefixDataMapTy &PDMap = getContext().pImpl->PrefixDataMap;
- ReturnInst *&PDHolder = PDMap[this];
- if (PrefixData) {
- if (PDHolder)
- PDHolder->setOperand(0, PrefixData);
- else
- PDHolder = ReturnInst::Create(getContext(), PrefixData);
- SCData |= (1<<1);
- } else {
- delete PDHolder;
- PDMap.erase(this);
- SCData &= ~(1<<1);
- }
- setValueSubclassData(SCData);
+ setHungoffOperand<1>(PrefixData);
+ setValueSubclassDataBit(1, PrefixData != nullptr);
}
Constant *Function::getPrologueData() const {
- assert(hasPrologueData());
- const LLVMContextImpl::PrologueDataMapTy &SOMap =
- getContext().pImpl->PrologueDataMap;
- assert(SOMap.find(this) != SOMap.end());
- return cast<Constant>(SOMap.find(this)->second->getReturnValue());
+ assert(hasPrologueData() && getNumOperands());
+ return cast<Constant>(Op<2>());
}
void Function::setPrologueData(Constant *PrologueData) {
- if (!PrologueData && !hasPrologueData())
- return;
-
- unsigned PDData = getSubclassDataFromValue();
- LLVMContextImpl::PrologueDataMapTy &PDMap = getContext().pImpl->PrologueDataMap;
- ReturnInst *&PDHolder = PDMap[this];
- if (PrologueData) {
- if (PDHolder)
- PDHolder->setOperand(0, PrologueData);
- else
- PDHolder = ReturnInst::Create(getContext(), PrologueData);
- PDData |= (1<<2);
- } else {
- delete PDHolder;
- PDMap.erase(this);
- PDData &= ~(1<<2);
+ setHungoffOperand<2>(PrologueData);
+ setValueSubclassDataBit(2, PrologueData != nullptr);
+}
+
+void Function::allocHungoffUselist() {
+ // If we've already allocated a uselist, stop here.
+ if (getNumOperands())
+ return;
+
+ allocHungoffUses(3, /*IsPhi=*/ false);
+ setNumHungOffUseOperands(3);
+
+ // Initialize the uselist with placeholder operands to allow traversal.
+ auto *CPN = ConstantPointerNull::get(Type::getInt1PtrTy(getContext(), 0));
+ Op<0>().set(CPN);
+ Op<1>().set(CPN);
+ Op<2>().set(CPN);
+}
+
+template <int Idx>
+void Function::setHungoffOperand(Constant *C) {
+ if (C) {
+ allocHungoffUselist();
+ Op<Idx>().set(C);
+ } else if (getNumOperands()) {
+ Op<Idx>().set(
+ ConstantPointerNull::get(Type::getInt1PtrTy(getContext(), 0)));
}
- setValueSubclassData(PDData);
+}
+
+void Function::setValueSubclassDataBit(unsigned Bit, bool On) {
+ assert(Bit < 16 && "SubclassData contains only 16 bits");
+ if (On)
+ setValueSubclassData(getSubclassDataFromValue() | (1 << Bit));
+ else
+ setValueSubclassData(getSubclassDataFromValue() & ~(1 << Bit));
}
void Function::setEntryCount(uint64_t Count) {
@@ -997,22 +1015,3 @@ Optional<uint64_t> Function::getEntryCount() const {
}
return None;
}
-
-void Function::setPersonalityFn(Constant *C) {
- if (!C) {
- if (hasPersonalityFn()) {
- // Note, the num operands is used to compute the offset of the operand, so
- // the order here matters. Clearing the operand then clearing the num
- // operands ensures we have the correct offset to the operand.
- Op<0>().set(nullptr);
- setFunctionNumOperands(0);
- }
- } else {
- // Note, the num operands is used to compute the offset of the operand, so
- // the order here matters. We need to set num operands to 1 first so that
- // we get the correct offset to the first operand when we set it.
- if (!hasPersonalityFn())
- setFunctionNumOperands(1);
- Op<0>().set(C);
- }
-}
diff --git a/contrib/llvm/lib/IR/FunctionInfo.cpp b/contrib/llvm/lib/IR/FunctionInfo.cpp
new file mode 100644
index 000000000000..17a67bcf0472
--- /dev/null
+++ b/contrib/llvm/lib/IR/FunctionInfo.cpp
@@ -0,0 +1,67 @@
+//===-- FunctionInfo.cpp - Function Info Index ----------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the function info index and summary classes for the
+// IR library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/IR/FunctionInfo.h"
+#include "llvm/ADT/StringMap.h"
+using namespace llvm;
+
+// Create the combined function index/summary from multiple
+// per-module instances.
+void FunctionInfoIndex::mergeFrom(std::unique_ptr<FunctionInfoIndex> Other,
+ uint64_t NextModuleId) {
+
+ StringRef ModPath;
+ for (auto &OtherFuncInfoLists : *Other) {
+ std::string FuncName = OtherFuncInfoLists.getKey();
+ FunctionInfoList &List = OtherFuncInfoLists.second;
+
+ // Assert that the func info list only has one entry, since we shouldn't
+ // have duplicate names within a single per-module index.
+ assert(List.size() == 1);
+ std::unique_ptr<FunctionInfo> Info = std::move(List.front());
+
+ // Skip if there was no function summary section.
+ if (!Info->functionSummary())
+ continue;
+
+ // Add the module path string ref for this module if we haven't already
+ // saved a reference to it.
+ if (ModPath.empty())
+ ModPath =
+ addModulePath(Info->functionSummary()->modulePath(), NextModuleId);
+ else
+ assert(ModPath == Info->functionSummary()->modulePath() &&
+ "Each module in the combined map should have a unique ID");
+
+ // Note the module path string ref was copied above and is still owned by
+ // the original per-module index. Reset it to the new module path
+ // string reference owned by the combined index.
+ Info->functionSummary()->setModulePath(ModPath);
+
+ // If it is a local function, rename it.
+ if (Info->functionSummary()->isLocalFunction()) {
+ // Any local functions are virtually renamed when being added to the
+ // combined index map, to disambiguate from other functions with
+ // the same name. The symbol table created for the combined index
+ // file should contain the renamed symbols.
+ FuncName =
+ FunctionInfoIndex::getGlobalNameForLocal(FuncName, NextModuleId);
+ }
+
+ // Add new function info to existing list. There may be duplicates when
+ // combining FunctionMap entries, due to COMDAT functions. Any local
+ // functions were virtually renamed above.
+ addFunctionInfo(FuncName, std::move(Info));
+ }
+}
diff --git a/contrib/llvm/lib/IR/GCOV.cpp b/contrib/llvm/lib/IR/GCOV.cpp
index 6ed589131725..35b8157751b6 100644
--- a/contrib/llvm/lib/IR/GCOV.cpp
+++ b/contrib/llvm/lib/IR/GCOV.cpp
@@ -448,7 +448,7 @@ static uint32_t branchDiv(uint64_t Numerator, uint64_t Divisor) {
namespace {
struct formatBranchInfo {
- formatBranchInfo(const GCOVOptions &Options, uint64_t Count, uint64_t Total)
+ formatBranchInfo(const GCOV::Options &Options, uint64_t Count, uint64_t Total)
: Options(Options), Count(Count), Total(Total) {}
void print(raw_ostream &OS) const {
@@ -460,7 +460,7 @@ struct formatBranchInfo {
OS << "taken " << branchDiv(Count, Total) << "%";
}
- const GCOVOptions &Options;
+ const GCOV::Options &Options;
uint64_t Count;
uint64_t Total;
};
diff --git a/contrib/llvm/lib/IR/Globals.cpp b/contrib/llvm/lib/IR/Globals.cpp
index 1d0282677bf7..6159f93faf89 100644
--- a/contrib/llvm/lib/IR/Globals.cpp
+++ b/contrib/llvm/lib/IR/Globals.cpp
@@ -32,15 +32,9 @@ bool GlobalValue::isMaterializable() const {
return F->isMaterializable();
return false;
}
-bool GlobalValue::isDematerializable() const {
- return getParent() && getParent()->isDematerializable(this);
-}
std::error_code GlobalValue::materialize() {
return getParent()->materialize(this);
}
-void GlobalValue::dematerialize() {
- getParent()->dematerialize(this);
-}
/// Override destroyConstantImpl to make sure it doesn't get called on
/// GlobalValue's because they shouldn't be treated like other constants.
@@ -97,10 +91,11 @@ void GlobalObject::setGlobalObjectSubClassData(unsigned Val) {
}
void GlobalObject::copyAttributesFrom(const GlobalValue *Src) {
- const auto *GV = cast<GlobalObject>(Src);
- GlobalValue::copyAttributesFrom(GV);
- setAlignment(GV->getAlignment());
- setSection(GV->getSection());
+ GlobalValue::copyAttributesFrom(Src);
+ if (const auto *GV = dyn_cast<GlobalObject>(Src)) {
+ setAlignment(GV->getAlignment());
+ setSection(GV->getSection());
+ }
}
const char *GlobalValue::getSection() const {
@@ -147,9 +142,9 @@ GlobalVariable::GlobalVariable(Type *Ty, bool constant, LinkageTypes Link,
Constant *InitVal, const Twine &Name,
ThreadLocalMode TLMode, unsigned AddressSpace,
bool isExternallyInitialized)
- : GlobalObject(PointerType::get(Ty, AddressSpace), Value::GlobalVariableVal,
+ : GlobalObject(Ty, Value::GlobalVariableVal,
OperandTraits<GlobalVariable>::op_begin(this),
- InitVal != nullptr, Link, Name),
+ InitVal != nullptr, Link, Name, AddressSpace),
isConstantGlobal(constant),
isExternallyInitializedConstant(isExternallyInitialized) {
setThreadLocalMode(TLMode);
@@ -165,9 +160,9 @@ GlobalVariable::GlobalVariable(Module &M, Type *Ty, bool constant,
const Twine &Name, GlobalVariable *Before,
ThreadLocalMode TLMode, unsigned AddressSpace,
bool isExternallyInitialized)
- : GlobalObject(PointerType::get(Ty, AddressSpace), Value::GlobalVariableVal,
+ : GlobalObject(Ty, Value::GlobalVariableVal,
OperandTraits<GlobalVariable>::op_begin(this),
- InitVal != nullptr, Link, Name),
+ InitVal != nullptr, Link, Name, AddressSpace),
isConstantGlobal(constant),
isExternallyInitializedConstant(isExternallyInitialized) {
setThreadLocalMode(TLMode);
@@ -178,7 +173,7 @@ GlobalVariable::GlobalVariable(Module &M, Type *Ty, bool constant,
}
if (Before)
- Before->getParent()->getGlobalList().insert(Before, this);
+ Before->getParent()->getGlobalList().insert(Before->getIterator(), this);
else
M.getGlobalList().push_back(this);
}
@@ -188,11 +183,11 @@ void GlobalVariable::setParent(Module *parent) {
}
void GlobalVariable::removeFromParent() {
- getParent()->getGlobalList().remove(this);
+ getParent()->getGlobalList().remove(getIterator());
}
void GlobalVariable::eraseFromParent() {
- getParent()->getGlobalList().erase(this);
+ getParent()->getGlobalList().erase(getIterator());
}
void GlobalVariable::setInitializer(Constant *InitVal) {
@@ -216,14 +211,14 @@ void GlobalVariable::setInitializer(Constant *InitVal) {
}
}
-/// copyAttributesFrom - copy all additional attributes (those not needed to
-/// create a GlobalVariable) from the GlobalVariable Src to this one.
+/// Copy all additional attributes (those not needed to create a GlobalVariable)
+/// from the GlobalVariable Src to this one.
void GlobalVariable::copyAttributesFrom(const GlobalValue *Src) {
- assert(isa<GlobalVariable>(Src) && "Expected a GlobalVariable!");
GlobalObject::copyAttributesFrom(Src);
- const GlobalVariable *SrcVar = cast<GlobalVariable>(Src);
- setThreadLocalMode(SrcVar->getThreadLocalMode());
- setExternallyInitialized(SrcVar->isExternallyInitialized());
+ if (const GlobalVariable *SrcVar = dyn_cast<GlobalVariable>(Src)) {
+ setThreadLocalMode(SrcVar->getThreadLocalMode());
+ setExternallyInitialized(SrcVar->isExternallyInitialized());
+ }
}
@@ -231,35 +226,40 @@ void GlobalVariable::copyAttributesFrom(const GlobalValue *Src) {
// GlobalAlias Implementation
//===----------------------------------------------------------------------===//
-GlobalAlias::GlobalAlias(PointerType *Ty, LinkageTypes Link, const Twine &Name,
- Constant *Aliasee, Module *ParentModule)
- : GlobalValue(Ty, Value::GlobalAliasVal, &Op<0>(), 1, Link, Name) {
+GlobalAlias::GlobalAlias(Type *Ty, unsigned AddressSpace, LinkageTypes Link,
+ const Twine &Name, Constant *Aliasee,
+ Module *ParentModule)
+ : GlobalValue(Ty, Value::GlobalAliasVal, &Op<0>(), 1, Link, Name,
+ AddressSpace) {
Op<0>() = Aliasee;
if (ParentModule)
ParentModule->getAliasList().push_back(this);
}
-GlobalAlias *GlobalAlias::create(PointerType *Ty, LinkageTypes Link,
- const Twine &Name, Constant *Aliasee,
- Module *ParentModule) {
- return new GlobalAlias(Ty, Link, Name, Aliasee, ParentModule);
+GlobalAlias *GlobalAlias::create(Type *Ty, unsigned AddressSpace,
+ LinkageTypes Link, const Twine &Name,
+ Constant *Aliasee, Module *ParentModule) {
+ return new GlobalAlias(Ty, AddressSpace, Link, Name, Aliasee, ParentModule);
}
-GlobalAlias *GlobalAlias::create(PointerType *Ty, LinkageTypes Linkage,
- const Twine &Name, Module *Parent) {
- return create(Ty, Linkage, Name, nullptr, Parent);
+GlobalAlias *GlobalAlias::create(Type *Ty, unsigned AddressSpace,
+ LinkageTypes Linkage, const Twine &Name,
+ Module *Parent) {
+ return create(Ty, AddressSpace, Linkage, Name, nullptr, Parent);
}
-GlobalAlias *GlobalAlias::create(PointerType *Ty, LinkageTypes Linkage,
- const Twine &Name, GlobalValue *Aliasee) {
- return create(Ty, Linkage, Name, Aliasee, Aliasee->getParent());
+GlobalAlias *GlobalAlias::create(Type *Ty, unsigned AddressSpace,
+ LinkageTypes Linkage, const Twine &Name,
+ GlobalValue *Aliasee) {
+ return create(Ty, AddressSpace, Linkage, Name, Aliasee, Aliasee->getParent());
}
GlobalAlias *GlobalAlias::create(LinkageTypes Link, const Twine &Name,
GlobalValue *Aliasee) {
PointerType *PTy = Aliasee->getType();
- return create(PTy, Link, Name, Aliasee);
+ return create(PTy->getElementType(), PTy->getAddressSpace(), Link, Name,
+ Aliasee);
}
GlobalAlias *GlobalAlias::create(const Twine &Name, GlobalValue *Aliasee) {
@@ -271,11 +271,11 @@ void GlobalAlias::setParent(Module *parent) {
}
void GlobalAlias::removeFromParent() {
- getParent()->getAliasList().remove(this);
+ getParent()->getAliasList().remove(getIterator());
}
void GlobalAlias::eraseFromParent() {
- getParent()->getAliasList().erase(this);
+ getParent()->getAliasList().erase(getIterator());
}
void GlobalAlias::setAliasee(Constant *Aliasee) {
diff --git a/contrib/llvm/lib/IR/IRBuilder.cpp b/contrib/llvm/lib/IR/IRBuilder.cpp
index bddb278dee79..447412936335 100644
--- a/contrib/llvm/lib/IR/IRBuilder.cpp
+++ b/contrib/llvm/lib/IR/IRBuilder.cpp
@@ -247,18 +247,21 @@ CallInst *IRBuilderBase::CreateMaskedIntrinsic(Intrinsic::ID Id,
return createCallHelper(TheFn, Ops, this, Name);
}
+template <typename T0, typename T1, typename T2, typename T3>
static std::vector<Value *>
getStatepointArgs(IRBuilderBase &B, uint64_t ID, uint32_t NumPatchBytes,
- Value *ActualCallee, ArrayRef<Value *> CallArgs,
- ArrayRef<Value *> DeoptArgs, ArrayRef<Value *> GCArgs) {
+ Value *ActualCallee, uint32_t Flags, ArrayRef<T0> CallArgs,
+ ArrayRef<T1> TransitionArgs, ArrayRef<T2> DeoptArgs,
+ ArrayRef<T3> GCArgs) {
std::vector<Value *> Args;
Args.push_back(B.getInt64(ID));
Args.push_back(B.getInt32(NumPatchBytes));
Args.push_back(ActualCallee);
Args.push_back(B.getInt32(CallArgs.size()));
- Args.push_back(B.getInt32((unsigned)StatepointFlags::None));
+ Args.push_back(B.getInt32(Flags));
Args.insert(Args.end(), CallArgs.begin(), CallArgs.end());
- Args.push_back(B.getInt32(0 /* no transition args */));
+ Args.push_back(B.getInt32(TransitionArgs.size()));
+ Args.insert(Args.end(), TransitionArgs.begin(), TransitionArgs.end());
Args.push_back(B.getInt32(DeoptArgs.size()));
Args.insert(Args.end(), DeoptArgs.begin(), DeoptArgs.end());
Args.insert(Args.end(), GCArgs.begin(), GCArgs.end());
@@ -266,69 +269,109 @@ getStatepointArgs(IRBuilderBase &B, uint64_t ID, uint32_t NumPatchBytes,
return Args;
}
-CallInst *IRBuilderBase::CreateGCStatepointCall(
- uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee,
- ArrayRef<Value *> CallArgs, ArrayRef<Value *> DeoptArgs,
- ArrayRef<Value *> GCArgs, const Twine &Name) {
+template <typename T0, typename T1, typename T2, typename T3>
+static CallInst *CreateGCStatepointCallCommon(
+ IRBuilderBase *Builder, uint64_t ID, uint32_t NumPatchBytes,
+ Value *ActualCallee, uint32_t Flags, ArrayRef<T0> CallArgs,
+ ArrayRef<T1> TransitionArgs, ArrayRef<T2> DeoptArgs, ArrayRef<T3> GCArgs,
+ const Twine &Name) {
// Extract out the type of the callee.
PointerType *FuncPtrType = cast<PointerType>(ActualCallee->getType());
assert(isa<FunctionType>(FuncPtrType->getElementType()) &&
"actual callee must be a callable value");
- Module *M = BB->getParent()->getParent();
+ Module *M = Builder->GetInsertBlock()->getParent()->getParent();
// Fill in the one generic type'd argument (the function is also vararg)
Type *ArgTypes[] = { FuncPtrType };
Function *FnStatepoint =
Intrinsic::getDeclaration(M, Intrinsic::experimental_gc_statepoint,
ArgTypes);
- std::vector<llvm::Value *> Args = getStatepointArgs(
- *this, ID, NumPatchBytes, ActualCallee, CallArgs, DeoptArgs, GCArgs);
- return createCallHelper(FnStatepoint, Args, this, Name);
+ std::vector<llvm::Value *> Args =
+ getStatepointArgs(*Builder, ID, NumPatchBytes, ActualCallee, Flags,
+ CallArgs, TransitionArgs, DeoptArgs, GCArgs);
+ return createCallHelper(FnStatepoint, Args, Builder, Name);
}
CallInst *IRBuilderBase::CreateGCStatepointCall(
uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee,
- ArrayRef<Use> CallArgs, ArrayRef<Value *> DeoptArgs,
+ ArrayRef<Value *> CallArgs, ArrayRef<Value *> DeoptArgs,
ArrayRef<Value *> GCArgs, const Twine &Name) {
- std::vector<Value *> VCallArgs;
- for (auto &U : CallArgs)
- VCallArgs.push_back(U.get());
- return CreateGCStatepointCall(ID, NumPatchBytes, ActualCallee, VCallArgs,
- DeoptArgs, GCArgs, Name);
+ return CreateGCStatepointCallCommon<Value *, Value *, Value *, Value *>(
+ this, ID, NumPatchBytes, ActualCallee, uint32_t(StatepointFlags::None),
+ CallArgs, None /* No Transition Args */, DeoptArgs, GCArgs, Name);
}
-InvokeInst *IRBuilderBase::CreateGCStatepointInvoke(
- uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee,
- BasicBlock *NormalDest, BasicBlock *UnwindDest,
- ArrayRef<Value *> InvokeArgs, ArrayRef<Value *> DeoptArgs,
+CallInst *IRBuilderBase::CreateGCStatepointCall(
+ uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee, uint32_t Flags,
+ ArrayRef<Use> CallArgs, ArrayRef<Use> TransitionArgs,
+ ArrayRef<Use> DeoptArgs, ArrayRef<Value *> GCArgs, const Twine &Name) {
+ return CreateGCStatepointCallCommon<Use, Use, Use, Value *>(
+ this, ID, NumPatchBytes, ActualCallee, Flags, CallArgs, TransitionArgs,
+ DeoptArgs, GCArgs, Name);
+}
+
+CallInst *IRBuilderBase::CreateGCStatepointCall(
+ uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee,
+ ArrayRef<Use> CallArgs, ArrayRef<Value *> DeoptArgs,
ArrayRef<Value *> GCArgs, const Twine &Name) {
+ return CreateGCStatepointCallCommon<Use, Value *, Value *, Value *>(
+ this, ID, NumPatchBytes, ActualCallee, uint32_t(StatepointFlags::None),
+ CallArgs, None, DeoptArgs, GCArgs, Name);
+}
+
+template <typename T0, typename T1, typename T2, typename T3>
+static InvokeInst *CreateGCStatepointInvokeCommon(
+ IRBuilderBase *Builder, uint64_t ID, uint32_t NumPatchBytes,
+ Value *ActualInvokee, BasicBlock *NormalDest, BasicBlock *UnwindDest,
+ uint32_t Flags, ArrayRef<T0> InvokeArgs, ArrayRef<T1> TransitionArgs,
+ ArrayRef<T2> DeoptArgs, ArrayRef<T3> GCArgs, const Twine &Name) {
// Extract out the type of the callee.
PointerType *FuncPtrType = cast<PointerType>(ActualInvokee->getType());
assert(isa<FunctionType>(FuncPtrType->getElementType()) &&
"actual callee must be a callable value");
- Module *M = BB->getParent()->getParent();
+ Module *M = Builder->GetInsertBlock()->getParent()->getParent();
// Fill in the one generic type'd argument (the function is also vararg)
Function *FnStatepoint = Intrinsic::getDeclaration(
M, Intrinsic::experimental_gc_statepoint, {FuncPtrType});
- std::vector<llvm::Value *> Args = getStatepointArgs(
- *this, ID, NumPatchBytes, ActualInvokee, InvokeArgs, DeoptArgs, GCArgs);
- return createInvokeHelper(FnStatepoint, NormalDest, UnwindDest, Args, this,
+ std::vector<llvm::Value *> Args =
+ getStatepointArgs(*Builder, ID, NumPatchBytes, ActualInvokee, Flags,
+ InvokeArgs, TransitionArgs, DeoptArgs, GCArgs);
+ return createInvokeHelper(FnStatepoint, NormalDest, UnwindDest, Args, Builder,
Name);
}
InvokeInst *IRBuilderBase::CreateGCStatepointInvoke(
uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee,
+ BasicBlock *NormalDest, BasicBlock *UnwindDest,
+ ArrayRef<Value *> InvokeArgs, ArrayRef<Value *> DeoptArgs,
+ ArrayRef<Value *> GCArgs, const Twine &Name) {
+ return CreateGCStatepointInvokeCommon<Value *, Value *, Value *, Value *>(
+ this, ID, NumPatchBytes, ActualInvokee, NormalDest, UnwindDest,
+ uint32_t(StatepointFlags::None), InvokeArgs, None /* No Transition Args*/,
+ DeoptArgs, GCArgs, Name);
+}
+
+InvokeInst *IRBuilderBase::CreateGCStatepointInvoke(
+ uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee,
+ BasicBlock *NormalDest, BasicBlock *UnwindDest, uint32_t Flags,
+ ArrayRef<Use> InvokeArgs, ArrayRef<Use> TransitionArgs,
+ ArrayRef<Use> DeoptArgs, ArrayRef<Value *> GCArgs, const Twine &Name) {
+ return CreateGCStatepointInvokeCommon<Use, Use, Use, Value *>(
+ this, ID, NumPatchBytes, ActualInvokee, NormalDest, UnwindDest, Flags,
+ InvokeArgs, TransitionArgs, DeoptArgs, GCArgs, Name);
+}
+
+InvokeInst *IRBuilderBase::CreateGCStatepointInvoke(
+ uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee,
BasicBlock *NormalDest, BasicBlock *UnwindDest, ArrayRef<Use> InvokeArgs,
ArrayRef<Value *> DeoptArgs, ArrayRef<Value *> GCArgs, const Twine &Name) {
- std::vector<Value *> VCallArgs;
- for (auto &U : InvokeArgs)
- VCallArgs.push_back(U.get());
- return CreateGCStatepointInvoke(ID, NumPatchBytes, ActualInvokee, NormalDest,
- UnwindDest, VCallArgs, DeoptArgs, GCArgs,
- Name);
+ return CreateGCStatepointInvokeCommon<Use, Value *, Value *, Value *>(
+ this, ID, NumPatchBytes, ActualInvokee, NormalDest, UnwindDest,
+ uint32_t(StatepointFlags::None), InvokeArgs, None, DeoptArgs, GCArgs,
+ Name);
}
CallInst *IRBuilderBase::CreateGCResult(Instruction *Statepoint,
diff --git a/contrib/llvm/lib/IR/InlineAsm.cpp b/contrib/llvm/lib/IR/InlineAsm.cpp
index aa9e0272ad10..15d3b830b8fc 100644
--- a/contrib/llvm/lib/IR/InlineAsm.cpp
+++ b/contrib/llvm/lib/IR/InlineAsm.cpp
@@ -24,23 +24,22 @@ using namespace llvm;
InlineAsm::~InlineAsm() {
}
-
-InlineAsm *InlineAsm::get(FunctionType *Ty, StringRef AsmString,
+InlineAsm *InlineAsm::get(FunctionType *FTy, StringRef AsmString,
StringRef Constraints, bool hasSideEffects,
bool isAlignStack, AsmDialect asmDialect) {
- InlineAsmKeyType Key(AsmString, Constraints, hasSideEffects, isAlignStack,
- asmDialect);
- LLVMContextImpl *pImpl = Ty->getContext().pImpl;
- return pImpl->InlineAsms.getOrCreate(PointerType::getUnqual(Ty), Key);
+ InlineAsmKeyType Key(AsmString, Constraints, FTy, hasSideEffects,
+ isAlignStack, asmDialect);
+ LLVMContextImpl *pImpl = FTy->getContext().pImpl;
+ return pImpl->InlineAsms.getOrCreate(PointerType::getUnqual(FTy), Key);
}
-InlineAsm::InlineAsm(PointerType *Ty, const std::string &asmString,
+InlineAsm::InlineAsm(FunctionType *FTy, const std::string &asmString,
const std::string &constraints, bool hasSideEffects,
bool isAlignStack, AsmDialect asmDialect)
- : Value(Ty, Value::InlineAsmVal),
- AsmString(asmString), Constraints(constraints),
- HasSideEffects(hasSideEffects), IsAlignStack(isAlignStack),
- Dialect(asmDialect) {
+ : Value(PointerType::getUnqual(FTy), Value::InlineAsmVal),
+ AsmString(asmString), Constraints(constraints), FTy(FTy),
+ HasSideEffects(hasSideEffects), IsAlignStack(isAlignStack),
+ Dialect(asmDialect) {
// Do various checks on the constraint string and type.
assert(Verify(getFunctionType(), constraints) &&
@@ -53,7 +52,7 @@ void InlineAsm::destroyConstant() {
}
FunctionType *InlineAsm::getFunctionType() const {
- return cast<FunctionType>(getType()->getElementType());
+ return FTy;
}
///Default constructor.
@@ -160,6 +159,9 @@ bool InlineAsm::ConstraintInfo::Parse(StringRef Str,
// If Operand N already has a matching input, reject this. An output
// can't be constrained to the same value as multiple inputs.
if (isMultipleAlternative) {
+ if (multipleAlternativeIndex >=
+ ConstraintsSoFar[N].multipleAlternatives.size())
+ return true;
InlineAsm::SubConstraintInfo &scInfo =
ConstraintsSoFar[N].multipleAlternatives[multipleAlternativeIndex];
if (scInfo.MatchingInput != -1)
@@ -291,4 +293,3 @@ bool InlineAsm::Verify(FunctionType *Ty, StringRef ConstStr) {
if (Ty->getNumParams() != NumInputs) return false;
return true;
}
-
diff --git a/contrib/llvm/lib/IR/Instruction.cpp b/contrib/llvm/lib/IR/Instruction.cpp
index c57ba16cf6ca..a0bd2c9698e8 100644
--- a/contrib/llvm/lib/IR/Instruction.cpp
+++ b/contrib/llvm/lib/IR/Instruction.cpp
@@ -28,7 +28,7 @@ Instruction::Instruction(Type *ty, unsigned it, Use *Ops, unsigned NumOps,
if (InsertBefore) {
BasicBlock *BB = InsertBefore->getParent();
assert(BB && "Instruction to insert before is not in a basic block!");
- BB->getInstList().insert(InsertBefore, this);
+ BB->getInstList().insert(InsertBefore->getIterator(), this);
}
}
@@ -62,33 +62,39 @@ Module *Instruction::getModule() {
return getParent()->getModule();
}
+Function *Instruction::getFunction() { return getParent()->getParent(); }
+
+const Function *Instruction::getFunction() const {
+ return getParent()->getParent();
+}
void Instruction::removeFromParent() {
- getParent()->getInstList().remove(this);
+ getParent()->getInstList().remove(getIterator());
}
iplist<Instruction>::iterator Instruction::eraseFromParent() {
- return getParent()->getInstList().erase(this);
+ return getParent()->getInstList().erase(getIterator());
}
/// insertBefore - Insert an unlinked instructions into a basic block
/// immediately before the specified instruction.
void Instruction::insertBefore(Instruction *InsertPos) {
- InsertPos->getParent()->getInstList().insert(InsertPos, this);
+ InsertPos->getParent()->getInstList().insert(InsertPos->getIterator(), this);
}
/// insertAfter - Insert an unlinked instructions into a basic block
/// immediately after the specified instruction.
void Instruction::insertAfter(Instruction *InsertPos) {
- InsertPos->getParent()->getInstList().insertAfter(InsertPos, this);
+ InsertPos->getParent()->getInstList().insertAfter(InsertPos->getIterator(),
+ this);
}
/// moveBefore - Unlink this instruction from its current basic block and
/// insert it into the basic block that MovePos lives in, right before
/// MovePos.
void Instruction::moveBefore(Instruction *MovePos) {
- MovePos->getParent()->getInstList().splice(MovePos,getParent()->getInstList(),
- this);
+ MovePos->getParent()->getInstList().splice(
+ MovePos->getIterator(), getParent()->getInstList(), getIterator());
}
/// Set or clear the unsafe-algebra flag on this instruction, which must be an
@@ -196,6 +202,10 @@ const char *Instruction::getOpcodeName(unsigned OpCode) {
case Invoke: return "invoke";
case Resume: return "resume";
case Unreachable: return "unreachable";
+ case CleanupRet: return "cleanupret";
+ case CatchRet: return "catchret";
+ case CatchPad: return "catchpad";
+ case CatchSwitch: return "catchswitch";
// Standard binary operators...
case Add: return "add";
@@ -256,6 +266,7 @@ const char *Instruction::getOpcodeName(unsigned OpCode) {
case ExtractValue: return "extractvalue";
case InsertValue: return "insertvalue";
case LandingPad: return "landingpad";
+ case CleanupPad: return "cleanuppad";
default: return "<Invalid operator> ";
}
@@ -285,11 +296,12 @@ static bool haveSameSpecialState(const Instruction *I1, const Instruction *I2,
if (const CallInst *CI = dyn_cast<CallInst>(I1))
return CI->isTailCall() == cast<CallInst>(I2)->isTailCall() &&
CI->getCallingConv() == cast<CallInst>(I2)->getCallingConv() &&
- CI->getAttributes() == cast<CallInst>(I2)->getAttributes();
+ CI->getAttributes() == cast<CallInst>(I2)->getAttributes() &&
+ CI->hasIdenticalOperandBundleSchema(*cast<CallInst>(I2));
if (const InvokeInst *CI = dyn_cast<InvokeInst>(I1))
return CI->getCallingConv() == cast<InvokeInst>(I2)->getCallingConv() &&
- CI->getAttributes() ==
- cast<InvokeInst>(I2)->getAttributes();
+ CI->getAttributes() == cast<InvokeInst>(I2)->getAttributes() &&
+ CI->hasIdenticalOperandBundleSchema(*cast<InvokeInst>(I2));
if (const InsertValueInst *IVI = dyn_cast<InsertValueInst>(I1))
return IVI->getIndices() == cast<InsertValueInst>(I2)->getIndices();
if (const ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(I1))
@@ -407,6 +419,8 @@ bool Instruction::mayReadFromMemory() const {
case Instruction::Fence: // FIXME: refine definition of mayReadFromMemory
case Instruction::AtomicCmpXchg:
case Instruction::AtomicRMW:
+ case Instruction::CatchPad:
+ case Instruction::CatchRet:
return true;
case Instruction::Call:
return !cast<CallInst>(this)->doesNotAccessMemory();
@@ -427,6 +441,8 @@ bool Instruction::mayWriteToMemory() const {
case Instruction::VAArg:
case Instruction::AtomicCmpXchg:
case Instruction::AtomicRMW:
+ case Instruction::CatchPad:
+ case Instruction::CatchRet:
return true;
case Instruction::Call:
return !cast<CallInst>(this)->onlyReadsMemory();
@@ -455,6 +471,10 @@ bool Instruction::isAtomic() const {
bool Instruction::mayThrow() const {
if (const CallInst *CI = dyn_cast<CallInst>(this))
return !CI->doesNotThrow();
+ if (const auto *CRI = dyn_cast<CleanupReturnInst>(this))
+ return CRI->unwindsToCaller();
+ if (const auto *CatchSwitch = dyn_cast<CatchSwitchInst>(this))
+ return CatchSwitch->unwindsToCaller();
return isa<ResumeInst>(this);
}
diff --git a/contrib/llvm/lib/IR/Instructions.cpp b/contrib/llvm/lib/IR/Instructions.cpp
index 86c921aeda8a..4ae2fd522b52 100644
--- a/contrib/llvm/lib/IR/Instructions.cpp
+++ b/contrib/llvm/lib/IR/Instructions.cpp
@@ -62,7 +62,10 @@ UnaryInstruction::~UnaryInstruction() {
const char *SelectInst::areInvalidOperands(Value *Op0, Value *Op1, Value *Op2) {
if (Op1->getType() != Op2->getType())
return "both values to select must have same type";
-
+
+ if (Op1->getType()->isTokenTy())
+ return "select values cannot have token type";
+
if (VectorType *VT = dyn_cast<VectorType>(Op0->getType())) {
// Vector select.
if (VT->getElementType() != Type::getInt1Ty(Op0->getContext()))
@@ -84,6 +87,8 @@ const char *SelectInst::areInvalidOperands(Value *Op0, Value *Op1, Value *Op2) {
// PHINode Class
//===----------------------------------------------------------------------===//
+void PHINode::anchor() {}
+
PHINode::PHINode(const PHINode &PN)
: Instruction(PN.getType(), Instruction::PHI, nullptr, PN.getNumOperands()),
ReservedSpace(PN.getNumOperands()) {
@@ -223,9 +228,10 @@ CallInst::~CallInst() {
}
void CallInst::init(FunctionType *FTy, Value *Func, ArrayRef<Value *> Args,
- const Twine &NameStr) {
+ ArrayRef<OperandBundleDef> Bundles, const Twine &NameStr) {
this->FTy = FTy;
- assert(getNumOperands() == Args.size() + 1 && "NumOperands not set up?");
+ assert(getNumOperands() == Args.size() + CountBundleInputs(Bundles) + 1 &&
+ "NumOperands not set up?");
Op<-1>() = Func;
#ifndef NDEBUG
@@ -240,6 +246,11 @@ void CallInst::init(FunctionType *FTy, Value *Func, ArrayRef<Value *> Args,
#endif
std::copy(Args.begin(), Args.end(), op_begin());
+
+ auto It = populateBundleOperandInfos(Bundles, Args.size());
+ (void)It;
+ assert(It + 1 == op_end() && "Should add up!");
+
setName(NameStr);
}
@@ -281,11 +292,26 @@ CallInst::CallInst(const CallInst &CI)
AttributeList(CI.AttributeList), FTy(CI.FTy) {
setTailCallKind(CI.getTailCallKind());
setCallingConv(CI.getCallingConv());
-
+
std::copy(CI.op_begin(), CI.op_end(), op_begin());
+ std::copy(CI.bundle_op_info_begin(), CI.bundle_op_info_end(),
+ bundle_op_info_begin());
SubclassOptionalData = CI.SubclassOptionalData;
}
+CallInst *CallInst::Create(CallInst *CI, ArrayRef<OperandBundleDef> OpB,
+ Instruction *InsertPt) {
+ std::vector<Value *> Args(CI->arg_begin(), CI->arg_end());
+
+ auto *NewCI = CallInst::Create(CI->getCalledValue(), Args, OpB, CI->getName(),
+ InsertPt);
+ NewCI->setTailCallKind(CI->getTailCallKind());
+ NewCI->setCallingConv(CI->getCallingConv());
+ NewCI->SubclassOptionalData = CI->SubclassOptionalData;
+ NewCI->setAttributes(CI->getAttributes());
+ return NewCI;
+}
+
void CallInst::addAttribute(unsigned i, Attribute::AttrKind attr) {
AttributeSet PAL = getAttributes();
PAL = PAL.addAttribute(getContext(), i, attr);
@@ -320,6 +346,8 @@ void CallInst::addDereferenceableOrNullAttr(unsigned i, uint64_t Bytes) {
}
bool CallInst::paramHasAttr(unsigned i, Attribute::AttrKind A) const {
+ assert(i < (getNumArgOperands() + 1) && "Param index out of bounds!");
+
if (AttributeList.hasAttribute(i, A))
return true;
if (const Function *F = getCalledFunction())
@@ -327,6 +355,25 @@ bool CallInst::paramHasAttr(unsigned i, Attribute::AttrKind A) const {
return false;
}
+bool CallInst::dataOperandHasImpliedAttr(unsigned i,
+ Attribute::AttrKind A) const {
+
+ // There are getNumOperands() - 1 data operands. The last operand is the
+ // callee.
+ assert(i < getNumOperands() && "Data operand index out of bounds!");
+
+ // The attribute A can either be directly specified, if the operand in
+ // question is a call argument; or be indirectly implied by the kind of its
+ // containing operand bundle, if the operand is a bundle operand.
+
+ if (i < (getNumArgOperands() + 1))
+ return paramHasAttr(i, A);
+
+ assert(hasOperandBundles() && i >= (getBundleOperandsStartIndex() + 1) &&
+ "Must be either a call argument or an operand bundle!");
+ return bundleOperandHasAttr(i - 1, A);
+}
+
/// IsConstantOne - Return true only if val is constant int 1
static bool IsConstantOne(Value *val) {
assert(val && "IsConstantOne does not work with nullptr val");
@@ -496,10 +543,12 @@ Instruction* CallInst::CreateFree(Value* Source, BasicBlock *InsertAtEnd) {
void InvokeInst::init(FunctionType *FTy, Value *Fn, BasicBlock *IfNormal,
BasicBlock *IfException, ArrayRef<Value *> Args,
+ ArrayRef<OperandBundleDef> Bundles,
const Twine &NameStr) {
this->FTy = FTy;
- assert(getNumOperands() == 3 + Args.size() && "NumOperands not set up?");
+ assert(getNumOperands() == 3 + Args.size() + CountBundleInputs(Bundles) &&
+ "NumOperands not set up?");
Op<-3>() = Fn;
Op<-2>() = IfNormal;
Op<-1>() = IfException;
@@ -516,6 +565,11 @@ void InvokeInst::init(FunctionType *FTy, Value *Fn, BasicBlock *IfNormal,
#endif
std::copy(Args.begin(), Args.end(), op_begin());
+
+ auto It = populateBundleOperandInfos(Bundles, Args.size());
+ (void)It;
+ assert(It + 3 == op_end() && "Should add up!");
+
setName(NameStr);
}
@@ -527,9 +581,24 @@ InvokeInst::InvokeInst(const InvokeInst &II)
AttributeList(II.AttributeList), FTy(II.FTy) {
setCallingConv(II.getCallingConv());
std::copy(II.op_begin(), II.op_end(), op_begin());
+ std::copy(II.bundle_op_info_begin(), II.bundle_op_info_end(),
+ bundle_op_info_begin());
SubclassOptionalData = II.SubclassOptionalData;
}
+InvokeInst *InvokeInst::Create(InvokeInst *II, ArrayRef<OperandBundleDef> OpB,
+ Instruction *InsertPt) {
+ std::vector<Value *> Args(II->arg_begin(), II->arg_end());
+
+ auto *NewII = InvokeInst::Create(II->getCalledValue(), II->getNormalDest(),
+ II->getUnwindDest(), Args, OpB,
+ II->getName(), InsertPt);
+ NewII->setCallingConv(II->getCallingConv());
+ NewII->SubclassOptionalData = II->SubclassOptionalData;
+ NewII->setAttributes(II->getAttributes());
+ return NewII;
+}
+
BasicBlock *InvokeInst::getSuccessorV(unsigned idx) const {
return getSuccessor(idx);
}
@@ -543,12 +612,20 @@ void InvokeInst::setSuccessorV(unsigned idx, BasicBlock *B) {
bool InvokeInst::hasFnAttrImpl(Attribute::AttrKind A) const {
if (AttributeList.hasAttribute(AttributeSet::FunctionIndex, A))
return true;
+
+ // Operand bundles override attributes on the called function, but don't
+ // override attributes directly present on the invoke instruction.
+ if (isFnAttrDisallowedByOpBundle(A))
+ return false;
+
if (const Function *F = getCalledFunction())
return F->getAttributes().hasAttribute(AttributeSet::FunctionIndex, A);
return false;
}
bool InvokeInst::paramHasAttr(unsigned i, Attribute::AttrKind A) const {
+ assert(i < (getNumArgOperands() + 1) && "Param index out of bounds!");
+
if (AttributeList.hasAttribute(i, A))
return true;
if (const Function *F = getCalledFunction())
@@ -556,6 +633,24 @@ bool InvokeInst::paramHasAttr(unsigned i, Attribute::AttrKind A) const {
return false;
}
+bool InvokeInst::dataOperandHasImpliedAttr(unsigned i,
+ Attribute::AttrKind A) const {
+ // There are getNumOperands() - 3 data operands. The last three operands are
+ // the callee and the two successor basic blocks.
+ assert(i < (getNumOperands() - 2) && "Data operand index out of bounds!");
+
+ // The attribute A can either be directly specified, if the operand in
+ // question is an invoke argument; or be indirectly implied by the kind of its
+ // containing operand bundle, if the operand is a bundle operand.
+
+ if (i < (getNumArgOperands() + 1))
+ return paramHasAttr(i, A);
+
+ assert(hasOperandBundles() && i >= (getBundleOperandsStartIndex() + 1) &&
+ "Must be either an invoke argument or an operand bundle!");
+ return bundleOperandHasAttr(i - 1, A);
+}
+
void InvokeInst::addAttribute(unsigned i, Attribute::AttrKind attr) {
AttributeSet PAL = getAttributes();
PAL = PAL.addAttribute(getContext(), i, attr);
@@ -671,6 +766,223 @@ BasicBlock *ResumeInst::getSuccessorV(unsigned idx) const {
}
//===----------------------------------------------------------------------===//
+// CleanupReturnInst Implementation
+//===----------------------------------------------------------------------===//
+
+CleanupReturnInst::CleanupReturnInst(const CleanupReturnInst &CRI)
+ : TerminatorInst(CRI.getType(), Instruction::CleanupRet,
+ OperandTraits<CleanupReturnInst>::op_end(this) -
+ CRI.getNumOperands(),
+ CRI.getNumOperands()) {
+ setInstructionSubclassData(CRI.getSubclassDataFromInstruction());
+ Op<0>() = CRI.Op<0>();
+ if (CRI.hasUnwindDest())
+ Op<1>() = CRI.Op<1>();
+}
+
+void CleanupReturnInst::init(Value *CleanupPad, BasicBlock *UnwindBB) {
+ if (UnwindBB)
+ setInstructionSubclassData(getSubclassDataFromInstruction() | 1);
+
+ Op<0>() = CleanupPad;
+ if (UnwindBB)
+ Op<1>() = UnwindBB;
+}
+
+CleanupReturnInst::CleanupReturnInst(Value *CleanupPad, BasicBlock *UnwindBB,
+ unsigned Values, Instruction *InsertBefore)
+ : TerminatorInst(Type::getVoidTy(CleanupPad->getContext()),
+ Instruction::CleanupRet,
+ OperandTraits<CleanupReturnInst>::op_end(this) - Values,
+ Values, InsertBefore) {
+ init(CleanupPad, UnwindBB);
+}
+
+CleanupReturnInst::CleanupReturnInst(Value *CleanupPad, BasicBlock *UnwindBB,
+ unsigned Values, BasicBlock *InsertAtEnd)
+ : TerminatorInst(Type::getVoidTy(CleanupPad->getContext()),
+ Instruction::CleanupRet,
+ OperandTraits<CleanupReturnInst>::op_end(this) - Values,
+ Values, InsertAtEnd) {
+ init(CleanupPad, UnwindBB);
+}
+
+BasicBlock *CleanupReturnInst::getSuccessorV(unsigned Idx) const {
+ assert(Idx == 0);
+ return getUnwindDest();
+}
+unsigned CleanupReturnInst::getNumSuccessorsV() const {
+ return getNumSuccessors();
+}
+void CleanupReturnInst::setSuccessorV(unsigned Idx, BasicBlock *B) {
+ assert(Idx == 0);
+ setUnwindDest(B);
+}
+
+//===----------------------------------------------------------------------===//
+// CatchReturnInst Implementation
+//===----------------------------------------------------------------------===//
+void CatchReturnInst::init(Value *CatchPad, BasicBlock *BB) {
+ Op<0>() = CatchPad;
+ Op<1>() = BB;
+}
+
+CatchReturnInst::CatchReturnInst(const CatchReturnInst &CRI)
+ : TerminatorInst(Type::getVoidTy(CRI.getContext()), Instruction::CatchRet,
+ OperandTraits<CatchReturnInst>::op_begin(this), 2) {
+ Op<0>() = CRI.Op<0>();
+ Op<1>() = CRI.Op<1>();
+}
+
+CatchReturnInst::CatchReturnInst(Value *CatchPad, BasicBlock *BB,
+ Instruction *InsertBefore)
+ : TerminatorInst(Type::getVoidTy(BB->getContext()), Instruction::CatchRet,
+ OperandTraits<CatchReturnInst>::op_begin(this), 2,
+ InsertBefore) {
+ init(CatchPad, BB);
+}
+
+CatchReturnInst::CatchReturnInst(Value *CatchPad, BasicBlock *BB,
+ BasicBlock *InsertAtEnd)
+ : TerminatorInst(Type::getVoidTy(BB->getContext()), Instruction::CatchRet,
+ OperandTraits<CatchReturnInst>::op_begin(this), 2,
+ InsertAtEnd) {
+ init(CatchPad, BB);
+}
+
+BasicBlock *CatchReturnInst::getSuccessorV(unsigned Idx) const {
+ assert(Idx < getNumSuccessors() && "Successor # out of range for catchret!");
+ return getSuccessor();
+}
+unsigned CatchReturnInst::getNumSuccessorsV() const {
+ return getNumSuccessors();
+}
+void CatchReturnInst::setSuccessorV(unsigned Idx, BasicBlock *B) {
+ assert(Idx < getNumSuccessors() && "Successor # out of range for catchret!");
+ setSuccessor(B);
+}
+
+//===----------------------------------------------------------------------===//
+// CatchSwitchInst Implementation
+//===----------------------------------------------------------------------===//
+
+CatchSwitchInst::CatchSwitchInst(Value *ParentPad, BasicBlock *UnwindDest,
+ unsigned NumReservedValues,
+ const Twine &NameStr,
+ Instruction *InsertBefore)
+ : TerminatorInst(ParentPad->getType(), Instruction::CatchSwitch, nullptr, 0,
+ InsertBefore) {
+ if (UnwindDest)
+ ++NumReservedValues;
+ init(ParentPad, UnwindDest, NumReservedValues + 1);
+ setName(NameStr);
+}
+
+CatchSwitchInst::CatchSwitchInst(Value *ParentPad, BasicBlock *UnwindDest,
+ unsigned NumReservedValues,
+ const Twine &NameStr, BasicBlock *InsertAtEnd)
+ : TerminatorInst(ParentPad->getType(), Instruction::CatchSwitch, nullptr, 0,
+ InsertAtEnd) {
+ if (UnwindDest)
+ ++NumReservedValues;
+ init(ParentPad, UnwindDest, NumReservedValues + 1);
+ setName(NameStr);
+}
+
+CatchSwitchInst::CatchSwitchInst(const CatchSwitchInst &CSI)
+ : TerminatorInst(CSI.getType(), Instruction::CatchSwitch, nullptr,
+ CSI.getNumOperands()) {
+ init(CSI.getParentPad(), CSI.getUnwindDest(), CSI.getNumOperands());
+ setNumHungOffUseOperands(ReservedSpace);
+ Use *OL = getOperandList();
+ const Use *InOL = CSI.getOperandList();
+ for (unsigned I = 1, E = ReservedSpace; I != E; ++I)
+ OL[I] = InOL[I];
+}
+
+void CatchSwitchInst::init(Value *ParentPad, BasicBlock *UnwindDest,
+ unsigned NumReservedValues) {
+ assert(ParentPad && NumReservedValues);
+
+ ReservedSpace = NumReservedValues;
+ setNumHungOffUseOperands(UnwindDest ? 2 : 1);
+ allocHungoffUses(ReservedSpace);
+
+ Op<0>() = ParentPad;
+ if (UnwindDest) {
+ setInstructionSubclassData(getSubclassDataFromInstruction() | 1);
+ setUnwindDest(UnwindDest);
+ }
+}
+
+/// growOperands - grow operands - This grows the operand list in response to a
+/// push_back style of operation. This grows the number of ops by 2 times.
+void CatchSwitchInst::growOperands(unsigned Size) {
+ unsigned NumOperands = getNumOperands();
+ assert(NumOperands >= 1);
+ if (ReservedSpace >= NumOperands + Size)
+ return;
+ ReservedSpace = (NumOperands + Size / 2) * 2;
+ growHungoffUses(ReservedSpace);
+}
+
+void CatchSwitchInst::addHandler(BasicBlock *Handler) {
+ unsigned OpNo = getNumOperands();
+ growOperands(1);
+ assert(OpNo < ReservedSpace && "Growing didn't work!");
+ setNumHungOffUseOperands(getNumOperands() + 1);
+ getOperandList()[OpNo] = Handler;
+}
+
+BasicBlock *CatchSwitchInst::getSuccessorV(unsigned idx) const {
+ return getSuccessor(idx);
+}
+unsigned CatchSwitchInst::getNumSuccessorsV() const {
+ return getNumSuccessors();
+}
+void CatchSwitchInst::setSuccessorV(unsigned idx, BasicBlock *B) {
+ setSuccessor(idx, B);
+}
+
+//===----------------------------------------------------------------------===//
+// FuncletPadInst Implementation
+//===----------------------------------------------------------------------===//
+void FuncletPadInst::init(Value *ParentPad, ArrayRef<Value *> Args,
+ const Twine &NameStr) {
+ assert(getNumOperands() == 1 + Args.size() && "NumOperands not set up?");
+ std::copy(Args.begin(), Args.end(), op_begin());
+ setParentPad(ParentPad);
+ setName(NameStr);
+}
+
+FuncletPadInst::FuncletPadInst(const FuncletPadInst &FPI)
+ : Instruction(FPI.getType(), FPI.getOpcode(),
+ OperandTraits<FuncletPadInst>::op_end(this) -
+ FPI.getNumOperands(),
+ FPI.getNumOperands()) {
+ std::copy(FPI.op_begin(), FPI.op_end(), op_begin());
+ setParentPad(FPI.getParentPad());
+}
+
+FuncletPadInst::FuncletPadInst(Instruction::FuncletPadOps Op, Value *ParentPad,
+ ArrayRef<Value *> Args, unsigned Values,
+ const Twine &NameStr, Instruction *InsertBefore)
+ : Instruction(ParentPad->getType(), Op,
+ OperandTraits<FuncletPadInst>::op_end(this) - Values, Values,
+ InsertBefore) {
+ init(ParentPad, Args, NameStr);
+}
+
+FuncletPadInst::FuncletPadInst(Instruction::FuncletPadOps Op, Value *ParentPad,
+ ArrayRef<Value *> Args, unsigned Values,
+ const Twine &NameStr, BasicBlock *InsertAtEnd)
+ : Instruction(ParentPad->getType(), Op,
+ OperandTraits<FuncletPadInst>::op_end(this) - Values, Values,
+ InsertAtEnd) {
+ init(ParentPad, Args, NameStr);
+}
+
+//===----------------------------------------------------------------------===//
// UnreachableInst Implementation
//===----------------------------------------------------------------------===//
@@ -1193,6 +1505,8 @@ FenceInst::FenceInst(LLVMContext &C, AtomicOrdering Ordering,
// GetElementPtrInst Implementation
//===----------------------------------------------------------------------===//
+void GetElementPtrInst::anchor() {}
+
void GetElementPtrInst::init(Value *Ptr, ArrayRef<Value *> IdxList,
const Twine &Name) {
assert(getNumOperands() == 1 + IdxList.size() &&
@@ -2029,7 +2343,7 @@ bool CastInst::isNoopCast(const DataLayout &DL) const {
/// * %S = secondOpcode MidTy %F to DstTy
/// The function returns a resultOpcode so these two casts can be replaced with:
/// * %Replacement = resultOpcode %SrcTy %x to DstTy
-/// If no such cast is permited, the function returns 0.
+/// If no such cast is permitted, the function returns 0.
unsigned CastInst::isEliminableCastPair(
Instruction::CastOps firstOp, Instruction::CastOps secondOp,
Type *SrcTy, Type *MidTy, Type *DstTy, Type *SrcIntPtrTy, Type *MidIntPtrTy,
@@ -2037,7 +2351,7 @@ unsigned CastInst::isEliminableCastPair(
// Define the 144 possibilities for these two cast instructions. The values
// in this matrix determine what to do in a given situation and select the
// case in the switch below. The rows correspond to firstOp, the columns
- // correspond to secondOp. In looking at the table below, keep in mind
+ // correspond to secondOp. In looking at the table below, keep in mind
// the following cast properties:
//
// Size Compare Source Destination
@@ -2087,17 +2401,19 @@ unsigned CastInst::isEliminableCastPair(
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,13,12}, // AddrSpaceCast -+
};
+ // TODO: This logic could be encoded into the table above and handled in the
+ // switch below.
// If either of the casts are a bitcast from scalar to vector, disallow the
- // merging. However, bitcast of A->B->A are allowed.
- bool isFirstBitcast = (firstOp == Instruction::BitCast);
- bool isSecondBitcast = (secondOp == Instruction::BitCast);
- bool chainedBitcast = (SrcTy == DstTy && isFirstBitcast && isSecondBitcast);
-
- // Check if any of the bitcasts convert scalars<->vectors.
- if ((isFirstBitcast && isa<VectorType>(SrcTy) != isa<VectorType>(MidTy)) ||
- (isSecondBitcast && isa<VectorType>(MidTy) != isa<VectorType>(DstTy)))
- // Unless we are bitcasing to the original type, disallow optimizations.
- if (!chainedBitcast) return 0;
+ // merging. However, any pair of bitcasts are allowed.
+ bool IsFirstBitcast = (firstOp == Instruction::BitCast);
+ bool IsSecondBitcast = (secondOp == Instruction::BitCast);
+ bool AreBothBitcasts = IsFirstBitcast && IsSecondBitcast;
+
+ // Check if any of the casts convert scalars <-> vectors.
+ if ((IsFirstBitcast && isa<VectorType>(SrcTy) != isa<VectorType>(MidTy)) ||
+ (IsSecondBitcast && isa<VectorType>(MidTy) != isa<VectorType>(DstTy)))
+ if (!AreBothBitcasts)
+ return 0;
int ElimCase = CastResults[firstOp-Instruction::CastOpsBegin]
[secondOp-Instruction::CastOpsBegin];
@@ -2966,9 +3282,8 @@ AddrSpaceCastInst::AddrSpaceCastInst(
void CmpInst::anchor() {}
-CmpInst::CmpInst(Type *ty, OtherOps op, unsigned short predicate,
- Value *LHS, Value *RHS, const Twine &Name,
- Instruction *InsertBefore)
+CmpInst::CmpInst(Type *ty, OtherOps op, Predicate predicate, Value *LHS,
+ Value *RHS, const Twine &Name, Instruction *InsertBefore)
: Instruction(ty, op,
OperandTraits<CmpInst>::op_begin(this),
OperandTraits<CmpInst>::operands(this),
@@ -2979,9 +3294,8 @@ CmpInst::CmpInst(Type *ty, OtherOps op, unsigned short predicate,
setName(Name);
}
-CmpInst::CmpInst(Type *ty, OtherOps op, unsigned short predicate,
- Value *LHS, Value *RHS, const Twine &Name,
- BasicBlock *InsertAtEnd)
+CmpInst::CmpInst(Type *ty, OtherOps op, Predicate predicate, Value *LHS,
+ Value *RHS, const Twine &Name, BasicBlock *InsertAtEnd)
: Instruction(ty, op,
OperandTraits<CmpInst>::op_begin(this),
OperandTraits<CmpInst>::operands(this),
@@ -2993,8 +3307,7 @@ CmpInst::CmpInst(Type *ty, OtherOps op, unsigned short predicate,
}
CmpInst *
-CmpInst::Create(OtherOps Op, unsigned short predicate,
- Value *S1, Value *S2,
+CmpInst::Create(OtherOps Op, Predicate predicate, Value *S1, Value *S2,
const Twine &Name, Instruction *InsertBefore) {
if (Op == Instruction::ICmp) {
if (InsertBefore)
@@ -3014,7 +3327,7 @@ CmpInst::Create(OtherOps Op, unsigned short predicate,
}
CmpInst *
-CmpInst::Create(OtherOps Op, unsigned short predicate, Value *S1, Value *S2,
+CmpInst::Create(OtherOps Op, Predicate predicate, Value *S1, Value *S2,
const Twine &Name, BasicBlock *InsertAtEnd) {
if (Op == Instruction::ICmp) {
return new ICmpInst(*InsertAtEnd, CmpInst::Predicate(predicate),
@@ -3077,6 +3390,8 @@ CmpInst::Predicate CmpInst::getInversePredicate(Predicate pred) {
}
}
+void ICmpInst::anchor() {}
+
ICmpInst::Predicate ICmpInst::getSignedPredicate(Predicate pred) {
switch (pred) {
default: llvm_unreachable("Unknown icmp predicate!");
@@ -3196,7 +3511,24 @@ CmpInst::Predicate CmpInst::getSwappedPredicate(Predicate pred) {
}
}
-bool CmpInst::isUnsigned(unsigned short predicate) {
+CmpInst::Predicate CmpInst::getSignedPredicate(Predicate pred) {
+ assert(CmpInst::isUnsigned(pred) && "Call only with signed predicates!");
+
+ switch (pred) {
+ default:
+ llvm_unreachable("Unknown predicate!");
+ case CmpInst::ICMP_ULT:
+ return CmpInst::ICMP_SLT;
+ case CmpInst::ICMP_ULE:
+ return CmpInst::ICMP_SLE;
+ case CmpInst::ICMP_UGT:
+ return CmpInst::ICMP_SGT;
+ case CmpInst::ICMP_UGE:
+ return CmpInst::ICMP_SGE;
+ }
+}
+
+bool CmpInst::isUnsigned(Predicate predicate) {
switch (predicate) {
default: return false;
case ICmpInst::ICMP_ULT: case ICmpInst::ICMP_ULE: case ICmpInst::ICMP_UGT:
@@ -3204,7 +3536,7 @@ bool CmpInst::isUnsigned(unsigned short predicate) {
}
}
-bool CmpInst::isSigned(unsigned short predicate) {
+bool CmpInst::isSigned(Predicate predicate) {
switch (predicate) {
default: return false;
case ICmpInst::ICMP_SLT: case ICmpInst::ICMP_SLE: case ICmpInst::ICMP_SGT:
@@ -3212,7 +3544,7 @@ bool CmpInst::isSigned(unsigned short predicate) {
}
}
-bool CmpInst::isOrdered(unsigned short predicate) {
+bool CmpInst::isOrdered(Predicate predicate) {
switch (predicate) {
default: return false;
case FCmpInst::FCMP_OEQ: case FCmpInst::FCMP_ONE: case FCmpInst::FCMP_OGT:
@@ -3221,7 +3553,7 @@ bool CmpInst::isOrdered(unsigned short predicate) {
}
}
-bool CmpInst::isUnordered(unsigned short predicate) {
+bool CmpInst::isUnordered(Predicate predicate) {
switch (predicate) {
default: return false;
case FCmpInst::FCMP_UEQ: case FCmpInst::FCMP_UNE: case FCmpInst::FCMP_UGT:
@@ -3230,7 +3562,7 @@ bool CmpInst::isUnordered(unsigned short predicate) {
}
}
-bool CmpInst::isTrueWhenEqual(unsigned short predicate) {
+bool CmpInst::isTrueWhenEqual(Predicate predicate) {
switch(predicate) {
default: return false;
case ICMP_EQ: case ICMP_UGE: case ICMP_ULE: case ICMP_SGE: case ICMP_SLE:
@@ -3238,7 +3570,7 @@ bool CmpInst::isTrueWhenEqual(unsigned short predicate) {
}
}
-bool CmpInst::isFalseWhenEqual(unsigned short predicate) {
+bool CmpInst::isFalseWhenEqual(Predicate predicate) {
switch(predicate) {
case ICMP_NE: case ICMP_UGT: case ICMP_ULT: case ICMP_SGT: case ICMP_SLT:
case FCMP_FALSE: case FCMP_ONE: case FCMP_OGT: case FCMP_OLT: return true;
@@ -3569,6 +3901,10 @@ AddrSpaceCastInst *AddrSpaceCastInst::cloneImpl() const {
}
CallInst *CallInst::cloneImpl() const {
+ if (hasOperandBundles()) {
+ unsigned DescriptorBytes = getNumOperandBundles() * sizeof(BundleOpInfo);
+ return new(getNumOperands(), DescriptorBytes) CallInst(*this);
+ }
return new(getNumOperands()) CallInst(*this);
}
@@ -3613,11 +3949,31 @@ IndirectBrInst *IndirectBrInst::cloneImpl() const {
}
InvokeInst *InvokeInst::cloneImpl() const {
+ if (hasOperandBundles()) {
+ unsigned DescriptorBytes = getNumOperandBundles() * sizeof(BundleOpInfo);
+ return new(getNumOperands(), DescriptorBytes) InvokeInst(*this);
+ }
return new(getNumOperands()) InvokeInst(*this);
}
ResumeInst *ResumeInst::cloneImpl() const { return new (1) ResumeInst(*this); }
+CleanupReturnInst *CleanupReturnInst::cloneImpl() const {
+ return new (getNumOperands()) CleanupReturnInst(*this);
+}
+
+CatchReturnInst *CatchReturnInst::cloneImpl() const {
+ return new (getNumOperands()) CatchReturnInst(*this);
+}
+
+CatchSwitchInst *CatchSwitchInst::cloneImpl() const {
+ return new CatchSwitchInst(*this);
+}
+
+FuncletPadInst *FuncletPadInst::cloneImpl() const {
+ return new (getNumOperands()) FuncletPadInst(*this);
+}
+
UnreachableInst *UnreachableInst::cloneImpl() const {
LLVMContext &Context = getContext();
return new UnreachableInst(Context);
diff --git a/contrib/llvm/lib/IR/LLVMContext.cpp b/contrib/llvm/lib/IR/LLVMContext.cpp
index 6d799e4b9650..8848bcb71477 100644
--- a/contrib/llvm/lib/IR/LLVMContext.cpp
+++ b/contrib/llvm/lib/IR/LLVMContext.cpp
@@ -104,6 +104,39 @@ LLVMContext::LLVMContext() : pImpl(new LLVMContextImpl(*this)) {
assert(DereferenceableOrNullID == MD_dereferenceable_or_null &&
"dereferenceable_or_null kind id drifted");
(void)DereferenceableOrNullID;
+
+ // Create the 'make.implicit' metadata kind.
+ unsigned MakeImplicitID = getMDKindID("make.implicit");
+ assert(MakeImplicitID == MD_make_implicit &&
+ "make.implicit kind id drifted");
+ (void)MakeImplicitID;
+
+ // Create the 'unpredictable' metadata kind.
+ unsigned UnpredictableID = getMDKindID("unpredictable");
+ assert(UnpredictableID == MD_unpredictable &&
+ "unpredictable kind id drifted");
+ (void)UnpredictableID;
+
+ // Create the 'invariant.group' metadata kind.
+ unsigned InvariantGroupId = getMDKindID("invariant.group");
+ assert(InvariantGroupId == MD_invariant_group &&
+ "invariant.group kind id drifted");
+ (void)InvariantGroupId;
+
+ // Create the 'align' metadata kind.
+ unsigned AlignID = getMDKindID("align");
+ assert(AlignID == MD_align && "align kind id drifted");
+ (void)AlignID;
+
+ auto *DeoptEntry = pImpl->getOrInsertBundleTag("deopt");
+ assert(DeoptEntry->second == LLVMContext::OB_deopt &&
+ "deopt operand bundle id drifted!");
+ (void)DeoptEntry;
+
+ auto *FuncletEntry = pImpl->getOrInsertBundleTag("funclet");
+ assert(FuncletEntry->second == LLVMContext::OB_funclet &&
+ "funclet operand bundle id drifted!");
+ (void)FuncletEntry;
}
LLVMContext::~LLVMContext() { delete pImpl; }
@@ -193,6 +226,11 @@ static bool isDiagnosticEnabled(const DiagnosticInfo &DI) {
if (!cast<DiagnosticInfoOptimizationRemarkAnalysis>(DI).isEnabled())
return false;
break;
+ case llvm::DK_OptimizationRemarkAnalysisFPCommute:
+ if (!cast<DiagnosticInfoOptimizationRemarkAnalysisFPCommute>(DI)
+ .isEnabled())
+ return false;
+ break;
default:
break;
}
@@ -250,7 +288,7 @@ unsigned LLVMContext::getMDKindID(StringRef Name) const {
.first->second;
}
-/// getHandlerNames - Populate client supplied smallvector using custome
+/// getHandlerNames - Populate client-supplied smallvector using custom
/// metadata name and ID.
void LLVMContext::getMDKindNames(SmallVectorImpl<StringRef> &Names) const {
Names.resize(pImpl->CustomMDKindNames.size());
@@ -258,3 +296,11 @@ void LLVMContext::getMDKindNames(SmallVectorImpl<StringRef> &Names) const {
E = pImpl->CustomMDKindNames.end(); I != E; ++I)
Names[I->second] = I->first();
}
+
+void LLVMContext::getOperandBundleTags(SmallVectorImpl<StringRef> &Tags) const {
+ pImpl->getOperandBundleTags(Tags);
+}
+
+uint32_t LLVMContext::getOperandBundleTagID(StringRef Tag) const {
+ return pImpl->getOperandBundleTagID(Tag);
+}
diff --git a/contrib/llvm/lib/IR/LLVMContextImpl.cpp b/contrib/llvm/lib/IR/LLVMContextImpl.cpp
index 1e2080770fcd..5239b4f7d84a 100644
--- a/contrib/llvm/lib/IR/LLVMContextImpl.cpp
+++ b/contrib/llvm/lib/IR/LLVMContextImpl.cpp
@@ -27,6 +27,7 @@ LLVMContextImpl::LLVMContextImpl(LLVMContext &C)
FloatTy(C, Type::FloatTyID),
DoubleTy(C, Type::DoubleTyID),
MetadataTy(C, Type::MetadataTyID),
+ TokenTy(C, Type::TokenTyID),
X86_FP80Ty(C, Type::X86_FP80TyID),
FP128Ty(C, Type::FP128TyID),
PPC_FP128Ty(C, Type::PPC_FP128TyID),
@@ -78,7 +79,7 @@ LLVMContextImpl::~LLVMContextImpl() {
// unnecessary RAUW when nodes are still unresolved.
for (auto *I : DistinctMDNodes)
I->dropAllReferences();
-#define HANDLE_MDNODE_LEAF(CLASS) \
+#define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) \
for (auto *I : CLASS##s) \
I->dropAllReferences();
#include "llvm/IR/Metadata.def"
@@ -92,8 +93,8 @@ LLVMContextImpl::~LLVMContextImpl() {
// Destroy MDNodes.
for (MDNode *I : DistinctMDNodes)
I->deleteAsSubclass();
-#define HANDLE_MDNODE_LEAF(CLASS) \
- for (CLASS *I : CLASS##s) \
+#define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) \
+ for (CLASS * I : CLASS##s) \
delete I;
#include "llvm/IR/Metadata.def"
@@ -218,6 +219,23 @@ unsigned MDNodeOpsKey::calculateHash(ArrayRef<Metadata *> Ops) {
return hash_combine_range(Ops.begin(), Ops.end());
}
+StringMapEntry<uint32_t> *LLVMContextImpl::getOrInsertBundleTag(StringRef Tag) {
+ uint32_t NewIdx = BundleTagCache.size();
+ return &*(BundleTagCache.insert(std::make_pair(Tag, NewIdx)).first);
+}
+
+void LLVMContextImpl::getOperandBundleTags(SmallVectorImpl<StringRef> &Tags) const {
+ Tags.resize(BundleTagCache.size());
+ for (const auto &T : BundleTagCache)
+ Tags[T.second] = T.first();
+}
+
+uint32_t LLVMContextImpl::getOperandBundleTagID(StringRef Tag) const {
+ auto I = BundleTagCache.find(Tag);
+ assert(I != BundleTagCache.end() && "Unknown tag!");
+ return I->second;
+}
+
// ConstantsContext anchors
void UnaryConstantExpr::anchor() { }
diff --git a/contrib/llvm/lib/IR/LLVMContextImpl.h b/contrib/llvm/lib/IR/LLVMContextImpl.h
index cbbf11e334c4..a24114d0a0ae 100644
--- a/contrib/llvm/lib/IR/LLVMContextImpl.h
+++ b/contrib/llvm/lib/IR/LLVMContextImpl.h
@@ -458,67 +458,6 @@ template <> struct MDNodeKeyImpl<DIFile> {
unsigned getHashValue() const { return hash_combine(Filename, Directory); }
};
-template <> struct MDNodeKeyImpl<DICompileUnit> {
- unsigned SourceLanguage;
- Metadata *File;
- StringRef Producer;
- bool IsOptimized;
- StringRef Flags;
- unsigned RuntimeVersion;
- StringRef SplitDebugFilename;
- unsigned EmissionKind;
- Metadata *EnumTypes;
- Metadata *RetainedTypes;
- Metadata *Subprograms;
- Metadata *GlobalVariables;
- Metadata *ImportedEntities;
- uint64_t DWOId;
-
- MDNodeKeyImpl(unsigned SourceLanguage, Metadata *File, StringRef Producer,
- bool IsOptimized, StringRef Flags, unsigned RuntimeVersion,
- StringRef SplitDebugFilename, unsigned EmissionKind,
- Metadata *EnumTypes, Metadata *RetainedTypes,
- Metadata *Subprograms, Metadata *GlobalVariables,
- Metadata *ImportedEntities, uint64_t DWOId)
- : SourceLanguage(SourceLanguage), File(File), Producer(Producer),
- IsOptimized(IsOptimized), Flags(Flags), RuntimeVersion(RuntimeVersion),
- SplitDebugFilename(SplitDebugFilename), EmissionKind(EmissionKind),
- EnumTypes(EnumTypes), RetainedTypes(RetainedTypes),
- Subprograms(Subprograms), GlobalVariables(GlobalVariables),
- ImportedEntities(ImportedEntities), DWOId(DWOId) {}
- MDNodeKeyImpl(const DICompileUnit *N)
- : SourceLanguage(N->getSourceLanguage()), File(N->getRawFile()),
- Producer(N->getProducer()), IsOptimized(N->isOptimized()),
- Flags(N->getFlags()), RuntimeVersion(N->getRuntimeVersion()),
- SplitDebugFilename(N->getSplitDebugFilename()),
- EmissionKind(N->getEmissionKind()), EnumTypes(N->getRawEnumTypes()),
- RetainedTypes(N->getRawRetainedTypes()),
- Subprograms(N->getRawSubprograms()),
- GlobalVariables(N->getRawGlobalVariables()),
- ImportedEntities(N->getRawImportedEntities()), DWOId(N->getDWOId()) {}
-
- bool isKeyOf(const DICompileUnit *RHS) const {
- return SourceLanguage == RHS->getSourceLanguage() &&
- File == RHS->getRawFile() && Producer == RHS->getProducer() &&
- IsOptimized == RHS->isOptimized() && Flags == RHS->getFlags() &&
- RuntimeVersion == RHS->getRuntimeVersion() &&
- SplitDebugFilename == RHS->getSplitDebugFilename() &&
- EmissionKind == RHS->getEmissionKind() &&
- EnumTypes == RHS->getRawEnumTypes() &&
- RetainedTypes == RHS->getRawRetainedTypes() &&
- Subprograms == RHS->getRawSubprograms() &&
- GlobalVariables == RHS->getRawGlobalVariables() &&
- ImportedEntities == RHS->getRawImportedEntities() &&
- DWOId == RHS->getDWOId();
- }
- unsigned getHashValue() const {
- return hash_combine(SourceLanguage, File, Producer, IsOptimized, Flags,
- RuntimeVersion, SplitDebugFilename, EmissionKind,
- EnumTypes, RetainedTypes, Subprograms, GlobalVariables,
- ImportedEntities, DWOId);
- }
-};
-
template <> struct MDNodeKeyImpl<DISubprogram> {
Metadata *Scope;
StringRef Name;
@@ -534,7 +473,6 @@ template <> struct MDNodeKeyImpl<DISubprogram> {
unsigned VirtualIndex;
unsigned Flags;
bool IsOptimized;
- Metadata *Function;
Metadata *TemplateParams;
Metadata *Declaration;
Metadata *Variables;
@@ -544,15 +482,15 @@ template <> struct MDNodeKeyImpl<DISubprogram> {
bool IsLocalToUnit, bool IsDefinition, unsigned ScopeLine,
Metadata *ContainingType, unsigned Virtuality,
unsigned VirtualIndex, unsigned Flags, bool IsOptimized,
- Metadata *Function, Metadata *TemplateParams,
- Metadata *Declaration, Metadata *Variables)
+ Metadata *TemplateParams, Metadata *Declaration,
+ Metadata *Variables)
: Scope(Scope), Name(Name), LinkageName(LinkageName), File(File),
Line(Line), Type(Type), IsLocalToUnit(IsLocalToUnit),
IsDefinition(IsDefinition), ScopeLine(ScopeLine),
ContainingType(ContainingType), Virtuality(Virtuality),
VirtualIndex(VirtualIndex), Flags(Flags), IsOptimized(IsOptimized),
- Function(Function), TemplateParams(TemplateParams),
- Declaration(Declaration), Variables(Variables) {}
+ TemplateParams(TemplateParams), Declaration(Declaration),
+ Variables(Variables) {}
MDNodeKeyImpl(const DISubprogram *N)
: Scope(N->getRawScope()), Name(N->getName()),
LinkageName(N->getLinkageName()), File(N->getRawFile()),
@@ -561,7 +499,6 @@ template <> struct MDNodeKeyImpl<DISubprogram> {
ScopeLine(N->getScopeLine()), ContainingType(N->getRawContainingType()),
Virtuality(N->getVirtuality()), VirtualIndex(N->getVirtualIndex()),
Flags(N->getFlags()), IsOptimized(N->isOptimized()),
- Function(N->getRawFunction()),
TemplateParams(N->getRawTemplateParams()),
Declaration(N->getRawDeclaration()), Variables(N->getRawVariables()) {}
@@ -576,7 +513,6 @@ template <> struct MDNodeKeyImpl<DISubprogram> {
Virtuality == RHS->getVirtuality() &&
VirtualIndex == RHS->getVirtualIndex() && Flags == RHS->getFlags() &&
IsOptimized == RHS->isOptimized() &&
- Function == RHS->getRawFunction() &&
TemplateParams == RHS->getRawTemplateParams() &&
Declaration == RHS->getRawDeclaration() &&
Variables == RHS->getRawVariables();
@@ -584,7 +520,7 @@ template <> struct MDNodeKeyImpl<DISubprogram> {
unsigned getHashValue() const {
return hash_combine(Scope, Name, LinkageName, File, Line, Type,
IsLocalToUnit, IsDefinition, ScopeLine, ContainingType,
- Virtuality, VirtualIndex, Flags, IsOptimized, Function,
+ Virtuality, VirtualIndex, Flags, IsOptimized,
TemplateParams, Declaration, Variables);
}
};
@@ -759,7 +695,6 @@ template <> struct MDNodeKeyImpl<DIGlobalVariable> {
};
template <> struct MDNodeKeyImpl<DILocalVariable> {
- unsigned Tag;
Metadata *Scope;
StringRef Name;
Metadata *File;
@@ -768,23 +703,23 @@ template <> struct MDNodeKeyImpl<DILocalVariable> {
unsigned Arg;
unsigned Flags;
- MDNodeKeyImpl(unsigned Tag, Metadata *Scope, StringRef Name, Metadata *File,
- unsigned Line, Metadata *Type, unsigned Arg, unsigned Flags)
- : Tag(Tag), Scope(Scope), Name(Name), File(File), Line(Line), Type(Type),
- Arg(Arg), Flags(Flags) {}
+ MDNodeKeyImpl(Metadata *Scope, StringRef Name, Metadata *File, unsigned Line,
+ Metadata *Type, unsigned Arg, unsigned Flags)
+ : Scope(Scope), Name(Name), File(File), Line(Line), Type(Type), Arg(Arg),
+ Flags(Flags) {}
MDNodeKeyImpl(const DILocalVariable *N)
- : Tag(N->getTag()), Scope(N->getRawScope()), Name(N->getName()),
- File(N->getRawFile()), Line(N->getLine()), Type(N->getRawType()),
- Arg(N->getArg()), Flags(N->getFlags()) {}
+ : Scope(N->getRawScope()), Name(N->getName()), File(N->getRawFile()),
+ Line(N->getLine()), Type(N->getRawType()), Arg(N->getArg()),
+ Flags(N->getFlags()) {}
bool isKeyOf(const DILocalVariable *RHS) const {
- return Tag == RHS->getTag() && Scope == RHS->getRawScope() &&
- Name == RHS->getName() && File == RHS->getRawFile() &&
- Line == RHS->getLine() && Type == RHS->getRawType() &&
- Arg == RHS->getArg() && Flags == RHS->getFlags();
+ return Scope == RHS->getRawScope() && Name == RHS->getName() &&
+ File == RHS->getRawFile() && Line == RHS->getLine() &&
+ Type == RHS->getRawType() && Arg == RHS->getArg() &&
+ Flags == RHS->getFlags();
}
unsigned getHashValue() const {
- return hash_combine(Tag, Scope, Name, File, Line, Type, Arg, Flags);
+ return hash_combine(Scope, Name, File, Line, Type, Arg, Flags);
}
};
@@ -857,6 +792,49 @@ template <> struct MDNodeKeyImpl<DIImportedEntity> {
}
};
+template <> struct MDNodeKeyImpl<DIMacro> {
+ unsigned MIType;
+ unsigned Line;
+ StringRef Name;
+ StringRef Value;
+
+ MDNodeKeyImpl(unsigned MIType, unsigned Line, StringRef Name, StringRef Value)
+ : MIType(MIType), Line(Line), Name(Name), Value(Value) {}
+ MDNodeKeyImpl(const DIMacro *N)
+ : MIType(N->getMacinfoType()), Line(N->getLine()), Name(N->getName()),
+ Value(N->getValue()) {}
+
+ bool isKeyOf(const DIMacro *RHS) const {
+ return MIType == RHS->getMacinfoType() && Line == RHS->getLine() &&
+ Name == RHS->getName() && Value == RHS->getValue();
+ }
+ unsigned getHashValue() const {
+ return hash_combine(MIType, Line, Name, Value);
+ }
+};
+
+template <> struct MDNodeKeyImpl<DIMacroFile> {
+ unsigned MIType;
+ unsigned Line;
+ Metadata *File;
+ Metadata *Elements;
+
+ MDNodeKeyImpl(unsigned MIType, unsigned Line, Metadata *File,
+ Metadata *Elements)
+ : MIType(MIType), Line(Line), File(File), Elements(Elements) {}
+ MDNodeKeyImpl(const DIMacroFile *N)
+ : MIType(N->getMacinfoType()), Line(N->getLine()), File(N->getRawFile()),
+ Elements(N->getRawElements()) {}
+
+ bool isKeyOf(const DIMacroFile *RHS) const {
+ return MIType == RHS->getMacinfoType() && Line == RHS->getLine() &&
+ File == RHS->getRawFile() && File == RHS->getRawElements();
+ }
+ unsigned getHashValue() const {
+ return hash_combine(MIType, Line, File, Elements);
+ }
+};
+
/// \brief DenseMapInfo for MDNode subclasses.
template <class NodeTy> struct MDNodeInfo {
typedef MDNodeKeyImpl<NodeTy> KeyTy;
@@ -953,7 +931,8 @@ public:
DenseMap<const Value*, ValueName*> ValueNames;
-#define HANDLE_MDNODE_LEAF(CLASS) DenseSet<CLASS *, CLASS##Info> CLASS##s;
+#define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) \
+ DenseSet<CLASS *, CLASS##Info> CLASS##s;
#include "llvm/IR/Metadata.def"
// MDNodes may be uniqued or not uniqued. When they're not uniqued, they
@@ -988,8 +967,10 @@ public:
ConstantInt *TheTrueVal;
ConstantInt *TheFalseVal;
+ std::unique_ptr<ConstantTokenNone> TheNoneToken;
+
// Basic type instances.
- Type VoidTy, LabelTy, HalfTy, FloatTy, DoubleTy, MetadataTy;
+ Type VoidTy, LabelTy, HalfTy, FloatTy, DoubleTy, MetadataTy, TokenTy;
Type X86_FP80Ty, FP128Ty, PPC_FP128Ty, X86_MMXTy;
IntegerType Int1Ty, Int8Ty, Int16Ty, Int32Ty, Int64Ty, Int128Ty;
@@ -1033,20 +1014,19 @@ public:
/// instructions in different blocks at the same location.
DenseMap<std::pair<const char *, unsigned>, unsigned> DiscriminatorTable;
- /// \brief Mapping from a function to its prefix data, which is stored as the
- /// operand of an unparented ReturnInst so that the prefix data has a Use.
- typedef DenseMap<const Function *, ReturnInst *> PrefixDataMapTy;
- PrefixDataMapTy PrefixDataMap;
-
- /// \brief Mapping from a function to its prologue data, which is stored as
- /// the operand of an unparented ReturnInst so that the prologue data has a
- /// Use.
- typedef DenseMap<const Function *, ReturnInst *> PrologueDataMapTy;
- PrologueDataMapTy PrologueDataMap;
-
int getOrAddScopeRecordIdxEntry(MDNode *N, int ExistingIdx);
int getOrAddScopeInlinedAtIdxEntry(MDNode *Scope, MDNode *IA,int ExistingIdx);
+ /// \brief A set of interned tags for operand bundles. The StringMap maps
+ /// bundle tags to their IDs.
+ ///
+ /// \see LLVMContext::getOperandBundleTagID
+ StringMap<uint32_t> BundleTagCache;
+
+ StringMapEntry<uint32_t> *getOrInsertBundleTag(StringRef Tag);
+ void getOperandBundleTags(SmallVectorImpl<StringRef> &Tags) const;
+ uint32_t getOperandBundleTagID(StringRef Tag) const;
+
LLVMContextImpl(LLVMContext &C);
~LLVMContextImpl();
diff --git a/contrib/llvm/lib/IR/LegacyPassManager.cpp b/contrib/llvm/lib/IR/LegacyPassManager.cpp
index 27d98a279fe2..f2e0c7d32c02 100644
--- a/contrib/llvm/lib/IR/LegacyPassManager.cpp
+++ b/contrib/llvm/lib/IR/LegacyPassManager.cpp
@@ -569,13 +569,33 @@ void PMTopLevelManager::collectLastUses(SmallVectorImpl<Pass *> &LastUses,
AnalysisUsage *PMTopLevelManager::findAnalysisUsage(Pass *P) {
AnalysisUsage *AnUsage = nullptr;
- DenseMap<Pass *, AnalysisUsage *>::iterator DMI = AnUsageMap.find(P);
+ auto DMI = AnUsageMap.find(P);
if (DMI != AnUsageMap.end())
AnUsage = DMI->second;
else {
- AnUsage = new AnalysisUsage();
- P->getAnalysisUsage(*AnUsage);
- AnUsageMap[P] = AnUsage;
+ // Look up the analysis usage from the pass instance (different instances
+ // of the same pass can produce different results), but unique the
+ // resulting object to reduce memory usage. This helps to greatly reduce
+ // memory usage when we have many instances of only a few pass types
+ // (e.g. instcombine, simplifycfg, etc...) which tend to share a fixed set
+ // of dependencies.
+ AnalysisUsage AU;
+ P->getAnalysisUsage(AU);
+
+ AUFoldingSetNode* Node = nullptr;
+ FoldingSetNodeID ID;
+ AUFoldingSetNode::Profile(ID, AU);
+ void *IP = nullptr;
+ if (auto *N = UniqueAnalysisUsages.FindNodeOrInsertPos(ID, IP))
+ Node = N;
+ else {
+ Node = new (AUFoldingSetNodeAllocator.Allocate()) AUFoldingSetNode(AU);
+ UniqueAnalysisUsages.InsertNode(Node, IP);
+ }
+ assert(Node && "cached analysis usage must be non null");
+
+ AnUsageMap[P] = &Node->AU;
+ AnUsage = &Node->AU;;
}
return AnUsage;
}
@@ -686,6 +706,10 @@ void PMTopLevelManager::schedulePass(Pass *P) {
/// passes and all pass managers. If desired pass is not found
/// then return NULL.
Pass *PMTopLevelManager::findAnalysisPass(AnalysisID AID) {
+ // For immutable passes we have a direct mapping from ID to pass, so check
+ // that first.
+ if (Pass *P = ImmutablePassMap.lookup(AID))
+ return P;
// Check pass managers
for (PMDataManager *PassManager : PassManagers)
@@ -697,24 +721,6 @@ Pass *PMTopLevelManager::findAnalysisPass(AnalysisID AID) {
if (Pass *P = IndirectPassManager->findAnalysisPass(AID, false))
return P;
- // Check the immutable passes. Iterate in reverse order so that we find
- // the most recently registered passes first.
- for (auto I = ImmutablePasses.rbegin(), E = ImmutablePasses.rend(); I != E;
- ++I) {
- AnalysisID PI = (*I)->getPassID();
- if (PI == AID)
- return *I;
-
- // If Pass not found then check the interfaces implemented by Immutable Pass
- const PassInfo *PassInf = findAnalysisPassInfo(PI);
- assert(PassInf && "Expected all immutable passes to be initialized");
- const std::vector<const PassInfo*> &ImmPI =
- PassInf->getInterfacesImplemented();
- for (const PassInfo *PI : ImmPI)
- if (PI->getTypeInfo() == AID)
- return *I;
- }
-
return nullptr;
}
@@ -729,6 +735,24 @@ const PassInfo *PMTopLevelManager::findAnalysisPassInfo(AnalysisID AID) const {
return PI;
}
+void PMTopLevelManager::addImmutablePass(ImmutablePass *P) {
+ P->initializePass();
+ ImmutablePasses.push_back(P);
+
+ // Add this pass to the map from its analysis ID. We clobber any prior runs
+ // of the pass in the map so that the last one added is the one found when
+ // doing lookups.
+ AnalysisID AID = P->getPassID();
+ ImmutablePassMap[AID] = P;
+
+ // Also add any interfaces implemented by the immutable pass to the map for
+ // fast lookup.
+ const PassInfo *PassInf = findAnalysisPassInfo(AID);
+ assert(PassInf && "Expected all immutable passes to be initialized");
+ for (const PassInfo *ImmPI : PassInf->getInterfacesImplemented())
+ ImmutablePassMap[ImmPI->getTypeInfo()] = P;
+}
+
// Print passes managed by this top level manager.
void PMTopLevelManager::dumpPasses() const {
@@ -780,15 +804,8 @@ void PMTopLevelManager::initializeAllAnalysisInfo() {
for (DenseMap<Pass *, Pass *>::iterator DMI = LastUser.begin(),
DME = LastUser.end(); DMI != DME; ++DMI) {
- DenseMap<Pass *, SmallPtrSet<Pass *, 8> >::iterator InvDMI =
- InversedLastUser.find(DMI->second);
- if (InvDMI != InversedLastUser.end()) {
- SmallPtrSet<Pass *, 8> &L = InvDMI->second;
- L.insert(DMI->first);
- } else {
- SmallPtrSet<Pass *, 8> L; L.insert(DMI->first);
- InversedLastUser[DMI->second] = L;
- }
+ SmallPtrSet<Pass *, 8> &L = InversedLastUser[DMI->second];
+ L.insert(DMI->first);
}
}
@@ -801,10 +818,6 @@ PMTopLevelManager::~PMTopLevelManager() {
for (SmallVectorImpl<ImmutablePass *>::iterator
I = ImmutablePasses.begin(), E = ImmutablePasses.end(); I != E; ++I)
delete *I;
-
- for (DenseMap<Pass *, AnalysisUsage *>::iterator DMI = AnUsageMap.begin(),
- DME = AnUsageMap.end(); DMI != DME; ++DMI)
- delete DMI->second;
}
//===----------------------------------------------------------------------===//
@@ -989,31 +1002,28 @@ void PMDataManager::add(Pass *P, bool ProcessAnalysis) {
// At the moment, this pass is the last user of all required passes.
SmallVector<Pass *, 12> LastUses;
- SmallVector<Pass *, 8> RequiredPasses;
+ SmallVector<Pass *, 8> UsedPasses;
SmallVector<AnalysisID, 8> ReqAnalysisNotAvailable;
unsigned PDepth = this->getDepth();
- collectRequiredAnalysis(RequiredPasses,
- ReqAnalysisNotAvailable, P);
- for (SmallVectorImpl<Pass *>::iterator I = RequiredPasses.begin(),
- E = RequiredPasses.end(); I != E; ++I) {
- Pass *PRequired = *I;
+ collectRequiredAndUsedAnalyses(UsedPasses, ReqAnalysisNotAvailable, P);
+ for (Pass *PUsed : UsedPasses) {
unsigned RDepth = 0;
- assert(PRequired->getResolver() && "Analysis Resolver is not set");
- PMDataManager &DM = PRequired->getResolver()->getPMDataManager();
+ assert(PUsed->getResolver() && "Analysis Resolver is not set");
+ PMDataManager &DM = PUsed->getResolver()->getPMDataManager();
RDepth = DM.getDepth();
if (PDepth == RDepth)
- LastUses.push_back(PRequired);
+ LastUses.push_back(PUsed);
else if (PDepth > RDepth) {
// Let the parent claim responsibility of last use
- TransferLastUses.push_back(PRequired);
+ TransferLastUses.push_back(PUsed);
// Keep track of higher level analysis used by this manager.
- HigherLevelAnalysis.push_back(PRequired);
+ HigherLevelAnalysis.push_back(PUsed);
} else
- llvm_unreachable("Unable to accommodate Required Pass");
+ llvm_unreachable("Unable to accommodate Used Pass");
}
// Set P as P's last user until someone starts using P.
@@ -1030,10 +1040,8 @@ void PMDataManager::add(Pass *P, bool ProcessAnalysis) {
}
// Now, take care of required analyses that are not available.
- for (SmallVectorImpl<AnalysisID>::iterator
- I = ReqAnalysisNotAvailable.begin(),
- E = ReqAnalysisNotAvailable.end() ;I != E; ++I) {
- const PassInfo *PI = TPM->findAnalysisPassInfo(*I);
+ for (AnalysisID ID : ReqAnalysisNotAvailable) {
+ const PassInfo *PI = TPM->findAnalysisPassInfo(ID);
Pass *AnalysisPass = PI->createPass();
this->addLowerLevelRequiredPass(P, AnalysisPass);
}
@@ -1048,30 +1056,29 @@ void PMDataManager::add(Pass *P, bool ProcessAnalysis) {
}
-/// Populate RP with analysis pass that are required by
+/// Populate UP with analysis pass that are used or required by
/// pass P and are available. Populate RP_NotAvail with analysis
/// pass that are required by pass P but are not available.
-void PMDataManager::collectRequiredAnalysis(SmallVectorImpl<Pass *> &RP,
- SmallVectorImpl<AnalysisID> &RP_NotAvail,
- Pass *P) {
+void PMDataManager::collectRequiredAndUsedAnalyses(
+ SmallVectorImpl<Pass *> &UP, SmallVectorImpl<AnalysisID> &RP_NotAvail,
+ Pass *P) {
AnalysisUsage *AnUsage = TPM->findAnalysisUsage(P);
- const AnalysisUsage::VectorType &RequiredSet = AnUsage->getRequiredSet();
- for (AnalysisUsage::VectorType::const_iterator
- I = RequiredSet.begin(), E = RequiredSet.end(); I != E; ++I) {
- if (Pass *AnalysisPass = findAnalysisPass(*I, true))
- RP.push_back(AnalysisPass);
+
+ for (const auto &UsedID : AnUsage->getUsedSet())
+ if (Pass *AnalysisPass = findAnalysisPass(UsedID, true))
+ UP.push_back(AnalysisPass);
+
+ for (const auto &RequiredID : AnUsage->getRequiredSet())
+ if (Pass *AnalysisPass = findAnalysisPass(RequiredID, true))
+ UP.push_back(AnalysisPass);
else
- RP_NotAvail.push_back(*I);
- }
+ RP_NotAvail.push_back(RequiredID);
- const AnalysisUsage::VectorType &IDs = AnUsage->getRequiredTransitiveSet();
- for (AnalysisUsage::VectorType::const_iterator I = IDs.begin(),
- E = IDs.end(); I != E; ++I) {
- if (Pass *AnalysisPass = findAnalysisPass(*I, true))
- RP.push_back(AnalysisPass);
+ for (const auto &RequiredID : AnUsage->getRequiredTransitiveSet())
+ if (Pass *AnalysisPass = findAnalysisPass(RequiredID, true))
+ UP.push_back(AnalysisPass);
else
- RP_NotAvail.push_back(*I);
- }
+ RP_NotAvail.push_back(RequiredID);
}
// All Required analyses should be available to the pass as it runs! Here
@@ -1206,6 +1213,15 @@ void PMDataManager::dumpPreservedSet(const Pass *P) const {
dumpAnalysisUsage("Preserved", P, analysisUsage.getPreservedSet());
}
+void PMDataManager::dumpUsedSet(const Pass *P) const {
+ if (PassDebugging < Details)
+ return;
+
+ AnalysisUsage analysisUsage;
+ P->getAnalysisUsage(analysisUsage);
+ dumpAnalysisUsage("Used", P, analysisUsage.getUsedSet());
+}
+
void PMDataManager::dumpAnalysisUsage(StringRef Msg, const Pass *P,
const AnalysisUsage::VectorType &Set) const {
assert(PassDebugging >= Details);
@@ -1310,6 +1326,7 @@ bool BBPassManager::runOnFunction(Function &F) {
dumpPassInfo(BP, MODIFICATION_MSG, ON_BASICBLOCK_MSG,
I->getName());
dumpPreservedSet(BP);
+ dumpUsedSet(BP);
verifyPreservedAnalysis(BP);
removeNotPreservedAnalysis(BP);
@@ -1524,6 +1541,7 @@ bool FPPassManager::runOnFunction(Function &F) {
if (LocalChanged)
dumpPassInfo(FP, MODIFICATION_MSG, ON_FUNCTION_MSG, F.getName());
dumpPreservedSet(FP);
+ dumpUsedSet(FP);
verifyPreservedAnalysis(FP);
removeNotPreservedAnalysis(FP);
@@ -1601,6 +1619,7 @@ MPPassManager::runOnModule(Module &M) {
dumpPassInfo(MP, MODIFICATION_MSG, ON_MODULE_MSG,
M.getModuleIdentifier());
dumpPreservedSet(MP);
+ dumpUsedSet(MP);
verifyPreservedAnalysis(MP);
removeNotPreservedAnalysis(MP);
diff --git a/contrib/llvm/lib/IR/MDBuilder.cpp b/contrib/llvm/lib/IR/MDBuilder.cpp
index b4c5ca7c6a12..4ce3ea2e9c04 100644
--- a/contrib/llvm/lib/IR/MDBuilder.cpp
+++ b/contrib/llvm/lib/IR/MDBuilder.cpp
@@ -36,8 +36,7 @@ MDNode *MDBuilder::createFPMath(float Accuracy) {
MDNode *MDBuilder::createBranchWeights(uint32_t TrueWeight,
uint32_t FalseWeight) {
- uint32_t Weights[] = {TrueWeight, FalseWeight};
- return createBranchWeights(Weights);
+ return createBranchWeights({TrueWeight, FalseWeight});
}
MDNode *MDBuilder::createBranchWeights(ArrayRef<uint32_t> Weights) {
@@ -53,14 +52,15 @@ MDNode *MDBuilder::createBranchWeights(ArrayRef<uint32_t> Weights) {
return MDNode::get(Context, Vals);
}
-MDNode *MDBuilder::createFunctionEntryCount(uint64_t Count) {
- SmallVector<Metadata *, 2> Vals(2);
- Vals[0] = createString("function_entry_count");
+MDNode *MDBuilder::createUnpredictable() {
+ return MDNode::get(Context, None);
+}
+MDNode *MDBuilder::createFunctionEntryCount(uint64_t Count) {
Type *Int64Ty = Type::getInt64Ty(Context);
- Vals[1] = createConstant(ConstantInt::get(Int64Ty, Count));
-
- return MDNode::get(Context, Vals);
+ return MDNode::get(Context,
+ {createString("function_entry_count"),
+ createConstant(ConstantInt::get(Int64Ty, Count))});
}
MDNode *MDBuilder::createRange(const APInt &Lo, const APInt &Hi) {
@@ -76,8 +76,7 @@ MDNode *MDBuilder::createRange(Constant *Lo, Constant *Hi) {
return nullptr;
// Return the range [Lo, Hi).
- Metadata *Range[2] = {createConstant(Lo), createConstant(Hi)};
- return MDNode::get(Context, Range);
+ return MDNode::get(Context, {createConstant(Lo), createConstant(Hi)});
}
MDNode *MDBuilder::createAnonymousAARoot(StringRef Name, MDNode *Extra) {
@@ -112,12 +111,10 @@ MDNode *MDBuilder::createTBAANode(StringRef Name, MDNode *Parent,
bool isConstant) {
if (isConstant) {
Constant *Flags = ConstantInt::get(Type::getInt64Ty(Context), 1);
- Metadata *Ops[3] = {createString(Name), Parent, createConstant(Flags)};
- return MDNode::get(Context, Ops);
- } else {
- Metadata *Ops[2] = {createString(Name), Parent};
- return MDNode::get(Context, Ops);
+ return MDNode::get(Context,
+ {createString(Name), Parent, createConstant(Flags)});
}
+ return MDNode::get(Context, {createString(Name), Parent});
}
MDNode *MDBuilder::createAliasScopeDomain(StringRef Name) {
@@ -125,8 +122,7 @@ MDNode *MDBuilder::createAliasScopeDomain(StringRef Name) {
}
MDNode *MDBuilder::createAliasScope(StringRef Name, MDNode *Domain) {
- Metadata *Ops[2] = {createString(Name), Domain};
- return MDNode::get(Context, Ops);
+ return MDNode::get(Context, {createString(Name), Domain});
}
/// \brief Return metadata for a tbaa.struct node with the given
@@ -161,23 +157,19 @@ MDNode *MDBuilder::createTBAAStructTypeNode(
MDNode *MDBuilder::createTBAAScalarTypeNode(StringRef Name, MDNode *Parent,
uint64_t Offset) {
ConstantInt *Off = ConstantInt::get(Type::getInt64Ty(Context), Offset);
- Metadata *Ops[3] = {createString(Name), Parent, createConstant(Off)};
- return MDNode::get(Context, Ops);
+ return MDNode::get(Context,
+ {createString(Name), Parent, createConstant(Off)});
}
/// \brief Return metadata for a TBAA tag node with the given
/// base type, access type and offset relative to the base type.
MDNode *MDBuilder::createTBAAStructTagNode(MDNode *BaseType, MDNode *AccessType,
uint64_t Offset, bool IsConstant) {
- Type *Int64 = Type::getInt64Ty(Context);
+ IntegerType *Int64 = Type::getInt64Ty(Context);
+ ConstantInt *Off = ConstantInt::get(Int64, Offset);
if (IsConstant) {
- Metadata *Ops[4] = {BaseType, AccessType,
- createConstant(ConstantInt::get(Int64, Offset)),
- createConstant(ConstantInt::get(Int64, 1))};
- return MDNode::get(Context, Ops);
- } else {
- Metadata *Ops[3] = {BaseType, AccessType,
- createConstant(ConstantInt::get(Int64, Offset))};
- return MDNode::get(Context, Ops);
+ return MDNode::get(Context, {BaseType, AccessType, createConstant(Off),
+ createConstant(ConstantInt::get(Int64, 1))});
}
+ return MDNode::get(Context, {BaseType, AccessType, createConstant(Off)});
}
diff --git a/contrib/llvm/lib/IR/Metadata.cpp b/contrib/llvm/lib/IR/Metadata.cpp
index 1abcf0d18c91..ab1ba5e2035b 100644
--- a/contrib/llvm/lib/IR/Metadata.cpp
+++ b/contrib/llvm/lib/IR/Metadata.cpp
@@ -120,6 +120,38 @@ void MetadataAsValue::untrack() {
MetadataTracking::untrack(MD);
}
+bool MetadataTracking::track(void *Ref, Metadata &MD, OwnerTy Owner) {
+ assert(Ref && "Expected live reference");
+ assert((Owner || *static_cast<Metadata **>(Ref) == &MD) &&
+ "Reference without owner must be direct");
+ if (auto *R = ReplaceableMetadataImpl::get(MD)) {
+ R->addRef(Ref, Owner);
+ return true;
+ }
+ return false;
+}
+
+void MetadataTracking::untrack(void *Ref, Metadata &MD) {
+ assert(Ref && "Expected live reference");
+ if (auto *R = ReplaceableMetadataImpl::get(MD))
+ R->dropRef(Ref);
+}
+
+bool MetadataTracking::retrack(void *Ref, Metadata &MD, void *New) {
+ assert(Ref && "Expected live reference");
+ assert(New && "Expected live reference");
+ assert(Ref != New && "Expected change");
+ if (auto *R = ReplaceableMetadataImpl::get(MD)) {
+ R->moveRef(Ref, New, MD);
+ return true;
+ }
+ return false;
+}
+
+bool MetadataTracking::isReplaceable(const Metadata &MD) {
+ return ReplaceableMetadataImpl::get(const_cast<Metadata &>(MD));
+}
+
void ReplaceableMetadataImpl::addRef(void *Ref, OwnerTy Owner) {
bool WasInserted =
UseMap.insert(std::make_pair(Ref, std::make_pair(Owner, NextIndex)))
@@ -239,6 +271,12 @@ void ReplaceableMetadataImpl::resolveAllUses(bool ResolveUsers) {
}
}
+ReplaceableMetadataImpl *ReplaceableMetadataImpl::get(Metadata &MD) {
+ if (auto *N = dyn_cast<MDNode>(&MD))
+ return N->Context.getReplaceableUses();
+ return dyn_cast<ValueAsMetadata>(&MD);
+}
+
static Function *getLocalFunction(Value *V) {
assert(V && "Expected value");
if (auto *A = dyn_cast<Argument>(V))
@@ -517,7 +555,7 @@ void MDNode::decrementUnresolvedOperandCount() {
resolve();
}
-void MDNode::resolveCycles() {
+void MDNode::resolveCycles(bool MDMaterialized) {
if (isResolved())
return;
@@ -530,6 +568,8 @@ void MDNode::resolveCycles() {
if (!N)
continue;
+ if (N->isTemporary() && !MDMaterialized)
+ continue;
assert(!N->isTemporary() &&
"Expected all forward declarations to be resolved");
if (!N->isResolved())
@@ -545,6 +585,18 @@ static bool hasSelfReference(MDNode *N) {
}
MDNode *MDNode::replaceWithPermanentImpl() {
+ switch (getMetadataID()) {
+ default:
+ // If this type isn't uniquable, replace with a distinct node.
+ return replaceWithDistinctImpl();
+
+#define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) \
+ case CLASS##Kind: \
+ break;
+#include "llvm/IR/Metadata.def"
+ }
+
+ // Even if this type is uniquable, self-references have to be distinct.
if (hasSelfReference(this))
return replaceWithDistinctImpl();
return replaceWithUniquedImpl();
@@ -671,8 +723,8 @@ MDNode *MDNode::uniquify() {
// Try to insert into uniquing store.
switch (getMetadataID()) {
default:
- llvm_unreachable("Invalid subclass of MDNode");
-#define HANDLE_MDNODE_LEAF(CLASS) \
+ llvm_unreachable("Invalid or non-uniquable subclass of MDNode");
+#define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) \
case CLASS##Kind: { \
CLASS *SubclassThis = cast<CLASS>(this); \
std::integral_constant<bool, HasCachedHash<CLASS>::value> \
@@ -687,8 +739,8 @@ MDNode *MDNode::uniquify() {
void MDNode::eraseFromStore() {
switch (getMetadataID()) {
default:
- llvm_unreachable("Invalid subclass of MDNode");
-#define HANDLE_MDNODE_LEAF(CLASS) \
+ llvm_unreachable("Invalid or non-uniquable subclass of MDNode");
+#define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) \
case CLASS##Kind: \
getContext().pImpl->CLASS##s.erase(cast<CLASS>(this)); \
break;
@@ -941,6 +993,17 @@ MDNode *MDNode::getMostGenericRange(MDNode *A, MDNode *B) {
return MDNode::get(A->getContext(), MDs);
}
+MDNode *MDNode::getMostGenericAlignmentOrDereferenceable(MDNode *A, MDNode *B) {
+ if (!A || !B)
+ return nullptr;
+
+ ConstantInt *AVal = mdconst::extract<ConstantInt>(A->getOperand(0));
+ ConstantInt *BVal = mdconst::extract<ConstantInt>(B->getOperand(0));
+ if (AVal->getZExtValue() < BVal->getZExtValue())
+ return A;
+ return B;
+}
+
//===----------------------------------------------------------------------===//
// NamedMDNode implementation.
//
@@ -1045,14 +1108,10 @@ MDNode *Instruction::getMetadataImpl(StringRef Kind) const {
return getMetadataImpl(getContext().getMDKindID(Kind));
}
-void Instruction::dropUnknownMetadata(ArrayRef<unsigned> KnownIDs) {
+void Instruction::dropUnknownNonDebugMetadata(ArrayRef<unsigned> KnownIDs) {
SmallSet<unsigned, 5> KnownSet;
KnownSet.insert(KnownIDs.begin(), KnownIDs.end());
- // Drop debug if needed
- if (KnownSet.erase(LLVMContext::MD_dbg))
- DbgLoc = DebugLoc();
-
if (!hasMetadataHashEntry())
return; // Nothing to remove!
@@ -1077,7 +1136,7 @@ void Instruction::dropUnknownMetadata(ArrayRef<unsigned> KnownIDs) {
}
}
-/// setMetadata - Set the metadata of of the specified kind to the specified
+/// setMetadata - Set the metadata of the specified kind to the specified
/// node. This updates/replaces metadata if already present, or removes it if
/// Node is null.
void Instruction::setMetadata(unsigned KindID, MDNode *Node) {
@@ -1251,3 +1310,11 @@ void Function::clearMetadata() {
getContext().pImpl->FunctionMetadata.erase(this);
setHasMetadataHashEntry(false);
}
+
+void Function::setSubprogram(DISubprogram *SP) {
+ setMetadata(LLVMContext::MD_dbg, SP);
+}
+
+DISubprogram *Function::getSubprogram() const {
+ return cast_or_null<DISubprogram>(getMetadata(LLVMContext::MD_dbg));
+}
diff --git a/contrib/llvm/lib/IR/MetadataImpl.h b/contrib/llvm/lib/IR/MetadataImpl.h
index 662a50eb1bdc..b9137460bd20 100644
--- a/contrib/llvm/lib/IR/MetadataImpl.h
+++ b/contrib/llvm/lib/IR/MetadataImpl.h
@@ -26,6 +26,19 @@ static T *getUniqued(DenseSet<T *, InfoT> &Store,
return I == Store.end() ? nullptr : *I;
}
+template <class T> T *MDNode::storeImpl(T *N, StorageType Storage) {
+ switch (Storage) {
+ case Uniqued:
+ llvm_unreachable("Cannot unique without a uniquing-store");
+ case Distinct:
+ N->storeDistinctInContext();
+ break;
+ case Temporary:
+ break;
+ }
+ return N;
+}
+
template <class T, class StoreT>
T *MDNode::storeImpl(T *N, StorageType Storage, StoreT &Store) {
switch (Storage) {
diff --git a/contrib/llvm/lib/IR/MetadataTracking.cpp b/contrib/llvm/lib/IR/MetadataTracking.cpp
deleted file mode 100644
index 47f0b9366d7d..000000000000
--- a/contrib/llvm/lib/IR/MetadataTracking.cpp
+++ /dev/null
@@ -1,55 +0,0 @@
-//===- MetadataTracking.cpp - Implement metadata tracking -----------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements Metadata tracking.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/IR/MetadataTracking.h"
-#include "llvm/IR/Metadata.h"
-
-using namespace llvm;
-
-ReplaceableMetadataImpl *ReplaceableMetadataImpl::get(Metadata &MD) {
- if (auto *N = dyn_cast<MDNode>(&MD))
- return N->Context.getReplaceableUses();
- return dyn_cast<ValueAsMetadata>(&MD);
-}
-
-bool MetadataTracking::track(void *Ref, Metadata &MD, OwnerTy Owner) {
- assert(Ref && "Expected live reference");
- assert((Owner || *static_cast<Metadata **>(Ref) == &MD) &&
- "Reference without owner must be direct");
- if (auto *R = ReplaceableMetadataImpl::get(MD)) {
- R->addRef(Ref, Owner);
- return true;
- }
- return false;
-}
-
-void MetadataTracking::untrack(void *Ref, Metadata &MD) {
- assert(Ref && "Expected live reference");
- if (auto *R = ReplaceableMetadataImpl::get(MD))
- R->dropRef(Ref);
-}
-
-bool MetadataTracking::retrack(void *Ref, Metadata &MD, void *New) {
- assert(Ref && "Expected live reference");
- assert(New && "Expected live reference");
- assert(Ref != New && "Expected change");
- if (auto *R = ReplaceableMetadataImpl::get(MD)) {
- R->moveRef(Ref, New, MD);
- return true;
- }
- return false;
-}
-
-bool MetadataTracking::isReplaceable(const Metadata &MD) {
- return ReplaceableMetadataImpl::get(const_cast<Metadata &>(MD));
-}
diff --git a/contrib/llvm/lib/IR/Module.cpp b/contrib/llvm/lib/IR/Module.cpp
index 043f74e12da3..ac578d6dba0f 100644
--- a/contrib/llvm/lib/IR/Module.cpp
+++ b/contrib/llvm/lib/IR/Module.cpp
@@ -29,6 +29,7 @@
#include <algorithm>
#include <cstdarg>
#include <cstdlib>
+
using namespace llvm;
//===----------------------------------------------------------------------===//
@@ -37,9 +38,9 @@ using namespace llvm;
// Explicit instantiations of SymbolTableListTraits since some of the methods
// are not in the public header file.
-template class llvm::SymbolTableListTraits<Function, Module>;
-template class llvm::SymbolTableListTraits<GlobalVariable, Module>;
-template class llvm::SymbolTableListTraits<GlobalAlias, Module>;
+template class llvm::SymbolTableListTraits<Function>;
+template class llvm::SymbolTableListTraits<GlobalVariable>;
+template class llvm::SymbolTableListTraits<GlobalAlias>;
//===----------------------------------------------------------------------===//
// Primitive Module methods.
@@ -81,7 +82,6 @@ RandomNumberGenerator *Module::createRNG(const Pass* P) const {
return new RandomNumberGenerator(Salt);
}
-
/// getNamedValue - Return the first global value in the module with
/// the specified name, of arbitrary type. This method returns null
/// if a global with the specified name is not found.
@@ -102,6 +102,9 @@ void Module::getMDKindNames(SmallVectorImpl<StringRef> &Result) const {
return Context.getMDKindNames(Result);
}
+void Module::getOperandBundleTags(SmallVectorImpl<StringRef> &Result) const {
+ return Context.getOperandBundleTags(Result);
+}
//===----------------------------------------------------------------------===//
// Methods for easy access to the functions in the module.
@@ -274,7 +277,7 @@ NamedMDNode *Module::getOrInsertNamedMetadata(StringRef Name) {
/// delete it.
void Module::eraseNamedMetadata(NamedMDNode *NMD) {
static_cast<StringMap<NamedMDNode *> *>(NamedMDSymTab)->erase(NMD->getName());
- NamedMDList.erase(NMD);
+ NamedMDList.erase(NMD->getIterator());
}
bool Module::isValidModFlagBehavior(Metadata *MD, ModFlagBehavior &MFB) {
@@ -376,17 +379,11 @@ const DataLayout &Module::getDataLayout() const { return DL; }
//
void Module::setMaterializer(GVMaterializer *GVM) {
assert(!Materializer &&
- "Module already has a GVMaterializer. Call MaterializeAllPermanently"
+ "Module already has a GVMaterializer. Call materializeAll"
" to clear it out before setting another one.");
Materializer.reset(GVM);
}
-bool Module::isDematerializable(const GlobalValue *GV) const {
- if (Materializer)
- return Materializer->isDematerializable(GV);
- return false;
-}
-
std::error_code Module::materialize(GlobalValue *GV) {
if (!Materializer)
return std::error_code();
@@ -394,23 +391,11 @@ std::error_code Module::materialize(GlobalValue *GV) {
return Materializer->materialize(GV);
}
-void Module::dematerialize(GlobalValue *GV) {
- if (Materializer)
- return Materializer->dematerialize(GV);
-}
-
std::error_code Module::materializeAll() {
if (!Materializer)
return std::error_code();
- return Materializer->materializeModule(this);
-}
-
-std::error_code Module::materializeAllPermanently() {
- if (std::error_code EC = materializeAll())
- return EC;
-
- Materializer.reset();
- return std::error_code();
+ std::unique_ptr<GVMaterializer> M = std::move(Materializer);
+ return M->materializeModule();
}
std::error_code Module::materializeMetadata() {
@@ -458,7 +443,14 @@ void Module::dropAllReferences() {
unsigned Module::getDwarfVersion() const {
auto *Val = cast_or_null<ConstantAsMetadata>(getModuleFlag("Dwarf Version"));
if (!Val)
- return dwarf::DWARF_VERSION;
+ return 0;
+ return cast<ConstantInt>(Val->getValue())->getZExtValue();
+}
+
+unsigned Module::getCodeViewFlag() const {
+ auto *Val = cast_or_null<ConstantAsMetadata>(getModuleFlag("CodeView"));
+ if (!Val)
+ return 0;
return cast<ConstantInt>(Val->getValue())->getZExtValue();
}
@@ -471,7 +463,7 @@ Comdat *Module::getOrInsertComdat(StringRef Name) {
PICLevel::Level Module::getPICLevel() const {
auto *Val = cast_or_null<ConstantAsMetadata>(getModuleFlag("PIC Level"));
- if (Val == NULL)
+ if (!Val)
return PICLevel::Default;
return static_cast<PICLevel::Level>(
@@ -481,3 +473,15 @@ PICLevel::Level Module::getPICLevel() const {
void Module::setPICLevel(PICLevel::Level PL) {
addModuleFlag(ModFlagBehavior::Error, "PIC Level", PL);
}
+
+void Module::setMaximumFunctionCount(uint64_t Count) {
+ addModuleFlag(ModFlagBehavior::Error, "MaxFunctionCount", Count);
+}
+
+Optional<uint64_t> Module::getMaximumFunctionCount() {
+ auto *Val =
+ cast_or_null<ConstantAsMetadata>(getModuleFlag("MaxFunctionCount"));
+ if (!Val)
+ return None;
+ return cast<ConstantInt>(Val->getValue())->getZExtValue();
+}
diff --git a/contrib/llvm/lib/IR/Statepoint.cpp b/contrib/llvm/lib/IR/Statepoint.cpp
index 83ee611cc375..d45c1883ef9e 100644
--- a/contrib/llvm/lib/IR/Statepoint.cpp
+++ b/contrib/llvm/lib/IR/Statepoint.cpp
@@ -67,10 +67,7 @@ bool llvm::isGCResult(const ImmutableCallSite &CS) {
bool llvm::isGCResult(const Value *inst) {
if (const CallInst *call = dyn_cast<CallInst>(inst)) {
if (Function *F = call->getCalledFunction()) {
- return (F->getIntrinsicID() == Intrinsic::experimental_gc_result_int ||
- F->getIntrinsicID() == Intrinsic::experimental_gc_result_float ||
- F->getIntrinsicID() == Intrinsic::experimental_gc_result_ptr ||
- F->getIntrinsicID() == Intrinsic::experimental_gc_result);
+ return F->getIntrinsicID() == Intrinsic::experimental_gc_result;
}
}
return false;
diff --git a/contrib/llvm/lib/IR/SymbolTableListTraitsImpl.h b/contrib/llvm/lib/IR/SymbolTableListTraitsImpl.h
index a18f98261abc..50573d8d688a 100644
--- a/contrib/llvm/lib/IR/SymbolTableListTraitsImpl.h
+++ b/contrib/llvm/lib/IR/SymbolTableListTraitsImpl.h
@@ -24,77 +24,73 @@ namespace llvm {
/// setSymTabObject - This is called when (f.e.) the parent of a basic block
/// changes. This requires us to remove all the instruction symtab entries from
/// the current function and reinsert them into the new function.
-template<typename ValueSubClass, typename ItemParentClass>
-template<typename TPtr>
-void SymbolTableListTraits<ValueSubClass,ItemParentClass>
-::setSymTabObject(TPtr *Dest, TPtr Src) {
+template <typename ValueSubClass>
+template <typename TPtr>
+void SymbolTableListTraits<ValueSubClass>::setSymTabObject(TPtr *Dest,
+ TPtr Src) {
// Get the old symtab and value list before doing the assignment.
- ValueSymbolTable *OldST = TraitsClass::getSymTab(getListOwner());
+ ValueSymbolTable *OldST = getSymTab(getListOwner());
// Do it.
*Dest = Src;
// Get the new SymTab object.
- ValueSymbolTable *NewST = TraitsClass::getSymTab(getListOwner());
+ ValueSymbolTable *NewST = getSymTab(getListOwner());
// If there is nothing to do, quick exit.
if (OldST == NewST) return;
// Move all the elements from the old symtab to the new one.
- iplist<ValueSubClass> &ItemList = TraitsClass::getList(getListOwner());
+ ListTy &ItemList = getList(getListOwner());
if (ItemList.empty()) return;
if (OldST) {
// Remove all entries from the previous symtab.
- for (typename iplist<ValueSubClass>::iterator I = ItemList.begin();
- I != ItemList.end(); ++I)
+ for (auto I = ItemList.begin(); I != ItemList.end(); ++I)
if (I->hasName())
OldST->removeValueName(I->getValueName());
}
if (NewST) {
// Add all of the items to the new symtab.
- for (typename iplist<ValueSubClass>::iterator I = ItemList.begin();
- I != ItemList.end(); ++I)
+ for (auto I = ItemList.begin(); I != ItemList.end(); ++I)
if (I->hasName())
- NewST->reinsertValue(I);
+ NewST->reinsertValue(&*I);
}
}
-template<typename ValueSubClass, typename ItemParentClass>
-void SymbolTableListTraits<ValueSubClass,ItemParentClass>
-::addNodeToList(ValueSubClass *V) {
+template <typename ValueSubClass>
+void SymbolTableListTraits<ValueSubClass>::addNodeToList(ValueSubClass *V) {
assert(!V->getParent() && "Value already in a container!!");
ItemParentClass *Owner = getListOwner();
V->setParent(Owner);
if (V->hasName())
- if (ValueSymbolTable *ST = TraitsClass::getSymTab(Owner))
+ if (ValueSymbolTable *ST = getSymTab(Owner))
ST->reinsertValue(V);
}
-template<typename ValueSubClass, typename ItemParentClass>
-void SymbolTableListTraits<ValueSubClass,ItemParentClass>
-::removeNodeFromList(ValueSubClass *V) {
+template <typename ValueSubClass>
+void SymbolTableListTraits<ValueSubClass>::removeNodeFromList(
+ ValueSubClass *V) {
V->setParent(nullptr);
if (V->hasName())
- if (ValueSymbolTable *ST = TraitsClass::getSymTab(getListOwner()))
+ if (ValueSymbolTable *ST = getSymTab(getListOwner()))
ST->removeValueName(V->getValueName());
}
-template<typename ValueSubClass, typename ItemParentClass>
-void SymbolTableListTraits<ValueSubClass,ItemParentClass>
-::transferNodesFromList(ilist_traits<ValueSubClass> &L2,
- ilist_iterator<ValueSubClass> first,
- ilist_iterator<ValueSubClass> last) {
+template <typename ValueSubClass>
+void SymbolTableListTraits<ValueSubClass>::transferNodesFromList(
+ SymbolTableListTraits &L2, ilist_iterator<ValueSubClass> first,
+ ilist_iterator<ValueSubClass> last) {
// We only have to do work here if transferring instructions between BBs
ItemParentClass *NewIP = getListOwner(), *OldIP = L2.getListOwner();
if (NewIP == OldIP) return; // No work to do at all...
// We only have to update symbol table entries if we are transferring the
// instructions to a different symtab object...
- ValueSymbolTable *NewST = TraitsClass::getSymTab(NewIP);
- ValueSymbolTable *OldST = TraitsClass::getSymTab(OldIP);
+ ValueSymbolTable *NewST = getSymTab(NewIP);
+ ValueSymbolTable *OldST = getSymTab(OldIP);
if (NewST != OldST) {
for (; first != last; ++first) {
ValueSubClass &V = *first;
diff --git a/contrib/llvm/lib/IR/Type.cpp b/contrib/llvm/lib/IR/Type.cpp
index a9ca80034ca7..4c1baf52a58f 100644
--- a/contrib/llvm/lib/IR/Type.cpp
+++ b/contrib/llvm/lib/IR/Type.cpp
@@ -35,6 +35,7 @@ Type *Type::getPrimitiveType(LLVMContext &C, TypeID IDNumber) {
case LabelTyID : return getLabelTy(C);
case MetadataTyID : return getMetadataTy(C);
case X86_MMXTyID : return getX86_MMXTy(C);
+ case TokenTyID : return getTokenTy(C);
default:
return nullptr;
}
@@ -42,16 +43,10 @@ Type *Type::getPrimitiveType(LLVMContext &C, TypeID IDNumber) {
/// getScalarType - If this is a vector type, return the element type,
/// otherwise return this.
-Type *Type::getScalarType() {
- if (VectorType *VTy = dyn_cast<VectorType>(this))
+Type *Type::getScalarType() const {
+ if (auto *VTy = dyn_cast<VectorType>(this))
return VTy->getElementType();
- return this;
-}
-
-const Type *Type::getScalarType() const {
- if (const VectorType *VTy = dyn_cast<VectorType>(this))
- return VTy->getElementType();
- return this;
+ return const_cast<Type*>(this);
}
/// isIntegerTy - Return true if this is an IntegerType of the specified width.
@@ -74,8 +69,8 @@ bool Type::canLosslesslyBitCastTo(Type *Ty) const {
// Vector -> Vector conversions are always lossless if the two vector types
// have the same size, otherwise not. Also, 64-bit vector types can be
// converted to x86mmx.
- if (const VectorType *thisPTy = dyn_cast<VectorType>(this)) {
- if (const VectorType *thatPTy = dyn_cast<VectorType>(Ty))
+ if (auto *thisPTy = dyn_cast<VectorType>(this)) {
+ if (auto *thatPTy = dyn_cast<VectorType>(Ty))
return thisPTy->getBitWidth() == thatPTy->getBitWidth();
if (Ty->getTypeID() == Type::X86_MMXTyID &&
thisPTy->getBitWidth() == 64)
@@ -83,7 +78,7 @@ bool Type::canLosslesslyBitCastTo(Type *Ty) const {
}
if (this->getTypeID() == Type::X86_MMXTyID)
- if (const VectorType *thatPTy = dyn_cast<VectorType>(Ty))
+ if (auto *thatPTy = dyn_cast<VectorType>(Ty))
if (thatPTy->getBitWidth() == 64)
return true;
@@ -91,8 +86,8 @@ bool Type::canLosslesslyBitCastTo(Type *Ty) const {
// remaining and ptr->ptr. Just select the lossless conversions. Everything
// else is not lossless. Conservatively assume we can't losslessly convert
// between pointers with different address spaces.
- if (const PointerType *PTy = dyn_cast<PointerType>(this)) {
- if (const PointerType *OtherPTy = dyn_cast<PointerType>(Ty))
+ if (auto *PTy = dyn_cast<PointerType>(this)) {
+ if (auto *OtherPTy = dyn_cast<PointerType>(Ty))
return PTy->getAddressSpace() == OtherPTy->getAddressSpace();
return false;
}
@@ -100,14 +95,12 @@ bool Type::canLosslesslyBitCastTo(Type *Ty) const {
}
bool Type::isEmptyTy() const {
- const ArrayType *ATy = dyn_cast<ArrayType>(this);
- if (ATy) {
+ if (auto *ATy = dyn_cast<ArrayType>(this)) {
unsigned NumElements = ATy->getNumElements();
return NumElements == 0 || ATy->getElementType()->isEmptyTy();
}
- const StructType *STy = dyn_cast<StructType>(this);
- if (STy) {
+ if (auto *STy = dyn_cast<StructType>(this)) {
unsigned NumElements = STy->getNumElements();
for (unsigned i = 0; i < NumElements; ++i)
if (!STy->getElementType(i)->isEmptyTy())
@@ -144,7 +137,7 @@ unsigned Type::getScalarSizeInBits() const {
/// is only valid on floating point types. If the FP type does not
/// have a stable mantissa (e.g. ppc long double), this method returns -1.
int Type::getFPMantissaWidth() const {
- if (const VectorType *VTy = dyn_cast<VectorType>(this))
+ if (auto *VTy = dyn_cast<VectorType>(this))
return VTy->getElementType()->getFPMantissaWidth();
assert(isFloatingPointTy() && "Not a floating point type!");
if (getTypeID() == HalfTyID) return 11;
@@ -159,66 +152,17 @@ int Type::getFPMantissaWidth() const {
/// isSizedDerivedType - Derived types like structures and arrays are sized
/// iff all of the members of the type are sized as well. Since asking for
/// their size is relatively uncommon, move this operation out of line.
-bool Type::isSizedDerivedType(SmallPtrSetImpl<const Type*> *Visited) const {
- if (const ArrayType *ATy = dyn_cast<ArrayType>(this))
+bool Type::isSizedDerivedType(SmallPtrSetImpl<Type*> *Visited) const {
+ if (auto *ATy = dyn_cast<ArrayType>(this))
return ATy->getElementType()->isSized(Visited);
- if (const VectorType *VTy = dyn_cast<VectorType>(this))
+ if (auto *VTy = dyn_cast<VectorType>(this))
return VTy->getElementType()->isSized(Visited);
return cast<StructType>(this)->isSized(Visited);
}
//===----------------------------------------------------------------------===//
-// Subclass Helper Methods
-//===----------------------------------------------------------------------===//
-
-unsigned Type::getIntegerBitWidth() const {
- return cast<IntegerType>(this)->getBitWidth();
-}
-
-bool Type::isFunctionVarArg() const {
- return cast<FunctionType>(this)->isVarArg();
-}
-
-Type *Type::getFunctionParamType(unsigned i) const {
- return cast<FunctionType>(this)->getParamType(i);
-}
-
-unsigned Type::getFunctionNumParams() const {
- return cast<FunctionType>(this)->getNumParams();
-}
-
-StringRef Type::getStructName() const {
- return cast<StructType>(this)->getName();
-}
-
-unsigned Type::getStructNumElements() const {
- return cast<StructType>(this)->getNumElements();
-}
-
-Type *Type::getStructElementType(unsigned N) const {
- return cast<StructType>(this)->getElementType(N);
-}
-
-Type *Type::getSequentialElementType() const {
- return cast<SequentialType>(this)->getElementType();
-}
-
-uint64_t Type::getArrayNumElements() const {
- return cast<ArrayType>(this)->getNumElements();
-}
-
-unsigned Type::getVectorNumElements() const {
- return cast<VectorType>(this)->getNumElements();
-}
-
-unsigned Type::getPointerAddressSpace() const {
- return cast<PointerType>(getScalarType())->getAddressSpace();
-}
-
-
-//===----------------------------------------------------------------------===//
// Primitive 'Type' data
//===----------------------------------------------------------------------===//
@@ -228,6 +172,7 @@ Type *Type::getHalfTy(LLVMContext &C) { return &C.pImpl->HalfTy; }
Type *Type::getFloatTy(LLVMContext &C) { return &C.pImpl->FloatTy; }
Type *Type::getDoubleTy(LLVMContext &C) { return &C.pImpl->DoubleTy; }
Type *Type::getMetadataTy(LLVMContext &C) { return &C.pImpl->MetadataTy; }
+Type *Type::getTokenTy(LLVMContext &C) { return &C.pImpl->TokenTy; }
Type *Type::getX86_FP80Ty(LLVMContext &C) { return &C.pImpl->X86_FP80Ty; }
Type *Type::getFP128Ty(LLVMContext &C) { return &C.pImpl->FP128Ty; }
Type *Type::getPPC_FP128Ty(LLVMContext &C) { return &C.pImpl->PPC_FP128Ty; }
@@ -345,7 +290,7 @@ FunctionType::FunctionType(Type *Result, ArrayRef<Type*> Params,
assert(isValidReturnType(Result) && "invalid return type for function");
setSubclassData(IsVarArgs);
- SubTys[0] = const_cast<Type*>(Result);
+ SubTys[0] = Result;
for (unsigned i = 0, e = Params.size(); i != e; ++i) {
assert(isValidArgumentType(Params[i]) &&
@@ -428,12 +373,14 @@ void StructType::setBody(ArrayRef<Type*> Elements, bool isPacked) {
if (isPacked)
setSubclassData(getSubclassData() | SCDB_Packed);
- unsigned NumElements = Elements.size();
- Type **Elts = getContext().pImpl->TypeAllocator.Allocate<Type*>(NumElements);
- memcpy(Elts, Elements.data(), sizeof(Elements[0]) * NumElements);
-
- ContainedTys = Elts;
- NumContainedTys = NumElements;
+ NumContainedTys = Elements.size();
+
+ if (Elements.empty()) {
+ ContainedTys = nullptr;
+ return;
+ }
+
+ ContainedTys = Elements.copy(getContext().pImpl->TypeAllocator).data();
}
void StructType::setName(StringRef Name) {
@@ -470,7 +417,6 @@ void StructType::setName(StringRef Name) {
do {
TempStr.resize(NameSize + 1);
- TmpStream.resync();
TmpStream << getContext().pImpl->NamedStructTypesUniqueID++;
IterBool = getContext().pImpl->NamedStructTypes.insert(
@@ -556,13 +502,13 @@ StructType *StructType::create(StringRef Name, Type *type, ...) {
return Ret;
}
-bool StructType::isSized(SmallPtrSetImpl<const Type*> *Visited) const {
+bool StructType::isSized(SmallPtrSetImpl<Type*> *Visited) const {
if ((getSubclassData() & SCDB_IsSized) != 0)
return true;
if (isOpaque())
return false;
- if (Visited && !Visited->insert(this).second)
+ if (Visited && !Visited->insert(const_cast<StructType*>(this)).second)
return false;
// Okay, our struct is sized if all of the elements are, but if one of the
@@ -602,22 +548,19 @@ void StructType::setBody(Type *type, ...) {
bool StructType::isValidElementType(Type *ElemTy) {
return !ElemTy->isVoidTy() && !ElemTy->isLabelTy() &&
- !ElemTy->isMetadataTy() && !ElemTy->isFunctionTy();
+ !ElemTy->isMetadataTy() && !ElemTy->isFunctionTy() &&
+ !ElemTy->isTokenTy();
}
/// isLayoutIdentical - Return true if this is layout identical to the
/// specified struct.
bool StructType::isLayoutIdentical(StructType *Other) const {
if (this == Other) return true;
-
- if (isPacked() != Other->isPacked() ||
- getNumElements() != Other->getNumElements())
+
+ if (isPacked() != Other->isPacked())
return false;
- if (!getNumElements())
- return true;
-
- return std::equal(element_begin(), element_end(), Other->element_begin());
+ return elements() == Other->elements();
}
/// getTypeByName - Return the type with the specified name, or null if there
@@ -631,8 +574,8 @@ StructType *Module::getTypeByName(StringRef Name) const {
// CompositeType Implementation
//===----------------------------------------------------------------------===//
-Type *CompositeType::getTypeAtIndex(const Value *V) {
- if (StructType *STy = dyn_cast<StructType>(this)) {
+Type *CompositeType::getTypeAtIndex(const Value *V) const {
+ if (auto *STy = dyn_cast<StructType>(this)) {
unsigned Idx =
(unsigned)cast<Constant>(V)->getUniqueInteger().getZExtValue();
assert(indexValid(Idx) && "Invalid structure index!");
@@ -641,16 +584,18 @@ Type *CompositeType::getTypeAtIndex(const Value *V) {
return cast<SequentialType>(this)->getElementType();
}
-Type *CompositeType::getTypeAtIndex(unsigned Idx) {
- if (StructType *STy = dyn_cast<StructType>(this)) {
+
+Type *CompositeType::getTypeAtIndex(unsigned Idx) const{
+ if (auto *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)) {
+ if (auto *STy = dyn_cast<StructType>(this)) {
// Structure indexes require (vectors of) 32-bit integer constants. In the
// vector case all of the indices must be equal.
if (!V->getType()->getScalarType()->isIntegerTy(32))
@@ -667,7 +612,7 @@ bool CompositeType::indexValid(const Value *V) const {
}
bool CompositeType::indexValid(unsigned Idx) const {
- if (const StructType *STy = dyn_cast<StructType>(this))
+ if (auto *STy = dyn_cast<StructType>(this))
return Idx < STy->getNumElements();
// Sequential types can be indexed by any integer.
return true;
@@ -683,10 +628,9 @@ ArrayType::ArrayType(Type *ElType, uint64_t NumEl)
NumElements = NumEl;
}
-ArrayType *ArrayType::get(Type *elementType, uint64_t NumElements) {
- Type *ElementType = const_cast<Type*>(elementType);
+ArrayType *ArrayType::get(Type *ElementType, uint64_t NumElements) {
assert(isValidElementType(ElementType) && "Invalid type for array element!");
-
+
LLVMContextImpl *pImpl = ElementType->getContext().pImpl;
ArrayType *&Entry =
pImpl->ArrayTypes[std::make_pair(ElementType, NumElements)];
@@ -698,7 +642,8 @@ ArrayType *ArrayType::get(Type *elementType, uint64_t NumElements) {
bool ArrayType::isValidElementType(Type *ElemTy) {
return !ElemTy->isVoidTy() && !ElemTy->isLabelTy() &&
- !ElemTy->isMetadataTy() && !ElemTy->isFunctionTy();
+ !ElemTy->isMetadataTy() && !ElemTy->isFunctionTy() &&
+ !ElemTy->isTokenTy();
}
//===----------------------------------------------------------------------===//
@@ -710,8 +655,7 @@ VectorType::VectorType(Type *ElType, unsigned NumEl)
NumElements = NumEl;
}
-VectorType *VectorType::get(Type *elementType, unsigned NumElements) {
- Type *ElementType = const_cast<Type*>(elementType);
+VectorType *VectorType::get(Type *ElementType, unsigned NumElements) {
assert(NumElements > 0 && "#Elements of a VectorType must be greater than 0");
assert(isValidElementType(ElementType) && "Element type of a VectorType must "
"be an integer, floating point, or "
@@ -761,13 +705,13 @@ PointerType::PointerType(Type *E, unsigned AddrSpace)
assert(oldNCT == NumContainedTys && "bitfield written out of bounds?");
}
-PointerType *Type::getPointerTo(unsigned addrs) {
- return PointerType::get(this, addrs);
+PointerType *Type::getPointerTo(unsigned addrs) const {
+ return PointerType::get(const_cast<Type*>(this), addrs);
}
bool PointerType::isValidElementType(Type *ElemTy) {
return !ElemTy->isVoidTy() && !ElemTy->isLabelTy() &&
- !ElemTy->isMetadataTy();
+ !ElemTy->isMetadataTy() && !ElemTy->isTokenTy();
}
bool PointerType::isLoadableOrStorableType(Type *ElemTy) {
diff --git a/contrib/llvm/lib/IR/TypeFinder.cpp b/contrib/llvm/lib/IR/TypeFinder.cpp
index 7accc5bef535..b5bdab0865b6 100644
--- a/contrib/llvm/lib/IR/TypeFinder.cpp
+++ b/contrib/llvm/lib/IR/TypeFinder.cpp
@@ -44,19 +44,13 @@ void TypeFinder::run(const Module &M, bool onlyNamed) {
for (Module::const_iterator FI = M.begin(), E = M.end(); FI != E; ++FI) {
incorporateType(FI->getType());
- if (FI->hasPrefixData())
- incorporateValue(FI->getPrefixData());
-
- if (FI->hasPrologueData())
- incorporateValue(FI->getPrologueData());
-
- if (FI->hasPersonalityFn())
- incorporateValue(FI->getPersonalityFn());
+ for (const Use &U : FI->operands())
+ incorporateValue(U.get());
// First incorporate the arguments.
for (Function::const_arg_iterator AI = FI->arg_begin(),
AE = FI->arg_end(); AI != AE; ++AI)
- incorporateValue(AI);
+ incorporateValue(&*AI);
for (Function::const_iterator BB = FI->begin(), E = FI->end();
BB != E;++BB)
@@ -85,7 +79,7 @@ void TypeFinder::run(const Module &M, bool onlyNamed) {
for (Module::const_named_metadata_iterator I = M.named_metadata_begin(),
E = M.named_metadata_end(); I != E; ++I) {
- const NamedMDNode *NMD = I;
+ const NamedMDNode *NMD = &*I;
for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i)
incorporateMDNode(NMD->getOperand(i));
}
diff --git a/contrib/llvm/lib/IR/User.cpp b/contrib/llvm/lib/IR/User.cpp
index 522722d701ba..a75abe6938c9 100644
--- a/contrib/llvm/lib/IR/User.cpp
+++ b/contrib/llvm/lib/IR/User.cpp
@@ -87,22 +87,70 @@ void User::growHungoffUses(unsigned NewNumUses, bool IsPhi) {
Use::zap(OldOps, OldOps + OldNumUses, true);
}
+
+// This is a private struct used by `User` to track the co-allocated descriptor
+// section.
+struct DescriptorInfo {
+ intptr_t SizeInBytes;
+};
+
+ArrayRef<const uint8_t> User::getDescriptor() const {
+ auto MutableARef = const_cast<User *>(this)->getDescriptor();
+ return {MutableARef.begin(), MutableARef.end()};
+}
+
+MutableArrayRef<uint8_t> User::getDescriptor() {
+ assert(HasDescriptor && "Don't call otherwise!");
+ assert(!HasHungOffUses && "Invariant!");
+
+ auto *DI = reinterpret_cast<DescriptorInfo *>(getIntrusiveOperands()) - 1;
+ assert(DI->SizeInBytes != 0 && "Should not have had a descriptor otherwise!");
+
+ return MutableArrayRef<uint8_t>(
+ reinterpret_cast<uint8_t *>(DI) - DI->SizeInBytes, DI->SizeInBytes);
+}
+
//===----------------------------------------------------------------------===//
// User operator new Implementations
//===----------------------------------------------------------------------===//
-void *User::operator new(size_t Size, unsigned Us) {
+void *User::allocateFixedOperandUser(size_t Size, unsigned Us,
+ unsigned DescBytes) {
assert(Us < (1u << NumUserOperandsBits) && "Too many operands");
- void *Storage = ::operator new(Size + sizeof(Use) * Us);
- Use *Start = static_cast<Use*>(Storage);
+
+ static_assert(sizeof(DescriptorInfo) % sizeof(void *) == 0, "Required below");
+
+ unsigned DescBytesToAllocate =
+ DescBytes == 0 ? 0 : (DescBytes + sizeof(DescriptorInfo));
+ assert(DescBytesToAllocate % sizeof(void *) == 0 &&
+ "We need this to satisfy alignment constraints for Uses");
+
+ uint8_t *Storage = static_cast<uint8_t *>(
+ ::operator new(Size + sizeof(Use) * Us + DescBytesToAllocate));
+ Use *Start = reinterpret_cast<Use *>(Storage + DescBytesToAllocate);
Use *End = Start + Us;
User *Obj = reinterpret_cast<User*>(End);
Obj->NumUserOperands = Us;
Obj->HasHungOffUses = false;
+ Obj->HasDescriptor = DescBytes != 0;
Use::initTags(Start, End);
+
+ if (DescBytes != 0) {
+ auto *DescInfo = reinterpret_cast<DescriptorInfo *>(Storage + DescBytes);
+ DescInfo->SizeInBytes = DescBytes;
+ }
+
return Obj;
}
+void *User::operator new(size_t Size, unsigned Us) {
+ return allocateFixedOperandUser(Size, Us, 0);
+}
+
+void *User::operator new(size_t Size, unsigned Us, unsigned DescBytes) {
+ return allocateFixedOperandUser(Size, Us, DescBytes);
+}
+
void *User::operator new(size_t Size) {
// Allocate space for a single Use*
void *Storage = ::operator new(Size + sizeof(Use *));
@@ -110,6 +158,7 @@ void *User::operator new(size_t Size) {
User *Obj = reinterpret_cast<User *>(HungOffOperandList + 1);
Obj->NumUserOperands = 0;
Obj->HasHungOffUses = true;
+ Obj->HasDescriptor = false;
*HungOffOperandList = nullptr;
return Obj;
}
@@ -123,11 +172,20 @@ void User::operator delete(void *Usr) {
// use a Use[] allocated prior to the user.
User *Obj = static_cast<User *>(Usr);
if (Obj->HasHungOffUses) {
+ assert(!Obj->HasDescriptor && "not supported!");
+
Use **HungOffOperandList = static_cast<Use **>(Usr) - 1;
// drop the hung off uses.
Use::zap(*HungOffOperandList, *HungOffOperandList + Obj->NumUserOperands,
/* Delete */ true);
::operator delete(HungOffOperandList);
+ } else if (Obj->HasDescriptor) {
+ Use *UseBegin = static_cast<Use *>(Usr) - Obj->NumUserOperands;
+ Use::zap(UseBegin, UseBegin + Obj->NumUserOperands, /* Delete */ false);
+
+ auto *DI = reinterpret_cast<DescriptorInfo *>(UseBegin) - 1;
+ uint8_t *Storage = reinterpret_cast<uint8_t *>(DI) - DI->SizeInBytes;
+ ::operator delete(Storage);
} else {
Use *Storage = static_cast<Use *>(Usr) - Obj->NumUserOperands;
Use::zap(Storage, Storage + Obj->NumUserOperands,
diff --git a/contrib/llvm/lib/IR/Value.cpp b/contrib/llvm/lib/IR/Value.cpp
index f554d590284f..eb9deb6a07e1 100644
--- a/contrib/llvm/lib/IR/Value.cpp
+++ b/contrib/llvm/lib/IR/Value.cpp
@@ -314,6 +314,16 @@ void Value::takeName(Value *V) {
}
#ifndef NDEBUG
+void Value::assertModuleIsMaterialized() const {
+ const GlobalValue *GV = dyn_cast<GlobalValue>(this);
+ if (!GV)
+ return;
+ const Module *M = GV->getParent();
+ if (!M)
+ return;
+ assert(M->isMaterialized());
+}
+
static bool contains(SmallPtrSetImpl<ConstantExpr *> &Cache, ConstantExpr *Expr,
Constant *C) {
if (!Cache.insert(Expr).second)
@@ -490,8 +500,7 @@ Value *Value::stripAndAccumulateInBoundsConstantOffsets(const DataLayout &DL,
return V;
Offset = GEPOffset;
V = GEP->getPointerOperand();
- } else if (Operator::getOpcode(V) == Instruction::BitCast ||
- Operator::getOpcode(V) == Instruction::AddrSpaceCast) {
+ } else if (Operator::getOpcode(V) == Instruction::BitCast) {
V = cast<Operator>(V)->getOperand(0);
} else if (GlobalAlias *GA = dyn_cast<GlobalAlias>(V)) {
V = GA->getAliasee();
diff --git a/contrib/llvm/lib/IR/ValueSymbolTable.cpp b/contrib/llvm/lib/IR/ValueSymbolTable.cpp
index e10142de8232..deb6e7573e72 100644
--- a/contrib/llvm/lib/IR/ValueSymbolTable.cpp
+++ b/contrib/llvm/lib/IR/ValueSymbolTable.cpp
@@ -32,6 +32,24 @@ ValueSymbolTable::~ValueSymbolTable() {
#endif
}
+ValueName *ValueSymbolTable::makeUniqueName(Value *V,
+ SmallString<256> &UniqueName) {
+ unsigned BaseSize = UniqueName.size();
+ while (1) {
+ // Trim any suffix off and append the next number.
+ UniqueName.resize(BaseSize);
+ raw_svector_ostream S(UniqueName);
+ if (isa<GlobalValue>(V))
+ S << ".";
+ S << ++LastUnique;
+
+ // Try insert the vmap entry with this suffix.
+ auto IterBool = vmap.insert(std::make_pair(UniqueName, V));
+ if (IterBool.second)
+ return &*IterBool.first;
+ }
+}
+
// Insert a value into the symbol table with the specified name...
//
void ValueSymbolTable::reinsertValue(Value* V) {
@@ -49,21 +67,8 @@ void ValueSymbolTable::reinsertValue(Value* V) {
// The name is too already used, just free it so we can allocate a new name.
V->getValueName()->Destroy();
- unsigned BaseSize = UniqueName.size();
- while (1) {
- // Trim any suffix off and append the next number.
- UniqueName.resize(BaseSize);
- raw_svector_ostream(UniqueName) << "." << ++LastUnique;
-
- // Try insert the vmap entry with this suffix.
- auto IterBool = vmap.insert(std::make_pair(UniqueName, V));
- if (IterBool.second) {
- // Newly inserted name. Success!
- V->setValueName(&*IterBool.first);
- //DEBUG(dbgs() << " Inserted value: " << UniqueName << ": " << *V << "\n");
- return;
- }
- }
+ ValueName *VN = makeUniqueName(V, UniqueName);
+ V->setValueName(VN);
}
void ValueSymbolTable::removeValueName(ValueName *V) {
@@ -86,20 +91,7 @@ ValueName *ValueSymbolTable::createValueName(StringRef Name, Value *V) {
// Otherwise, there is a naming conflict. Rename this value.
SmallString<256> UniqueName(Name.begin(), Name.end());
-
- while (1) {
- // Trim any suffix off and append the next number.
- UniqueName.resize(Name.size());
- raw_svector_ostream(UniqueName) << ++LastUnique;
-
- // Try insert the vmap entry with this suffix.
- auto IterBool = vmap.insert(std::make_pair(UniqueName, V));
- if (IterBool.second) {
- // DEBUG(dbgs() << " Inserted value: " << UniqueName << ": " << *V <<
- // "\n");
- return &*IterBool.first;
- }
- }
+ return makeUniqueName(V, UniqueName);
}
diff --git a/contrib/llvm/lib/IR/ValueTypes.cpp b/contrib/llvm/lib/IR/ValueTypes.cpp
index d95de3989df0..f2932302af2a 100644
--- a/contrib/llvm/lib/IR/ValueTypes.cpp
+++ b/contrib/llvm/lib/IR/ValueTypes.cpp
@@ -19,6 +19,11 @@
#include "llvm/Support/ErrorHandling.h"
using namespace llvm;
+EVT EVT::changeExtendedTypeToInteger() const {
+ LLVMContext &Context = LLVMTy->getContext();
+ return getIntegerVT(Context, getSizeInBits());
+}
+
EVT EVT::changeExtendedVectorElementTypeToInteger() const {
LLVMContext &Context = LLVMTy->getContext();
EVT IntTy = getIntegerVT(Context, getVectorElementType().getSizeInBits());
@@ -83,6 +88,10 @@ bool EVT::isExtended1024BitVector() const {
return isExtendedVector() && getExtendedSizeInBits() == 1024;
}
+bool EVT::isExtended2048BitVector() const {
+ return isExtendedVector() && getExtendedSizeInBits() == 2048;
+}
+
EVT EVT::getExtendedVectorElementType() const {
assert(isExtended() && "Type is not extended!");
return EVT::getEVT(cast<VectorType>(LLVMTy)->getElementType());
@@ -134,6 +143,8 @@ std::string EVT::getEVTString() const {
case MVT::v16i1: return "v16i1";
case MVT::v32i1: return "v32i1";
case MVT::v64i1: return "v64i1";
+ case MVT::v512i1: return "v512i1";
+ case MVT::v1024i1: return "v1024i1";
case MVT::v1i8: return "v1i8";
case MVT::v2i8: return "v2i8";
case MVT::v4i8: return "v4i8";
@@ -141,22 +152,29 @@ std::string EVT::getEVTString() const {
case MVT::v16i8: return "v16i8";
case MVT::v32i8: return "v32i8";
case MVT::v64i8: return "v64i8";
+ case MVT::v128i8: return "v128i8";
+ case MVT::v256i8: return "v256i8";
case MVT::v1i16: return "v1i16";
case MVT::v2i16: return "v2i16";
case MVT::v4i16: return "v4i16";
case MVT::v8i16: return "v8i16";
case MVT::v16i16: return "v16i16";
case MVT::v32i16: return "v32i16";
+ case MVT::v64i16: return "v64i16";
+ case MVT::v128i16: return "v128i16";
case MVT::v1i32: return "v1i32";
case MVT::v2i32: return "v2i32";
case MVT::v4i32: return "v4i32";
case MVT::v8i32: return "v8i32";
case MVT::v16i32: return "v16i32";
+ case MVT::v32i32: return "v32i32";
+ case MVT::v64i32: return "v64i32";
case MVT::v1i64: return "v1i64";
case MVT::v2i64: return "v2i64";
case MVT::v4i64: return "v4i64";
case MVT::v8i64: return "v8i64";
case MVT::v16i64: return "v16i64";
+ case MVT::v32i64: return "v32i64";
case MVT::v1i128: return "v1i128";
case MVT::v1f32: return "v1f32";
case MVT::v2f32: return "v2f32";
@@ -203,6 +221,8 @@ Type *EVT::getTypeForEVT(LLVMContext &Context) const {
case MVT::v16i1: return VectorType::get(Type::getInt1Ty(Context), 16);
case MVT::v32i1: return VectorType::get(Type::getInt1Ty(Context), 32);
case MVT::v64i1: return VectorType::get(Type::getInt1Ty(Context), 64);
+ case MVT::v512i1: return VectorType::get(Type::getInt1Ty(Context), 512);
+ case MVT::v1024i1: return VectorType::get(Type::getInt1Ty(Context), 1024);
case MVT::v1i8: return VectorType::get(Type::getInt8Ty(Context), 1);
case MVT::v2i8: return VectorType::get(Type::getInt8Ty(Context), 2);
case MVT::v4i8: return VectorType::get(Type::getInt8Ty(Context), 4);
@@ -210,22 +230,29 @@ Type *EVT::getTypeForEVT(LLVMContext &Context) const {
case MVT::v16i8: return VectorType::get(Type::getInt8Ty(Context), 16);
case MVT::v32i8: return VectorType::get(Type::getInt8Ty(Context), 32);
case MVT::v64i8: return VectorType::get(Type::getInt8Ty(Context), 64);
+ case MVT::v128i8: return VectorType::get(Type::getInt8Ty(Context), 128);
+ case MVT::v256i8: return VectorType::get(Type::getInt8Ty(Context), 256);
case MVT::v1i16: return VectorType::get(Type::getInt16Ty(Context), 1);
case MVT::v2i16: return VectorType::get(Type::getInt16Ty(Context), 2);
case MVT::v4i16: return VectorType::get(Type::getInt16Ty(Context), 4);
case MVT::v8i16: return VectorType::get(Type::getInt16Ty(Context), 8);
case MVT::v16i16: return VectorType::get(Type::getInt16Ty(Context), 16);
case MVT::v32i16: return VectorType::get(Type::getInt16Ty(Context), 32);
+ case MVT::v64i16: return VectorType::get(Type::getInt16Ty(Context), 64);
+ case MVT::v128i16: return VectorType::get(Type::getInt16Ty(Context), 128);
case MVT::v1i32: return VectorType::get(Type::getInt32Ty(Context), 1);
case MVT::v2i32: return VectorType::get(Type::getInt32Ty(Context), 2);
case MVT::v4i32: return VectorType::get(Type::getInt32Ty(Context), 4);
case MVT::v8i32: return VectorType::get(Type::getInt32Ty(Context), 8);
case MVT::v16i32: return VectorType::get(Type::getInt32Ty(Context), 16);
+ case MVT::v32i32: return VectorType::get(Type::getInt32Ty(Context), 32);
+ case MVT::v64i32: return VectorType::get(Type::getInt32Ty(Context), 64);
case MVT::v1i64: return VectorType::get(Type::getInt64Ty(Context), 1);
case MVT::v2i64: return VectorType::get(Type::getInt64Ty(Context), 2);
case MVT::v4i64: return VectorType::get(Type::getInt64Ty(Context), 4);
case MVT::v8i64: return VectorType::get(Type::getInt64Ty(Context), 8);
case MVT::v16i64: return VectorType::get(Type::getInt64Ty(Context), 16);
+ case MVT::v32i64: return VectorType::get(Type::getInt64Ty(Context), 32);
case MVT::v1i128: return VectorType::get(Type::getInt128Ty(Context), 1);
case MVT::v2f16: return VectorType::get(Type::getHalfTy(Context), 2);
case MVT::v4f16: return VectorType::get(Type::getHalfTy(Context), 4);
diff --git a/contrib/llvm/lib/IR/Verifier.cpp b/contrib/llvm/lib/IR/Verifier.cpp
index 2a0a4ff393ed..81c87e4759b7 100644
--- a/contrib/llvm/lib/IR/Verifier.cpp
+++ b/contrib/llvm/lib/IR/Verifier.cpp
@@ -39,8 +39,7 @@
// only by the unwind edge of an invoke instruction.
// * A landingpad instruction must be the first non-PHI instruction in the
// block.
-// * All landingpad instructions must use the same personality function with
-// the same function.
+// * Landingpad instructions must be in a function with a personality function.
// * All other things that are tested by asserts spread about the code...
//
//===----------------------------------------------------------------------===//
@@ -92,6 +91,16 @@ struct VerifierSupport {
: OS(OS), M(nullptr), Broken(false) {}
private:
+ template <class NodeTy> void Write(const ilist_iterator<NodeTy> &I) {
+ Write(&*I);
+ }
+
+ void Write(const Module *M) {
+ if (!M)
+ return;
+ OS << "; ModuleID = '" << M->getModuleIdentifier() << "'\n";
+ }
+
void Write(const Value *V) {
if (!V)
return;
@@ -184,6 +193,9 @@ class Verifier : public InstVisitor<Verifier>, VerifierSupport {
/// \brief Track unresolved string-based type references.
SmallDenseMap<const MDString *, const MDNode *, 32> UnresolvedTypeRefs;
+ /// \brief The result type for a landingpad.
+ Type *LandingPadResultTy;
+
/// \brief Whether we've seen a call to @llvm.localescape in this function
/// already.
bool SawFrameEscape;
@@ -192,9 +204,15 @@ class Verifier : public InstVisitor<Verifier>, VerifierSupport {
/// given function and the largest index passed to llvm.localrecover.
DenseMap<Function *, std::pair<unsigned, unsigned>> FrameEscapeInfo;
+ /// Cache of constants visited in search of ConstantExprs.
+ SmallPtrSet<const Constant *, 32> ConstantExprVisited;
+
+ void checkAtomicMemAccessSize(const Module *M, Type *Ty,
+ const Instruction *I);
public:
explicit Verifier(raw_ostream &OS)
- : VerifierSupport(OS), Context(nullptr), SawFrameEscape(false) {}
+ : VerifierSupport(OS), Context(nullptr), LandingPadResultTy(nullptr),
+ SawFrameEscape(false) {}
bool verify(const Function &F) {
M = F.getParent();
@@ -228,6 +246,7 @@ public:
// FIXME: We strip const here because the inst visitor strips const.
visit(const_cast<Function &>(F));
InstsInThisBlock.clear();
+ LandingPadResultTy = nullptr;
SawFrameEscape = false;
return !Broken;
@@ -297,12 +316,12 @@ private:
void visitFunction(const Function &F);
void visitBasicBlock(BasicBlock &BB);
void visitRangeMetadata(Instruction& I, MDNode* Range, Type* Ty);
+ void visitDereferenceableMetadata(Instruction& I, MDNode* MD);
template <class Ty> bool isValidMetadataArray(const MDTuple &N);
#define HANDLE_SPECIALIZED_MDNODE_LEAF(CLASS) void visit##CLASS(const CLASS &N);
#include "llvm/IR/Metadata.def"
void visitDIScope(const DIScope &N);
- void visitDIDerivedTypeBase(const DIDerivedTypeBase &N);
void visitDIVariable(const DIVariable &N);
void visitDILexicalBlockBase(const DILexicalBlockBase &N);
void visitDITemplateParameter(const DITemplateParameter &N);
@@ -379,7 +398,13 @@ private:
void visitAllocaInst(AllocaInst &AI);
void visitExtractValueInst(ExtractValueInst &EVI);
void visitInsertValueInst(InsertValueInst &IVI);
+ void visitEHPadPredecessors(Instruction &I);
void visitLandingPadInst(LandingPadInst &LPI);
+ void visitCatchPadInst(CatchPadInst &CPI);
+ void visitCatchReturnInst(CatchReturnInst &CatchReturn);
+ void visitCleanupPadInst(CleanupPadInst &CPI);
+ void visitCatchSwitchInst(CatchSwitchInst &CatchSwitch);
+ void visitCleanupReturnInst(CleanupReturnInst &CRI);
void VerifyCallSite(CallSite CS);
void verifyMustTailCall(CallInst &CI);
@@ -399,7 +424,8 @@ private:
void VerifyFunctionMetadata(
const SmallVector<std::pair<unsigned, MDNode *>, 4> MDs);
- void VerifyConstantExprBitcastType(const ConstantExpr *CE);
+ void visitConstantExprsRecursively(const Constant *EntryC);
+ void visitConstantExpr(const ConstantExpr *CE);
void VerifyStatepoint(ImmutableCallSite CS);
void verifyFrameRecoverIndices();
@@ -524,25 +550,7 @@ void Verifier::visitGlobalVariable(const GlobalVariable &GV) {
}
// Walk any aggregate initializers looking for bitcasts between address spaces
- SmallPtrSet<const Value *, 4> Visited;
- SmallVector<const Value *, 4> WorkStack;
- WorkStack.push_back(cast<Value>(GV.getInitializer()));
-
- while (!WorkStack.empty()) {
- const Value *V = WorkStack.pop_back_val();
- if (!Visited.insert(V).second)
- continue;
-
- if (const User *U = dyn_cast<User>(V)) {
- WorkStack.append(U->op_begin(), U->op_end());
- }
-
- if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
- VerifyConstantExprBitcastType(CE);
- if (Broken)
- return;
- }
- }
+ visitConstantExprsRecursively(GV.getInitializer());
visitGlobalValue(GV);
}
@@ -556,7 +564,8 @@ void Verifier::visitAliaseeSubExpr(const GlobalAlias &GA, const Constant &C) {
void Verifier::visitAliaseeSubExpr(SmallPtrSetImpl<const GlobalAlias*> &Visited,
const GlobalAlias &GA, const Constant &C) {
if (const auto *GV = dyn_cast<GlobalValue>(&C)) {
- Assert(!GV->isDeclaration(), "Alias must point to a definition", &GA);
+ Assert(!GV->isDeclarationForLinker(), "Alias must point to a definition",
+ &GA);
if (const auto *GA2 = dyn_cast<GlobalAlias>(GV)) {
Assert(Visited.insert(GA2).second, "Aliases cannot form a cycle", &GA);
@@ -571,7 +580,7 @@ void Verifier::visitAliaseeSubExpr(SmallPtrSetImpl<const GlobalAlias*> &Visited,
}
if (const auto *CE = dyn_cast<ConstantExpr>(&C))
- VerifyConstantExprBitcastType(CE);
+ visitConstantExprsRecursively(CE);
for (const Use &U : C.operands()) {
Value *V = &*U;
@@ -779,39 +788,10 @@ void Verifier::visitDIBasicType(const DIBasicType &N) {
"invalid tag", &N);
}
-void Verifier::visitDIDerivedTypeBase(const DIDerivedTypeBase &N) {
+void Verifier::visitDIDerivedType(const DIDerivedType &N) {
// Common scope checks.
visitDIScope(N);
- Assert(isScopeRef(N, N.getScope()), "invalid scope", &N, N.getScope());
- Assert(isTypeRef(N, N.getBaseType()), "invalid base type", &N,
- N.getBaseType());
-
- // FIXME: Sink this into the subclass verifies.
- if (!N.getFile() || N.getFile()->getFilename().empty()) {
- // Check whether the filename is allowed to be empty.
- uint16_t Tag = N.getTag();
- Assert(
- Tag == dwarf::DW_TAG_const_type || Tag == dwarf::DW_TAG_volatile_type ||
- Tag == dwarf::DW_TAG_pointer_type ||
- Tag == dwarf::DW_TAG_ptr_to_member_type ||
- Tag == dwarf::DW_TAG_reference_type ||
- Tag == dwarf::DW_TAG_rvalue_reference_type ||
- Tag == dwarf::DW_TAG_restrict_type ||
- Tag == dwarf::DW_TAG_array_type ||
- Tag == dwarf::DW_TAG_enumeration_type ||
- Tag == dwarf::DW_TAG_subroutine_type ||
- Tag == dwarf::DW_TAG_inheritance || Tag == dwarf::DW_TAG_friend ||
- Tag == dwarf::DW_TAG_structure_type ||
- Tag == dwarf::DW_TAG_member || Tag == dwarf::DW_TAG_typedef,
- "derived/composite type requires a filename", &N, N.getFile());
- }
-}
-
-void Verifier::visitDIDerivedType(const DIDerivedType &N) {
- // Common derived type checks.
- visitDIDerivedTypeBase(N);
-
Assert(N.getTag() == dwarf::DW_TAG_typedef ||
N.getTag() == dwarf::DW_TAG_pointer_type ||
N.getTag() == dwarf::DW_TAG_ptr_to_member_type ||
@@ -828,6 +808,10 @@ void Verifier::visitDIDerivedType(const DIDerivedType &N) {
Assert(isTypeRef(N, N.getExtraData()), "invalid pointer to member type", &N,
N.getExtraData());
}
+
+ Assert(isScopeRef(N, N.getScope()), "invalid scope", &N, N.getScope());
+ Assert(isTypeRef(N, N.getBaseType()), "invalid base type", &N,
+ N.getBaseType());
}
static bool hasConflictingReferenceFlags(unsigned Flags) {
@@ -845,27 +829,34 @@ void Verifier::visitTemplateParams(const MDNode &N, const Metadata &RawParams) {
}
void Verifier::visitDICompositeType(const DICompositeType &N) {
- // Common derived type checks.
- visitDIDerivedTypeBase(N);
+ // Common scope checks.
+ visitDIScope(N);
Assert(N.getTag() == dwarf::DW_TAG_array_type ||
N.getTag() == dwarf::DW_TAG_structure_type ||
N.getTag() == dwarf::DW_TAG_union_type ||
N.getTag() == dwarf::DW_TAG_enumeration_type ||
- N.getTag() == dwarf::DW_TAG_subroutine_type ||
N.getTag() == dwarf::DW_TAG_class_type,
"invalid tag", &N);
+ Assert(isScopeRef(N, N.getScope()), "invalid scope", &N, N.getScope());
+ Assert(isTypeRef(N, N.getBaseType()), "invalid base type", &N,
+ N.getBaseType());
+
Assert(!N.getRawElements() || isa<MDTuple>(N.getRawElements()),
"invalid composite elements", &N, N.getRawElements());
Assert(isTypeRef(N, N.getRawVTableHolder()), "invalid vtable holder", &N,
N.getRawVTableHolder());
- Assert(!N.getRawElements() || isa<MDTuple>(N.getRawElements()),
- "invalid composite elements", &N, N.getRawElements());
Assert(!hasConflictingReferenceFlags(N.getFlags()), "invalid reference flags",
&N);
if (auto *Params = N.getRawTemplateParams())
visitTemplateParams(N, *Params);
+
+ if (N.getTag() == dwarf::DW_TAG_class_type ||
+ N.getTag() == dwarf::DW_TAG_union_type) {
+ Assert(N.getFile() && !N.getFile()->getFilename().empty(),
+ "class/union requires a filename", &N, N.getFile());
+ }
}
void Verifier::visitDISubroutineType(const DISubroutineType &N) {
@@ -885,6 +876,7 @@ void Verifier::visitDIFile(const DIFile &N) {
}
void Verifier::visitDICompileUnit(const DICompileUnit &N) {
+ Assert(N.isDistinct(), "compile units must be distinct", &N);
Assert(N.getTag() == dwarf::DW_TAG_compile_unit, "invalid tag", &N);
// Don't bother verifying the compilation directory or producer string
@@ -928,6 +920,12 @@ void Verifier::visitDICompileUnit(const DICompileUnit &N) {
Op);
}
}
+ if (auto *Array = N.getRawMacros()) {
+ Assert(isa<MDTuple>(Array), "invalid macro list", &N, Array);
+ for (Metadata *Op : N.getMacros()->operands()) {
+ Assert(Op && isa<DIMacroNode>(Op), "invalid macro ref", &N, Op);
+ }
+ }
}
void Verifier::visitDISubprogram(const DISubprogram &N) {
@@ -937,13 +935,6 @@ void Verifier::visitDISubprogram(const DISubprogram &N) {
Assert(isa<DISubroutineType>(T), "invalid subroutine type", &N, T);
Assert(isTypeRef(N, N.getRawContainingType()), "invalid containing type", &N,
N.getRawContainingType());
- if (auto *RawF = N.getRawFunction()) {
- auto *FMD = dyn_cast<ConstantAsMetadata>(RawF);
- auto *F = FMD ? FMD->getValue() : nullptr;
- auto *FT = F ? dyn_cast<PointerType>(F->getType()) : nullptr;
- Assert(F && FT && isa<FunctionType>(FT->getElementType()),
- "invalid function", &N, F, FT);
- }
if (auto *Params = N.getRawTemplateParams())
visitTemplateParams(N, *Params);
if (auto *S = N.getRawDeclaration()) {
@@ -961,40 +952,8 @@ void Verifier::visitDISubprogram(const DISubprogram &N) {
Assert(!hasConflictingReferenceFlags(N.getFlags()), "invalid reference flags",
&N);
- auto *F = N.getFunction();
- if (!F)
- return;
-
- // Check that all !dbg attachments lead to back to N (or, at least, another
- // subprogram that describes the same function).
- //
- // FIXME: Check this incrementally while visiting !dbg attachments.
- // FIXME: Only check when N is the canonical subprogram for F.
- SmallPtrSet<const MDNode *, 32> Seen;
- for (auto &BB : *F)
- for (auto &I : BB) {
- // Be careful about using DILocation here since we might be dealing with
- // broken code (this is the Verifier after all).
- DILocation *DL =
- dyn_cast_or_null<DILocation>(I.getDebugLoc().getAsMDNode());
- if (!DL)
- continue;
- if (!Seen.insert(DL).second)
- continue;
-
- DILocalScope *Scope = DL->getInlinedAtScope();
- if (Scope && !Seen.insert(Scope).second)
- continue;
-
- DISubprogram *SP = Scope ? Scope->getSubprogram() : nullptr;
- if (SP && !Seen.insert(SP).second)
- continue;
-
- // FIXME: Once N is canonical, check "SP == &N".
- Assert(SP->describes(F),
- "!dbg attachment points at wrong subprogram for function", &N, F,
- &I, DL, Scope, SP);
- }
+ if (N.isDefinition())
+ Assert(N.isDistinct(), "subprogram definitions must be distinct", &N);
}
void Verifier::visitDILexicalBlockBase(const DILexicalBlockBase &N) {
@@ -1020,6 +979,27 @@ void Verifier::visitDINamespace(const DINamespace &N) {
Assert(isa<DIScope>(S), "invalid scope ref", &N, S);
}
+void Verifier::visitDIMacro(const DIMacro &N) {
+ Assert(N.getMacinfoType() == dwarf::DW_MACINFO_define ||
+ N.getMacinfoType() == dwarf::DW_MACINFO_undef,
+ "invalid macinfo type", &N);
+ Assert(!N.getName().empty(), "anonymous macro", &N);
+}
+
+void Verifier::visitDIMacroFile(const DIMacroFile &N) {
+ Assert(N.getMacinfoType() == dwarf::DW_MACINFO_start_file,
+ "invalid macinfo type", &N);
+ if (auto *F = N.getRawFile())
+ Assert(isa<DIFile>(F), "invalid file", &N, F);
+
+ if (auto *Array = N.getRawElements()) {
+ Assert(isa<MDTuple>(Array), "invalid macro list", &N, Array);
+ for (Metadata *Op : N.getElements()->operands()) {
+ Assert(Op && isa<DIMacroNode>(Op), "invalid macro ref", &N, Op);
+ }
+ }
+}
+
void Verifier::visitDIModule(const DIModule &N) {
Assert(N.getTag() == dwarf::DW_TAG_module, "invalid tag", &N);
Assert(!N.getName().empty(), "anonymous module", &N);
@@ -1075,9 +1055,7 @@ void Verifier::visitDILocalVariable(const DILocalVariable &N) {
// Checks common to all variables.
visitDIVariable(N);
- Assert(N.getTag() == dwarf::DW_TAG_auto_variable ||
- N.getTag() == dwarf::DW_TAG_arg_variable,
- "invalid tag", &N);
+ Assert(N.getTag() == dwarf::DW_TAG_variable, "invalid tag", &N);
Assert(N.getRawScope() && isa<DILocalScope>(N.getRawScope()),
"local variable requires a valid scope", &N, N.getRawScope());
}
@@ -1274,7 +1252,10 @@ void Verifier::VerifyAttributeTypes(AttributeSet Attrs, unsigned Idx,
I->getKindAsEnum() == Attribute::OptimizeNone ||
I->getKindAsEnum() == Attribute::JumpTable ||
I->getKindAsEnum() == Attribute::Convergent ||
- I->getKindAsEnum() == Attribute::ArgMemOnly) {
+ I->getKindAsEnum() == Attribute::ArgMemOnly ||
+ I->getKindAsEnum() == Attribute::NoRecurse ||
+ I->getKindAsEnum() == Attribute::InaccessibleMemOnly ||
+ I->getKindAsEnum() == Attribute::InaccessibleMemOrArgMemOnly) {
if (!isFunction) {
CheckFailed("Attribute '" + I->getAsString() +
"' only applies to functions!", V);
@@ -1365,7 +1346,7 @@ void Verifier::VerifyParameterAttrs(AttributeSet Attrs, unsigned Idx, Type *Ty,
V);
if (PointerType *PTy = dyn_cast<PointerType>(Ty)) {
- SmallPtrSet<const Type*, 4> Visited;
+ SmallPtrSet<Type*, 4> Visited;
if (!PTy->getElementType()->isSized(&Visited)) {
Assert(!Attrs.hasAttribute(Idx, Attribute::ByVal) &&
!Attrs.hasAttribute(Idx, Attribute::InAlloca),
@@ -1445,6 +1426,18 @@ void Verifier::VerifyFunctionAttrs(FunctionType *FT, AttributeSet Attrs,
"Attributes 'readnone and readonly' are incompatible!", V);
Assert(
+ !(Attrs.hasAttribute(AttributeSet::FunctionIndex, Attribute::ReadNone) &&
+ Attrs.hasAttribute(AttributeSet::FunctionIndex,
+ Attribute::InaccessibleMemOrArgMemOnly)),
+ "Attributes 'readnone and inaccessiblemem_or_argmemonly' are incompatible!", V);
+
+ Assert(
+ !(Attrs.hasAttribute(AttributeSet::FunctionIndex, Attribute::ReadNone) &&
+ Attrs.hasAttribute(AttributeSet::FunctionIndex,
+ Attribute::InaccessibleMemOnly)),
+ "Attributes 'readnone and inaccessiblememonly' are incompatible!", V);
+
+ Assert(
!(Attrs.hasAttribute(AttributeSet::FunctionIndex, Attribute::NoInline) &&
Attrs.hasAttribute(AttributeSet::FunctionIndex,
Attribute::AlwaysInline)),
@@ -1501,7 +1494,35 @@ void Verifier::VerifyFunctionMetadata(
}
}
-void Verifier::VerifyConstantExprBitcastType(const ConstantExpr *CE) {
+void Verifier::visitConstantExprsRecursively(const Constant *EntryC) {
+ if (!ConstantExprVisited.insert(EntryC).second)
+ return;
+
+ SmallVector<const Constant *, 16> Stack;
+ Stack.push_back(EntryC);
+
+ while (!Stack.empty()) {
+ const Constant *C = Stack.pop_back_val();
+
+ // Check this constant expression.
+ if (const auto *CE = dyn_cast<ConstantExpr>(C))
+ visitConstantExpr(CE);
+
+ // Visit all sub-expressions.
+ for (const Use &U : C->operands()) {
+ const auto *OpC = dyn_cast<Constant>(U);
+ if (!OpC)
+ continue;
+ if (isa<GlobalValue>(OpC))
+ continue; // Global values get visited separately.
+ if (!ConstantExprVisited.insert(OpC).second)
+ continue;
+ Stack.push_back(OpC);
+ }
+ }
+}
+
+void Verifier::visitConstantExpr(const ConstantExpr *CE) {
if (CE->getOpcode() != Instruction::BitCast)
return;
@@ -1554,17 +1575,11 @@ void Verifier::VerifyStatepoint(ImmutableCallSite CS) {
&CI);
const Value *Target = CS.getArgument(2);
- const PointerType *PT = dyn_cast<PointerType>(Target->getType());
+ auto *PT = dyn_cast<PointerType>(Target->getType());
Assert(PT && PT->getElementType()->isFunctionTy(),
"gc.statepoint callee must be of function pointer type", &CI, Target);
FunctionType *TargetFuncType = cast<FunctionType>(PT->getElementType());
- if (NumPatchBytes)
- Assert(isa<ConstantPointerNull>(Target->stripPointerCasts()),
- "gc.statepoint must have null as call target if number of patchable "
- "bytes is non zero",
- &CI);
-
const Value *NumCallArgsV = CS.getArgument(3);
Assert(isa<ConstantInt>(NumCallArgsV),
"gc.statepoint number of arguments to underlying call "
@@ -1743,17 +1758,33 @@ void Verifier::visitFunction(const Function &F) {
FT->getParamType(i));
Assert(I->getType()->isFirstClassType(),
"Function arguments must have first-class types!", I);
- if (!isLLVMdotName)
+ if (!isLLVMdotName) {
Assert(!I->getType()->isMetadataTy(),
"Function takes metadata but isn't an intrinsic", I, &F);
+ Assert(!I->getType()->isTokenTy(),
+ "Function takes token but isn't an intrinsic", I, &F);
+ }
}
+ if (!isLLVMdotName)
+ Assert(!F.getReturnType()->isTokenTy(),
+ "Functions returns a token but isn't an intrinsic", &F);
+
// Get the function metadata attachments.
SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
F.getAllMetadata(MDs);
assert(F.hasMetadata() != MDs.empty() && "Bit out-of-sync");
VerifyFunctionMetadata(MDs);
+ // Check validity of the personality function
+ if (F.hasPersonalityFn()) {
+ auto *Per = dyn_cast<Function>(F.getPersonalityFn()->stripPointerCasts());
+ if (Per)
+ Assert(Per->getParent() == F.getParent(),
+ "Referencing personality function in another module!",
+ &F, F.getParent(), Per, Per->getParent());
+ }
+
if (F.isMaterializable()) {
// Function has a body somewhere we can't see.
Assert(MDs.empty(), "unmaterialized function cannot have metadata", &F,
@@ -1782,13 +1813,27 @@ void Verifier::visitFunction(const Function &F) {
}
// Visit metadata attachments.
- for (const auto &I : MDs)
+ for (const auto &I : MDs) {
+ // Verify that the attachment is legal.
+ switch (I.first) {
+ default:
+ break;
+ case LLVMContext::MD_dbg:
+ Assert(isa<DISubprogram>(I.second),
+ "function !dbg attachment must be a subprogram", &F, I.second);
+ break;
+ }
+
+ // Verify the metadata itself.
visitMDNode(*I.second);
+ }
}
// If this function is actually an intrinsic, verify that it is only used in
// direct call/invokes, never having its "address taken".
- if (F.getIntrinsicID()) {
+ // Only do this if the module is materialized, otherwise we don't have all the
+ // uses.
+ if (F.getIntrinsicID() && F.getParent()->isMaterialized()) {
const User *U;
if (F.hasAddressTaken(&U))
Assert(0, "Invalid user of intrinsic instruction!", U);
@@ -1798,6 +1843,44 @@ void Verifier::visitFunction(const Function &F) {
(F.isDeclaration() && F.hasExternalLinkage()) ||
F.hasAvailableExternallyLinkage(),
"Function is marked as dllimport, but not external.", &F);
+
+ auto *N = F.getSubprogram();
+ if (!N)
+ return;
+
+ // Check that all !dbg attachments lead to back to N (or, at least, another
+ // subprogram that describes the same function).
+ //
+ // FIXME: Check this incrementally while visiting !dbg attachments.
+ // FIXME: Only check when N is the canonical subprogram for F.
+ SmallPtrSet<const MDNode *, 32> Seen;
+ for (auto &BB : F)
+ for (auto &I : BB) {
+ // Be careful about using DILocation here since we might be dealing with
+ // broken code (this is the Verifier after all).
+ DILocation *DL =
+ dyn_cast_or_null<DILocation>(I.getDebugLoc().getAsMDNode());
+ if (!DL)
+ continue;
+ if (!Seen.insert(DL).second)
+ continue;
+
+ DILocalScope *Scope = DL->getInlinedAtScope();
+ if (Scope && !Seen.insert(Scope).second)
+ continue;
+
+ DISubprogram *SP = Scope ? Scope->getSubprogram() : nullptr;
+
+ // Scope and SP could be the same MDNode and we don't want to skip
+ // validation in that case
+ if (SP && ((Scope != SP) && !Seen.insert(SP).second))
+ continue;
+
+ // FIXME: Once N is canonical, check "SP == &N".
+ Assert(SP->describes(&F),
+ "!dbg attachment points at wrong subprogram for function", N, &F,
+ &I, DL, Scope, SP);
+ }
}
// verifyBasicBlock - Verify that a basic block is well formed...
@@ -2194,6 +2277,9 @@ void Verifier::visitPHINode(PHINode &PN) {
isa<PHINode>(--BasicBlock::iterator(&PN)),
"PHI nodes not grouped at top of basic block!", &PN, PN.getParent());
+ // Check that a PHI doesn't yield a Token.
+ Assert(!PN.getType()->isTokenTy(), "PHI nodes cannot have token type!");
+
// Check that all of the values of the PHI node have the same type as the
// result, and that the incoming blocks are really basic blocks.
for (Value *IncValue : PN.incoming_values()) {
@@ -2296,16 +2382,44 @@ void Verifier::VerifyCallSite(CallSite CS) {
// Verify that there's no metadata unless it's a direct call to an intrinsic.
if (CS.getCalledFunction() == nullptr ||
!CS.getCalledFunction()->getName().startswith("llvm.")) {
- for (FunctionType::param_iterator PI = FTy->param_begin(),
- PE = FTy->param_end(); PI != PE; ++PI)
- Assert(!(*PI)->isMetadataTy(),
+ for (Type *ParamTy : FTy->params()) {
+ Assert(!ParamTy->isMetadataTy(),
"Function has metadata parameter but isn't an intrinsic", I);
+ Assert(!ParamTy->isTokenTy(),
+ "Function has token parameter but isn't an intrinsic", I);
+ }
}
+ // Verify that indirect calls don't return tokens.
+ if (CS.getCalledFunction() == nullptr)
+ Assert(!FTy->getReturnType()->isTokenTy(),
+ "Return type cannot be token for indirect call!");
+
if (Function *F = CS.getCalledFunction())
if (Intrinsic::ID ID = (Intrinsic::ID)F->getIntrinsicID())
visitIntrinsicCallSite(ID, CS);
+ // Verify that a callsite has at most one "deopt" and one "funclet" operand
+ // bundle.
+ bool FoundDeoptBundle = false, FoundFuncletBundle = false;
+ for (unsigned i = 0, e = CS.getNumOperandBundles(); i < e; ++i) {
+ OperandBundleUse BU = CS.getOperandBundleAt(i);
+ uint32_t Tag = BU.getTagID();
+ if (Tag == LLVMContext::OB_deopt) {
+ Assert(!FoundDeoptBundle, "Multiple deopt operand bundles", I);
+ FoundDeoptBundle = true;
+ }
+ if (Tag == LLVMContext::OB_funclet) {
+ Assert(!FoundFuncletBundle, "Multiple funclet operand bundles", I);
+ FoundFuncletBundle = true;
+ Assert(BU.Inputs.size() == 1,
+ "Expected exactly one funclet bundle operand", I);
+ Assert(isa<FuncletPadInst>(BU.Inputs.front()),
+ "Funclet bundle operands should correspond to a FuncletPadInst",
+ I);
+ }
+ }
+
visitInstruction(*I);
}
@@ -2406,10 +2520,12 @@ void Verifier::visitCallInst(CallInst &CI) {
void Verifier::visitInvokeInst(InvokeInst &II) {
VerifyCallSite(&II);
- // Verify that there is a landingpad instruction as the first non-PHI
- // instruction of the 'unwind' destination.
- Assert(II.getUnwindDest()->isLandingPad(),
- "The unwind destination does not have a landingpad instruction!", &II);
+ // Verify that the first non-PHI instruction of the unwind destination is an
+ // exception handling instruction.
+ Assert(
+ II.getUnwindDest()->isEHPad(),
+ "The unwind destination does not have an exception handling instruction!",
+ &II);
visitTerminatorInst(II);
}
@@ -2622,6 +2738,14 @@ void Verifier::visitRangeMetadata(Instruction& I,
}
}
+void Verifier::checkAtomicMemAccessSize(const Module *M, Type *Ty,
+ const Instruction *I) {
+ unsigned Size = M->getDataLayout().getTypeSizeInBits(Ty);
+ Assert(Size >= 8, "atomic memory access' size must be byte-sized", Ty, I);
+ Assert(!(Size & (Size - 1)),
+ "atomic memory access' operand must have a power-of-two size", Ty, I);
+}
+
void Verifier::visitLoadInst(LoadInst &LI) {
PointerType *PTy = dyn_cast<PointerType>(LI.getOperand(0)->getType());
Assert(PTy, "Load operand must be a pointer.", &LI);
@@ -2633,14 +2757,12 @@ void Verifier::visitLoadInst(LoadInst &LI) {
"Load cannot have Release ordering", &LI);
Assert(LI.getAlignment() != 0,
"Atomic load must specify explicit alignment", &LI);
- if (!ElTy->isPointerTy()) {
- Assert(ElTy->isIntegerTy(), "atomic load operand must have integer type!",
- &LI, ElTy);
- unsigned Size = ElTy->getPrimitiveSizeInBits();
- Assert(Size >= 8 && !(Size & (Size - 1)),
- "atomic load operand must be power-of-two byte-sized integer", &LI,
- ElTy);
- }
+ Assert(ElTy->isIntegerTy() || ElTy->isPointerTy() ||
+ ElTy->isFloatingPointTy(),
+ "atomic load operand must have integer, pointer, or floating point "
+ "type!",
+ ElTy, &LI);
+ checkAtomicMemAccessSize(M, ElTy, &LI);
} else {
Assert(LI.getSynchScope() == CrossThread,
"Non-atomic load cannot have SynchronizationScope specified", &LI);
@@ -2662,14 +2784,12 @@ void Verifier::visitStoreInst(StoreInst &SI) {
"Store cannot have Acquire ordering", &SI);
Assert(SI.getAlignment() != 0,
"Atomic store must specify explicit alignment", &SI);
- if (!ElTy->isPointerTy()) {
- Assert(ElTy->isIntegerTy(),
- "atomic store operand must have integer type!", &SI, ElTy);
- unsigned Size = ElTy->getPrimitiveSizeInBits();
- Assert(Size >= 8 && !(Size & (Size - 1)),
- "atomic store operand must be power-of-two byte-sized integer",
- &SI, ElTy);
- }
+ Assert(ElTy->isIntegerTy() || ElTy->isPointerTy() ||
+ ElTy->isFloatingPointTy(),
+ "atomic store operand must have integer, pointer, or floating point "
+ "type!",
+ ElTy, &SI);
+ checkAtomicMemAccessSize(M, ElTy, &SI);
} else {
Assert(SI.getSynchScope() == CrossThread,
"Non-atomic store cannot have SynchronizationScope specified", &SI);
@@ -2678,7 +2798,7 @@ void Verifier::visitStoreInst(StoreInst &SI) {
}
void Verifier::visitAllocaInst(AllocaInst &AI) {
- SmallPtrSet<const Type*, 4> Visited;
+ SmallPtrSet<Type*, 4> Visited;
PointerType *PTy = AI.getType();
Assert(PTy->getAddressSpace() == 0,
"Allocation instruction pointer not in the generic address space!",
@@ -2716,9 +2836,7 @@ void Verifier::visitAtomicCmpXchgInst(AtomicCmpXchgInst &CXI) {
Type *ElTy = PTy->getElementType();
Assert(ElTy->isIntegerTy(), "cmpxchg operand must have integer type!", &CXI,
ElTy);
- unsigned Size = ElTy->getPrimitiveSizeInBits();
- Assert(Size >= 8 && !(Size & (Size - 1)),
- "cmpxchg operand must be power-of-two byte-sized integer", &CXI, ElTy);
+ checkAtomicMemAccessSize(M, ElTy, &CXI);
Assert(ElTy == CXI.getOperand(1)->getType(),
"Expected value type does not match pointer operand type!", &CXI,
ElTy);
@@ -2737,10 +2855,7 @@ void Verifier::visitAtomicRMWInst(AtomicRMWInst &RMWI) {
Type *ElTy = PTy->getElementType();
Assert(ElTy->isIntegerTy(), "atomicrmw operand must have integer type!",
&RMWI, ElTy);
- unsigned Size = ElTy->getPrimitiveSizeInBits();
- Assert(Size >= 8 && !(Size & (Size - 1)),
- "atomicrmw operand must be power-of-two byte-sized integer", &RMWI,
- ElTy);
+ checkAtomicMemAccessSize(M, ElTy, &RMWI);
Assert(ElTy == RMWI.getOperand(1)->getType(),
"Argument value type does not match pointer operand type!", &RMWI,
ElTy);
@@ -2777,23 +2892,62 @@ void Verifier::visitInsertValueInst(InsertValueInst &IVI) {
visitInstruction(IVI);
}
-void Verifier::visitLandingPadInst(LandingPadInst &LPI) {
- BasicBlock *BB = LPI.getParent();
+void Verifier::visitEHPadPredecessors(Instruction &I) {
+ assert(I.isEHPad());
+
+ BasicBlock *BB = I.getParent();
+ Function *F = BB->getParent();
+
+ Assert(BB != &F->getEntryBlock(), "EH pad cannot be in entry block.", &I);
+
+ if (auto *LPI = dyn_cast<LandingPadInst>(&I)) {
+ // The landingpad instruction defines its parent as a landing pad block. The
+ // landing pad block may be branched to only by the unwind edge of an
+ // invoke.
+ for (BasicBlock *PredBB : predecessors(BB)) {
+ const auto *II = dyn_cast<InvokeInst>(PredBB->getTerminator());
+ Assert(II && II->getUnwindDest() == BB && II->getNormalDest() != BB,
+ "Block containing LandingPadInst must be jumped to "
+ "only by the unwind edge of an invoke.",
+ LPI);
+ }
+ return;
+ }
+ if (auto *CPI = dyn_cast<CatchPadInst>(&I)) {
+ if (!pred_empty(BB))
+ Assert(BB->getUniquePredecessor() == CPI->getCatchSwitch()->getParent(),
+ "Block containg CatchPadInst must be jumped to "
+ "only by its catchswitch.",
+ CPI);
+ return;
+ }
+
+ for (BasicBlock *PredBB : predecessors(BB)) {
+ TerminatorInst *TI = PredBB->getTerminator();
+ if (auto *II = dyn_cast<InvokeInst>(TI)) {
+ Assert(II->getUnwindDest() == BB && II->getNormalDest() != BB,
+ "EH pad must be jumped to via an unwind edge", &I, II);
+ } else if (!isa<CleanupReturnInst>(TI) && !isa<CatchSwitchInst>(TI)) {
+ Assert(false, "EH pad must be jumped to via an unwind edge", &I, TI);
+ }
+ }
+}
+void Verifier::visitLandingPadInst(LandingPadInst &LPI) {
// The landingpad instruction is ill-formed if it doesn't have any clauses and
// isn't a cleanup.
Assert(LPI.getNumClauses() > 0 || LPI.isCleanup(),
"LandingPadInst needs at least one clause or to be a cleanup.", &LPI);
- // The landingpad instruction defines its parent as a landing pad block. The
- // landing pad block may be branched to only by the unwind edge of an invoke.
- for (pred_iterator I = pred_begin(BB), E = pred_end(BB); I != E; ++I) {
- const InvokeInst *II = dyn_cast<InvokeInst>((*I)->getTerminator());
- Assert(II && II->getUnwindDest() == BB && II->getNormalDest() != BB,
- "Block containing LandingPadInst must be jumped to "
- "only by the unwind edge of an invoke.",
+ visitEHPadPredecessors(LPI);
+
+ if (!LandingPadResultTy)
+ LandingPadResultTy = LPI.getType();
+ else
+ Assert(LandingPadResultTy == LPI.getType(),
+ "The landingpad instruction should have a consistent result type "
+ "inside a function.",
&LPI);
- }
Function *F = LPI.getParent()->getParent();
Assert(F->hasPersonalityFn(),
@@ -2820,6 +2974,132 @@ void Verifier::visitLandingPadInst(LandingPadInst &LPI) {
visitInstruction(LPI);
}
+void Verifier::visitCatchPadInst(CatchPadInst &CPI) {
+ visitEHPadPredecessors(CPI);
+
+ BasicBlock *BB = CPI.getParent();
+
+ Function *F = BB->getParent();
+ Assert(F->hasPersonalityFn(),
+ "CatchPadInst needs to be in a function with a personality.", &CPI);
+
+ Assert(isa<CatchSwitchInst>(CPI.getParentPad()),
+ "CatchPadInst needs to be directly nested in a CatchSwitchInst.",
+ CPI.getParentPad());
+
+ // The catchpad instruction must be the first non-PHI instruction in the
+ // block.
+ Assert(BB->getFirstNonPHI() == &CPI,
+ "CatchPadInst not the first non-PHI instruction in the block.", &CPI);
+
+ visitInstruction(CPI);
+}
+
+void Verifier::visitCatchReturnInst(CatchReturnInst &CatchReturn) {
+ Assert(isa<CatchPadInst>(CatchReturn.getOperand(0)),
+ "CatchReturnInst needs to be provided a CatchPad", &CatchReturn,
+ CatchReturn.getOperand(0));
+
+ visitTerminatorInst(CatchReturn);
+}
+
+void Verifier::visitCleanupPadInst(CleanupPadInst &CPI) {
+ visitEHPadPredecessors(CPI);
+
+ BasicBlock *BB = CPI.getParent();
+
+ Function *F = BB->getParent();
+ Assert(F->hasPersonalityFn(),
+ "CleanupPadInst needs to be in a function with a personality.", &CPI);
+
+ // The cleanuppad instruction must be the first non-PHI instruction in the
+ // block.
+ Assert(BB->getFirstNonPHI() == &CPI,
+ "CleanupPadInst not the first non-PHI instruction in the block.",
+ &CPI);
+
+ auto *ParentPad = CPI.getParentPad();
+ Assert(isa<CatchSwitchInst>(ParentPad) || isa<ConstantTokenNone>(ParentPad) ||
+ isa<CleanupPadInst>(ParentPad) || isa<CatchPadInst>(ParentPad),
+ "CleanupPadInst has an invalid parent.", &CPI);
+
+ User *FirstUser = nullptr;
+ BasicBlock *FirstUnwindDest = nullptr;
+ for (User *U : CPI.users()) {
+ BasicBlock *UnwindDest;
+ if (CleanupReturnInst *CRI = dyn_cast<CleanupReturnInst>(U)) {
+ UnwindDest = CRI->getUnwindDest();
+ } else if (isa<CleanupPadInst>(U) || isa<CatchSwitchInst>(U)) {
+ continue;
+ } else if (CallSite(U)) {
+ continue;
+ } else {
+ Assert(false, "bogus cleanuppad use", &CPI);
+ }
+
+ if (!FirstUser) {
+ FirstUser = U;
+ FirstUnwindDest = UnwindDest;
+ } else {
+ Assert(
+ UnwindDest == FirstUnwindDest,
+ "cleanupret instructions from the same cleanuppad must have the same "
+ "unwind destination",
+ FirstUser, U);
+ }
+ }
+
+ visitInstruction(CPI);
+}
+
+void Verifier::visitCatchSwitchInst(CatchSwitchInst &CatchSwitch) {
+ visitEHPadPredecessors(CatchSwitch);
+
+ BasicBlock *BB = CatchSwitch.getParent();
+
+ Function *F = BB->getParent();
+ Assert(F->hasPersonalityFn(),
+ "CatchSwitchInst needs to be in a function with a personality.",
+ &CatchSwitch);
+
+ // The catchswitch instruction must be the first non-PHI instruction in the
+ // block.
+ Assert(BB->getFirstNonPHI() == &CatchSwitch,
+ "CatchSwitchInst not the first non-PHI instruction in the block.",
+ &CatchSwitch);
+
+ if (BasicBlock *UnwindDest = CatchSwitch.getUnwindDest()) {
+ Instruction *I = UnwindDest->getFirstNonPHI();
+ Assert(I->isEHPad() && !isa<LandingPadInst>(I),
+ "CatchSwitchInst must unwind to an EH block which is not a "
+ "landingpad.",
+ &CatchSwitch);
+ }
+
+ auto *ParentPad = CatchSwitch.getParentPad();
+ Assert(isa<CatchSwitchInst>(ParentPad) || isa<ConstantTokenNone>(ParentPad) ||
+ isa<CleanupPadInst>(ParentPad) || isa<CatchPadInst>(ParentPad),
+ "CatchSwitchInst has an invalid parent.", ParentPad);
+
+ visitTerminatorInst(CatchSwitch);
+}
+
+void Verifier::visitCleanupReturnInst(CleanupReturnInst &CRI) {
+ Assert(isa<CleanupPadInst>(CRI.getOperand(0)),
+ "CleanupReturnInst needs to be provided a CleanupPad", &CRI,
+ CRI.getOperand(0));
+
+ if (BasicBlock *UnwindDest = CRI.getUnwindDest()) {
+ Instruction *I = UnwindDest->getFirstNonPHI();
+ Assert(I->isEHPad() && !isa<LandingPadInst>(I),
+ "CleanupReturnInst must unwind to an EH block which is not a "
+ "landingpad.",
+ &CRI);
+ }
+
+ visitTerminatorInst(CRI);
+}
+
void Verifier::verifyDominatesUse(Instruction &I, unsigned i) {
Instruction *Op = cast<Instruction>(I.getOperand(i));
// If the we have an invalid invoke, don't try to compute the dominance.
@@ -2835,6 +3115,19 @@ void Verifier::verifyDominatesUse(Instruction &I, unsigned i) {
"Instruction does not dominate all uses!", Op, &I);
}
+void Verifier::visitDereferenceableMetadata(Instruction& I, MDNode* MD) {
+ Assert(I.getType()->isPointerTy(), "dereferenceable, dereferenceable_or_null "
+ "apply only to pointer types", &I);
+ Assert(isa<LoadInst>(I),
+ "dereferenceable, dereferenceable_or_null apply only to load"
+ " instructions, use attributes for calls or invokes", &I);
+ Assert(MD->getNumOperands() == 1, "dereferenceable, dereferenceable_or_null "
+ "take one operand!", &I);
+ ConstantInt *CI = mdconst::dyn_extract<ConstantInt>(MD->getOperand(0));
+ Assert(CI && CI->getType()->isIntegerTy(64), "dereferenceable, "
+ "dereferenceable_or_null metadata value must be an i64!", &I);
+}
+
/// verifyInstruction - Verify that an instruction is well formed.
///
void Verifier::visitInstruction(Instruction &I) {
@@ -2903,7 +3196,7 @@ void Verifier::visitInstruction(Instruction &I) {
" donothing or patchpoint",
&I);
Assert(F->getParent() == M, "Referencing function in another module!",
- &I);
+ &I, M, F, F->getParent());
} else if (BasicBlock *OpBB = dyn_cast<BasicBlock>(I.getOperand(i))) {
Assert(OpBB->getParent() == BB->getParent(),
"Referring to a basic block in another function!", &I);
@@ -2911,7 +3204,7 @@ void Verifier::visitInstruction(Instruction &I) {
Assert(OpArg->getParent() == BB->getParent(),
"Referring to an argument in another function!", &I);
} else if (GlobalValue *GV = dyn_cast<GlobalValue>(I.getOperand(i))) {
- Assert(GV->getParent() == M, "Referencing global in another module!", &I);
+ Assert(GV->getParent() == M, "Referencing global in another module!", &I, M, GV, GV->getParent());
} else if (isa<Instruction>(I.getOperand(i))) {
verifyDominatesUse(I, i);
} else if (isa<InlineAsm>(I.getOperand(i))) {
@@ -2922,22 +3215,7 @@ void Verifier::visitInstruction(Instruction &I) {
if (CE->getType()->isPtrOrPtrVectorTy()) {
// If we have a ConstantExpr pointer, we need to see if it came from an
// illegal bitcast (inttoptr <constant int> )
- SmallVector<const ConstantExpr *, 4> Stack;
- SmallPtrSet<const ConstantExpr *, 4> Visited;
- Stack.push_back(CE);
-
- while (!Stack.empty()) {
- const ConstantExpr *V = Stack.pop_back_val();
- if (!Visited.insert(V).second)
- continue;
-
- VerifyConstantExprBitcastType(V);
-
- for (unsigned I = 0, N = V->getNumOperands(); I != N; ++I) {
- if (ConstantExpr *Op = dyn_cast<ConstantExpr>(V->getOperand(I)))
- Stack.push_back(Op);
- }
- }
+ visitConstantExprsRecursively(CE);
}
}
}
@@ -2971,6 +3249,28 @@ void Verifier::visitInstruction(Instruction &I) {
&I);
}
+ if (MDNode *MD = I.getMetadata(LLVMContext::MD_dereferenceable))
+ visitDereferenceableMetadata(I, MD);
+
+ if (MDNode *MD = I.getMetadata(LLVMContext::MD_dereferenceable_or_null))
+ visitDereferenceableMetadata(I, MD);
+
+ if (MDNode *AlignMD = I.getMetadata(LLVMContext::MD_align)) {
+ Assert(I.getType()->isPointerTy(), "align applies only to pointer types",
+ &I);
+ Assert(isa<LoadInst>(I), "align applies only to load instructions, "
+ "use attributes for calls or invokes", &I);
+ Assert(AlignMD->getNumOperands() == 1, "align takes one operand!", &I);
+ ConstantInt *CI = mdconst::dyn_extract<ConstantInt>(AlignMD->getOperand(0));
+ Assert(CI && CI->getType()->isIntegerTy(64),
+ "align metadata value must be an i64!", &I);
+ uint64_t Align = CI->getZExtValue();
+ Assert(isPowerOf2_64(Align),
+ "align metadata value must be a power of 2!", &I);
+ Assert(Align <= Value::MaximumAlignment,
+ "alignment is larger that implementation defined limit", &I);
+ }
+
if (MDNode *N = I.getDebugLoc().getAsMDNode()) {
Assert(isa<DILocation>(N), "invalid !dbg metadata attachment", &I, N);
visitMDNode(*N);
@@ -2998,6 +3298,7 @@ bool Verifier::VerifyIntrinsicType(Type *Ty,
case IITDescriptor::Void: return !Ty->isVoidTy();
case IITDescriptor::VarArg: return true;
case IITDescriptor::MMX: return !Ty->isX86_MMXTy();
+ case IITDescriptor::Token: return !Ty->isTokenTy();
case IITDescriptor::Metadata: return !Ty->isMetadataTy();
case IITDescriptor::Half: return !Ty->isHalfTy();
case IITDescriptor::Float: return !Ty->isFloatTy();
@@ -3321,9 +3622,6 @@ void Verifier::visitIntrinsicCallSite(Intrinsic::ID ID, CallSite CS) {
VerifyStatepoint(CS);
break;
- case Intrinsic::experimental_gc_result_int:
- case Intrinsic::experimental_gc_result_float:
- case Intrinsic::experimental_gc_result_ptr:
case Intrinsic::experimental_gc_result: {
Assert(CS.getParent()->getParent()->hasGC(),
"Enclosing function does not use GC.", CS);
@@ -3339,9 +3637,8 @@ void Verifier::visitIntrinsicCallSite(Intrinsic::ID ID, CallSite CS) {
// Assert that result type matches wrapped callee.
const Value *Target = StatepointCS.getArgument(2);
- const PointerType *PT = cast<PointerType>(Target->getType());
- const FunctionType *TargetFuncType =
- cast<FunctionType>(PT->getElementType());
+ auto *PT = cast<PointerType>(Target->getType());
+ auto *TargetFuncType = cast<FunctionType>(PT->getElementType());
Assert(CS.getType() == TargetFuncType->getReturnType(),
"gc.result result type does not match wrapped callee", CS);
break;
@@ -3352,19 +3649,16 @@ void Verifier::visitIntrinsicCallSite(Intrinsic::ID ID, CallSite CS) {
// Check that this relocate is correctly tied to the statepoint
// This is case for relocate on the unwinding path of an invoke statepoint
- if (ExtractValueInst *ExtractValue =
- dyn_cast<ExtractValueInst>(CS.getArgOperand(0))) {
- Assert(isa<LandingPadInst>(ExtractValue->getAggregateOperand()),
- "gc relocate on unwind path incorrectly linked to the statepoint",
- CS);
+ if (LandingPadInst *LandingPad =
+ dyn_cast<LandingPadInst>(CS.getArgOperand(0))) {
const BasicBlock *InvokeBB =
- ExtractValue->getParent()->getUniquePredecessor();
+ LandingPad->getParent()->getUniquePredecessor();
// Landingpad relocates should have only one predecessor with invoke
// statepoint terminator
Assert(InvokeBB, "safepoints should have unique landingpads",
- ExtractValue->getParent());
+ LandingPad->getParent());
Assert(InvokeBB->getTerminator(), "safepoint block should be well formed",
InvokeBB);
Assert(isStatepoint(InvokeBB->getTerminator()),
@@ -3448,6 +3742,12 @@ void Verifier::visitIntrinsicCallSite(Intrinsic::ID ID, CallSite CS) {
"gc.relocate: relocating a pointer shouldn't change its address space", CS);
break;
}
+ case Intrinsic::eh_exceptioncode:
+ case Intrinsic::eh_exceptionpointer: {
+ Assert(isa<CatchPadInst>(CS.getArgOperand(0)),
+ "eh.exceptionpointer argument must be a catchpad", CS);
+ break;
+ }
};
}
@@ -3598,7 +3898,7 @@ void Verifier::verifyTypeRefs() {
for (auto *CU : CUs->operands())
if (auto Ts = cast<DICompileUnit>(CU)->getRetainedTypes())
for (DIType *Op : Ts)
- if (auto *T = dyn_cast<DICompositeType>(Op))
+ if (auto *T = dyn_cast_or_null<DICompositeType>(Op))
if (auto *S = T->getRawIdentifier()) {
UnresolvedTypeRefs.erase(S);
TypeRefs.insert(std::make_pair(S, T));