aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/AsmWriter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/IR/AsmWriter.cpp')
-rw-r--r--llvm/lib/IR/AsmWriter.cpp244
1 files changed, 195 insertions, 49 deletions
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index acf0e4afef27..fd08310316b3 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -228,9 +228,9 @@ static void predictValueUseListOrderImpl(const Value *V, const Function *F,
return LU->getOperandNo() > RU->getOperandNo();
});
- if (std::is_sorted(
- List.begin(), List.end(),
- [](const Entry &L, const Entry &R) { return L.second < R.second; }))
+ if (llvm::is_sorted(List, [](const Entry &L, const Entry &R) {
+ return L.second < R.second;
+ }))
// Order is already correct.
return;
@@ -462,6 +462,33 @@ static void PrintLLVMName(raw_ostream &OS, const Value *V) {
isa<GlobalValue>(V) ? GlobalPrefix : LocalPrefix);
}
+static void PrintShuffleMask(raw_ostream &Out, Type *Ty, ArrayRef<int> Mask) {
+ Out << ", <";
+ if (isa<ScalableVectorType>(Ty))
+ Out << "vscale x ";
+ Out << Mask.size() << " x i32> ";
+ bool FirstElt = true;
+ if (all_of(Mask, [](int Elt) { return Elt == 0; })) {
+ Out << "zeroinitializer";
+ } else if (all_of(Mask, [](int Elt) { return Elt == UndefMaskElem; })) {
+ Out << "undef";
+ } else {
+ Out << "<";
+ for (int Elt : Mask) {
+ if (FirstElt)
+ FirstElt = false;
+ else
+ Out << ", ";
+ Out << "i32 ";
+ if (Elt == UndefMaskElem)
+ Out << "undef";
+ else
+ Out << Elt;
+ }
+ Out << ">";
+ }
+}
+
namespace {
class TypePrinting {
@@ -561,6 +588,7 @@ void TypePrinting::print(Type *Ty, raw_ostream &OS) {
switch (Ty->getTypeID()) {
case Type::VoidTyID: OS << "void"; return;
case Type::HalfTyID: OS << "half"; return;
+ case Type::BFloatTyID: OS << "bfloat"; return;
case Type::FloatTyID: OS << "float"; return;
case Type::DoubleTyID: OS << "double"; return;
case Type::X86_FP80TyID: OS << "x86_fp80"; return;
@@ -623,12 +651,14 @@ void TypePrinting::print(Type *Ty, raw_ostream &OS) {
OS << ']';
return;
}
- case Type::VectorTyID: {
+ case Type::FixedVectorTyID:
+ case Type::ScalableVectorTyID: {
VectorType *PTy = cast<VectorType>(Ty);
+ ElementCount EC = PTy->getElementCount();
OS << "<";
- if (PTy->isScalable())
+ if (EC.Scalable)
OS << "vscale x ";
- OS << PTy->getNumElements() << " x ";
+ OS << EC.Min << " x ";
print(PTy->getElementType(), OS);
OS << '>';
return;
@@ -783,7 +813,7 @@ public:
/// These functions do the actual initialization.
inline void initializeIfNeeded();
- void initializeIndexIfNeeded();
+ int initializeIndexIfNeeded();
// Implementation Details
private:
@@ -806,7 +836,8 @@ private:
/// Add all of the module level global variables (and their initializers)
/// and function declarations, but not the contents of those functions.
void processModule();
- void processIndex();
+ // Returns number of allocated slots
+ int processIndex();
/// Add all of the functions arguments, basic blocks, and instructions.
void processFunction();
@@ -920,11 +951,12 @@ inline void SlotTracker::initializeIfNeeded() {
processFunction();
}
-void SlotTracker::initializeIndexIfNeeded() {
+int SlotTracker::initializeIndexIfNeeded() {
if (!TheIndex)
- return;
- processIndex();
+ return 0;
+ int NumSlots = processIndex();
TheIndex = nullptr; ///< Prevent re-processing next time we're called.
+ return NumSlots;
}
// Iterate through all the global variables, functions, and global
@@ -1019,7 +1051,7 @@ void SlotTracker::processFunction() {
}
// Iterate through all the GUID in the index and create slots for them.
-void SlotTracker::processIndex() {
+int SlotTracker::processIndex() {
ST_DEBUG("begin processIndex!\n");
assert(TheIndex);
@@ -1038,17 +1070,17 @@ void SlotTracker::processIndex() {
for (auto &GlobalList : *TheIndex)
CreateGUIDSlot(GlobalList.first);
+ for (auto &TId : TheIndex->typeIdCompatibleVtableMap())
+ CreateGUIDSlot(GlobalValue::getGUID(TId.first));
+
// Start numbering the TypeIds after the GUIDs.
TypeIdNext = GUIDNext;
-
for (auto TidIter = TheIndex->typeIds().begin();
TidIter != TheIndex->typeIds().end(); TidIter++)
CreateTypeIdSlot(TidIter->second.first);
- for (auto &TId : TheIndex->typeIdCompatibleVtableMap())
- CreateGUIDSlot(GlobalValue::getGUID(TId.first));
-
ST_DEBUG("end processIndex!\n");
+ return TypeIdNext;
}
void SlotTracker::processGlobalObjectMetadata(const GlobalObject &GO) {
@@ -1348,7 +1380,7 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV,
return;
}
- // Either half, or some form of long double.
+ // Either half, bfloat or some form of long double.
// These appear as a magic letter identifying the type, then a
// fixed number of hex digits.
Out << "0x";
@@ -1376,6 +1408,10 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV,
Out << 'H';
Out << format_hex_no_prefix(API.getZExtValue(), 4,
/*Upper=*/true);
+ } else if (&APF.getSemantics() == &APFloat::BFloat()) {
+ Out << 'R';
+ Out << format_hex_no_prefix(API.getZExtValue(), 4,
+ /*Upper=*/true);
} else
llvm_unreachable("Unsupported floating point type");
return;
@@ -1475,13 +1511,14 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV,
}
if (isa<ConstantVector>(CV) || isa<ConstantDataVector>(CV)) {
- Type *ETy = CV->getType()->getVectorElementType();
+ auto *CVVTy = cast<VectorType>(CV->getType());
+ Type *ETy = CVVTy->getElementType();
Out << '<';
TypePrinter.print(ETy, Out);
Out << ' ';
WriteAsOperandInternal(Out, CV->getAggregateElement(0U), &TypePrinter,
Machine, Context);
- for (unsigned i = 1, e = CV->getType()->getVectorNumElements(); i != e;++i){
+ for (unsigned i = 1, e = CVVTy->getNumElements(); i != e; ++i) {
Out << ", ";
TypePrinter.print(ETy, Out);
Out << ' ';
@@ -1545,6 +1582,9 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV,
TypePrinter.print(CE->getType(), Out);
}
+ if (CE->getOpcode() == Instruction::ShuffleVector)
+ PrintShuffleMask(Out, CE->getType(), CE->getShuffleMask());
+
Out << ')';
return;
}
@@ -1614,6 +1654,8 @@ struct MDFieldPrinter {
bool ShouldSkipNull = true);
template <class IntTy>
void printInt(StringRef Name, IntTy Int, bool ShouldSkipZero = true);
+ void printAPInt(StringRef Name, const APInt &Int, bool IsUnsigned,
+ bool ShouldSkipZero);
void printBool(StringRef Name, bool Value, Optional<bool> Default = None);
void printDIFlags(StringRef Name, DINode::DIFlags Flags);
void printDISPFlags(StringRef Name, DISubprogram::DISPFlags Flags);
@@ -1689,6 +1731,15 @@ void MDFieldPrinter::printInt(StringRef Name, IntTy Int, bool ShouldSkipZero) {
Out << FS << Name << ": " << Int;
}
+void MDFieldPrinter::printAPInt(StringRef Name, const APInt &Int,
+ bool IsUnsigned, bool ShouldSkipZero) {
+ if (ShouldSkipZero && Int.isNullValue())
+ return;
+
+ Out << FS << Name << ": ";
+ Int.print(Out, !IsUnsigned);
+}
+
void MDFieldPrinter::printBool(StringRef Name, bool Value,
Optional<bool> Default) {
if (Default && Value == *Default)
@@ -1807,9 +1858,34 @@ static void writeDISubrange(raw_ostream &Out, const DISubrange *N,
if (auto *CE = N->getCount().dyn_cast<ConstantInt*>())
Printer.printInt("count", CE->getSExtValue(), /* ShouldSkipZero */ false);
else
- Printer.printMetadata("count", N->getCount().dyn_cast<DIVariable*>(),
- /*ShouldSkipNull */ false);
- Printer.printInt("lowerBound", N->getLowerBound());
+ Printer.printMetadata("count", N->getCount().dyn_cast<DIVariable *>(),
+ /*ShouldSkipNull */ true);
+
+ // A lowerBound of constant 0 should not be skipped, since it is different
+ // from an unspecified lower bound (= nullptr).
+ auto *LBound = N->getRawLowerBound();
+ if (auto *LE = dyn_cast_or_null<ConstantAsMetadata>(LBound)) {
+ auto *LV = cast<ConstantInt>(LE->getValue());
+ Printer.printInt("lowerBound", LV->getSExtValue(),
+ /* ShouldSkipZero */ false);
+ } else
+ Printer.printMetadata("lowerBound", LBound, /*ShouldSkipNull */ true);
+
+ auto *UBound = N->getRawUpperBound();
+ if (auto *UE = dyn_cast_or_null<ConstantAsMetadata>(UBound)) {
+ auto *UV = cast<ConstantInt>(UE->getValue());
+ Printer.printInt("upperBound", UV->getSExtValue(),
+ /* ShouldSkipZero */ false);
+ } else
+ Printer.printMetadata("upperBound", UBound, /*ShouldSkipNull */ true);
+
+ auto *Stride = N->getRawStride();
+ if (auto *SE = dyn_cast_or_null<ConstantAsMetadata>(Stride)) {
+ auto *SV = cast<ConstantInt>(SE->getValue());
+ Printer.printInt("stride", SV->getSExtValue(), /* ShouldSkipZero */ false);
+ } else
+ Printer.printMetadata("stride", Stride, /*ShouldSkipNull */ true);
+
Out << ")";
}
@@ -1818,13 +1894,10 @@ static void writeDIEnumerator(raw_ostream &Out, const DIEnumerator *N,
Out << "!DIEnumerator(";
MDFieldPrinter Printer(Out);
Printer.printString("name", N->getName(), /* ShouldSkipEmpty */ false);
- if (N->isUnsigned()) {
- auto Value = static_cast<uint64_t>(N->getValue());
- Printer.printInt("value", Value, /* ShouldSkipZero */ false);
+ Printer.printAPInt("value", N->getValue(), N->isUnsigned(),
+ /*ShouldSkipZero=*/false);
+ if (N->isUnsigned())
Printer.printBool("isUnsigned", true);
- } else {
- Printer.printInt("value", N->getValue(), /* ShouldSkipZero */ false);
- }
Out << ")";
}
@@ -1888,6 +1961,7 @@ static void writeDICompositeType(raw_ostream &Out, const DICompositeType *N,
Printer.printMetadata("templateParams", N->getRawTemplateParams());
Printer.printString("identifier", N->getIdentifier());
Printer.printMetadata("discriminator", N->getRawDiscriminator());
+ Printer.printMetadata("dataLocation", N->getRawDataLocation());
Out << ")";
}
@@ -1945,6 +2019,8 @@ static void writeDICompileUnit(raw_ostream &Out, const DICompileUnit *N,
false);
Printer.printNameTableKind("nameTableKind", N->getNameTableKind());
Printer.printBool("rangesBaseAddress", N->getRangesBaseAddress(), false);
+ Printer.printString("sysroot", N->getSysRoot());
+ Printer.printString("sdk", N->getSDK());
Out << ")";
}
@@ -2057,7 +2133,9 @@ static void writeDIModule(raw_ostream &Out, const DIModule *N,
Printer.printString("name", N->getName());
Printer.printString("configMacros", N->getConfigurationMacros());
Printer.printString("includePath", N->getIncludePath());
- Printer.printString("sysroot", N->getSysRoot());
+ Printer.printString("apinotes", N->getAPINotesFile());
+ Printer.printMetadata("file", N->getRawFile());
+ Printer.printInt("line", N->getLineNo());
Out << ")";
}
@@ -2071,6 +2149,7 @@ static void writeDITemplateTypeParameter(raw_ostream &Out,
MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
Printer.printString("name", N->getName());
Printer.printMetadata("type", N->getRawType(), /* ShouldSkipNull */ false);
+ Printer.printBool("defaulted", N->isDefault(), /* Default= */ false);
Out << ")";
}
@@ -2085,6 +2164,7 @@ static void writeDITemplateValueParameter(raw_ostream &Out,
Printer.printTag(N);
Printer.printString("name", N->getName());
Printer.printMetadata("type", N->getRawType());
+ Printer.printBool("defaulted", N->isDefault(), /* Default= */ false);
Printer.printMetadata("value", N->getValue(), /* ShouldSkipNull */ false);
Out << ")";
}
@@ -2430,10 +2510,10 @@ public:
void printTypeIdInfo(const FunctionSummary::TypeIdInfo &TIDInfo);
void printVFuncId(const FunctionSummary::VFuncId VFId);
void
- printNonConstVCalls(const std::vector<FunctionSummary::VFuncId> VCallList,
+ printNonConstVCalls(const std::vector<FunctionSummary::VFuncId> &VCallList,
const char *Tag);
void
- printConstVCalls(const std::vector<FunctionSummary::ConstVCall> VCallList,
+ printConstVCalls(const std::vector<FunctionSummary::ConstVCall> &VCallList,
const char *Tag);
private:
@@ -2651,8 +2731,10 @@ void AssemblyWriter::printModule(const Module *M) {
printUseLists(nullptr);
// Output all of the functions.
- for (const Function &F : *M)
+ for (const Function &F : *M) {
+ Out << '\n';
printFunction(&F);
+ }
assert(UseListOrders.empty() && "All use-lists should have been consumed");
// Output all attribute groups.
@@ -2676,21 +2758,22 @@ void AssemblyWriter::printModule(const Module *M) {
void AssemblyWriter::printModuleSummaryIndex() {
assert(TheIndex);
- Machine.initializeIndexIfNeeded();
+ int NumSlots = Machine.initializeIndexIfNeeded();
Out << "\n";
// Print module path entries. To print in order, add paths to a vector
// indexed by module slot.
std::vector<std::pair<std::string, ModuleHash>> moduleVec;
- std::string RegularLTOModuleName = "[Regular LTO]";
+ std::string RegularLTOModuleName =
+ ModuleSummaryIndex::getRegularLTOModuleName();
moduleVec.resize(TheIndex->modulePaths().size());
for (auto &ModPath : TheIndex->modulePaths())
moduleVec[Machine.getModulePathSlot(ModPath.first())] = std::make_pair(
// A module id of -1 is a special entry for a regular LTO module created
// during the thin link.
ModPath.second.first == -1u ? RegularLTOModuleName
- : (std::string)ModPath.first(),
+ : (std::string)std::string(ModPath.first()),
ModPath.second.second);
unsigned i = 0;
@@ -2737,6 +2820,15 @@ void AssemblyWriter::printModuleSummaryIndex() {
printTypeIdCompatibleVtableSummary(TId.second);
Out << ") ; guid = " << GUID << "\n";
}
+
+ // Don't emit flags when it's not really needed (value is zero by default).
+ if (TheIndex->getFlags()) {
+ Out << "^" << NumSlots << " = flags: " << TheIndex->getFlags() << "\n";
+ ++NumSlots;
+ }
+
+ Out << "^" << NumSlots << " = blockcount: " << TheIndex->getBlockCount()
+ << "\n";
}
static const char *
@@ -2769,6 +2861,8 @@ static const char *getWholeProgDevirtResByArgKindName(
static const char *getTTResKindName(TypeTestResolution::Kind K) {
switch (K) {
+ case TypeTestResolution::Unknown:
+ return "unknown";
case TypeTestResolution::Unsat:
return "unsat";
case TypeTestResolution::ByteArray:
@@ -2900,10 +2994,15 @@ void AssemblyWriter::printAliasSummary(const AliasSummary *AS) {
}
void AssemblyWriter::printGlobalVarSummary(const GlobalVarSummary *GS) {
+ auto VTableFuncs = GS->vTableFuncs();
Out << ", varFlags: (readonly: " << GS->VarFlags.MaybeReadOnly << ", "
- << "writeonly: " << GS->VarFlags.MaybeWriteOnly << ")";
+ << "writeonly: " << GS->VarFlags.MaybeWriteOnly << ", "
+ << "constant: " << GS->VarFlags.Constant;
+ if (!VTableFuncs.empty())
+ Out << ", "
+ << "vcall_visibility: " << GS->VarFlags.VCallVisibility;
+ Out << ")";
- auto VTableFuncs = GS->vTableFuncs();
if (!VTableFuncs.empty()) {
Out << ", vTableFuncs: (";
FieldSeparator FS;
@@ -2986,6 +3085,36 @@ void AssemblyWriter::printFunctionSummary(const FunctionSummary *FS) {
if (const auto *TIdInfo = FS->getTypeIdInfo())
printTypeIdInfo(*TIdInfo);
+
+ auto PrintRange = [&](const ConstantRange &Range) {
+ Out << "[" << Range.getLower() << ", " << Range.getSignedMax() << "]";
+ };
+
+ if (!FS->paramAccesses().empty()) {
+ Out << ", params: (";
+ FieldSeparator IFS;
+ for (auto &PS : FS->paramAccesses()) {
+ Out << IFS;
+ Out << "(param: " << PS.ParamNo;
+ Out << ", offset: ";
+ PrintRange(PS.Use);
+ if (!PS.Calls.empty()) {
+ Out << ", calls: (";
+ FieldSeparator IFS;
+ for (auto &Call : PS.Calls) {
+ Out << IFS;
+ Out << "(callee: ^" << Machine.getGUIDSlot(Call.Callee);
+ Out << ", param: " << Call.ParamNo;
+ Out << ", offset: ";
+ PrintRange(Call.Offsets);
+ Out << ")";
+ }
+ Out << ")";
+ }
+ Out << ")";
+ }
+ Out << ")";
+ }
}
void AssemblyWriter::printTypeIdInfo(
@@ -3057,7 +3186,7 @@ void AssemblyWriter::printVFuncId(const FunctionSummary::VFuncId VFId) {
}
void AssemblyWriter::printNonConstVCalls(
- const std::vector<FunctionSummary::VFuncId> VCallList, const char *Tag) {
+ const std::vector<FunctionSummary::VFuncId> &VCallList, const char *Tag) {
Out << Tag << ": (";
FieldSeparator FS;
for (auto &VFuncId : VCallList) {
@@ -3068,7 +3197,8 @@ void AssemblyWriter::printNonConstVCalls(
}
void AssemblyWriter::printConstVCalls(
- const std::vector<FunctionSummary::ConstVCall> VCallList, const char *Tag) {
+ const std::vector<FunctionSummary::ConstVCall> &VCallList,
+ const char *Tag) {
Out << Tag << ": (";
FieldSeparator FS;
for (auto &ConstVCall : VCallList) {
@@ -3200,11 +3330,7 @@ static void PrintVisibility(GlobalValue::VisibilityTypes Vis,
static void PrintDSOLocation(const GlobalValue &GV,
formatted_raw_ostream &Out) {
- // GVs with local linkage or non default visibility are implicitly dso_local,
- // so we don't print it.
- bool Implicit = GV.hasLocalLinkage() ||
- (!GV.hasExternalWeakLinkage() && !GV.hasDefaultVisibility());
- if (GV.isDSOLocal() && !Implicit)
+ if (GV.isDSOLocal() && !GV.isImplicitDSOLocal())
Out << "dso_local ";
}
@@ -3850,7 +3976,7 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
PrintCallingConv(CI->getCallingConv(), Out);
}
- Operand = CI->getCalledValue();
+ Operand = CI->getCalledOperand();
FunctionType *FTy = CI->getFunctionType();
Type *RetTy = FTy->getReturnType();
const AttributeList &PAL = CI->getAttributes();
@@ -3889,7 +4015,7 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
writeOperandBundles(CI);
} else if (const InvokeInst *II = dyn_cast<InvokeInst>(&I)) {
- Operand = II->getCalledValue();
+ Operand = II->getCalledOperand();
FunctionType *FTy = II->getFunctionType();
Type *RetTy = FTy->getReturnType();
const AttributeList &PAL = II->getAttributes();
@@ -3932,7 +4058,7 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
Out << " unwind ";
writeOperand(II->getUnwindDest(), true);
} else if (const CallBrInst *CBI = dyn_cast<CallBrInst>(&I)) {
- Operand = CBI->getCalledValue();
+ Operand = CBI->getCalledOperand();
FunctionType *FTy = CBI->getFunctionType();
Type *RetTy = FTy->getReturnType();
const AttributeList &PAL = CBI->getAttributes();
@@ -4079,6 +4205,8 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
RMWI->getSyncScopeID());
} else if (const FenceInst *FI = dyn_cast<FenceInst>(&I)) {
writeAtomic(FI->getContext(), FI->getOrdering(), FI->getSyncScopeID());
+ } else if (const ShuffleVectorInst *SVI = dyn_cast<ShuffleVectorInst>(&I)) {
+ PrintShuffleMask(Out, SVI->getType(), SVI->getShuffleMask());
}
// Print Metadata info.
@@ -4140,9 +4268,16 @@ void AssemblyWriter::writeAttribute(const Attribute &Attr, bool InAttrGroup) {
return;
}
- assert(Attr.hasAttribute(Attribute::ByVal) && "unexpected type attr");
+ assert((Attr.hasAttribute(Attribute::ByVal) ||
+ Attr.hasAttribute(Attribute::Preallocated)) &&
+ "unexpected type attr");
+
+ if (Attr.hasAttribute(Attribute::ByVal)) {
+ Out << "byval";
+ } else {
+ Out << "preallocated";
+ }
- Out << "byval";
if (Type *Ty = Attr.getValueAsType()) {
Out << '(';
TypePrinter.print(Ty, Out);
@@ -4228,6 +4363,17 @@ void Function::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW,
W.printFunction(this);
}
+void BasicBlock::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW,
+ bool ShouldPreserveUseListOrder,
+ bool IsForDebug) const {
+ SlotTracker SlotTable(this->getModule());
+ formatted_raw_ostream OS(ROS);
+ AssemblyWriter W(OS, SlotTable, this->getModule(), AAW,
+ IsForDebug,
+ ShouldPreserveUseListOrder);
+ W.printBasicBlock(this);
+}
+
void Module::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW,
bool ShouldPreserveUseListOrder, bool IsForDebug) const {
SlotTracker SlotTable(this);