diff options
Diffstat (limited to 'llvm/lib/IR/AsmWriter.cpp')
| -rw-r--r-- | llvm/lib/IR/AsmWriter.cpp | 146 |
1 files changed, 131 insertions, 15 deletions
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index fd08310316b3..69abf8769e4b 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -116,6 +116,15 @@ struct OrderMap { } // end anonymous namespace +/// Look for a value that might be wrapped as metadata, e.g. a value in a +/// metadata operand. Returns the input value as-is if it is not wrapped. +static const Value *skipMetadataWrapper(const Value *V) { + if (const auto *MAV = dyn_cast<MetadataAsValue>(V)) + if (const auto *VAM = dyn_cast<ValueAsMetadata>(MAV->getMetadata())) + return VAM->getValue(); + return V; +} + static void orderValue(const Value *V, OrderMap &OM) { if (OM.lookup(V).first) return; @@ -132,8 +141,6 @@ static void orderValue(const Value *V, OrderMap &OM) { } static OrderMap orderModule(const Module *M) { - // This needs to match the order used by ValueEnumerator::ValueEnumerator() - // and ValueEnumerator::incorporateFunction(). OrderMap OM; for (const GlobalVariable &G : M->globals()) { @@ -167,10 +174,12 @@ static OrderMap orderModule(const Module *M) { for (const BasicBlock &BB : F) { orderValue(&BB, OM); for (const Instruction &I : BB) { - for (const Value *Op : I.operands()) + for (const Value *Op : I.operands()) { + Op = skipMetadataWrapper(Op); if ((isa<Constant>(*Op) && !isa<GlobalValue>(*Op)) || isa<InlineAsm>(*Op)) orderValue(Op, OM); + } orderValue(&I, OM); } } @@ -284,9 +293,11 @@ static UseListOrderStack predictUseListOrder(const Module *M) { predictValueUseListOrder(&A, &F, OM, Stack); for (const BasicBlock &BB : F) for (const Instruction &I : BB) - for (const Value *Op : I.operands()) + for (const Value *Op : I.operands()) { + Op = skipMetadataWrapper(Op); if (isa<Constant>(*Op) || isa<InlineAsm>(*Op)) // Visit GlobalValues. predictValueUseListOrder(Op, &F, OM, Stack); + } for (const BasicBlock &BB : F) for (const Instruction &I : BB) predictValueUseListOrder(&I, &F, OM, Stack); @@ -388,6 +399,7 @@ static void PrintCallingConv(unsigned cc, raw_ostream &Out) { case CallingConv::AMDGPU_PS: Out << "amdgpu_ps"; break; case CallingConv::AMDGPU_CS: Out << "amdgpu_cs"; break; case CallingConv::AMDGPU_KERNEL: Out << "amdgpu_kernel"; break; + case CallingConv::AMDGPU_Gfx: Out << "amdgpu_gfx"; break; } } @@ -597,6 +609,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::X86_AMXTyID: OS << "x86_amx"; return; case Type::TokenTyID: OS << "token"; return; case Type::IntegerTyID: OS << 'i' << cast<IntegerType>(Ty)->getBitWidth(); @@ -656,9 +669,9 @@ void TypePrinting::print(Type *Ty, raw_ostream &OS) { VectorType *PTy = cast<VectorType>(Ty); ElementCount EC = PTy->getElementCount(); OS << "<"; - if (EC.Scalable) + if (EC.isScalable()) OS << "vscale x "; - OS << EC.Min << " x "; + OS << EC.getKnownMinValue() << " x "; print(PTy->getElementType(), OS); OS << '>'; return; @@ -1355,9 +1368,8 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV, // "Inf" or NaN, that atof will accept, but the lexer will not. Check // that the string matches the "[-+]?[0-9]" regex. // - assert(((StrVal[0] >= '0' && StrVal[0] <= '9') || - ((StrVal[0] == '-' || StrVal[0] == '+') && - (StrVal[1] >= '0' && StrVal[1] <= '9'))) && + assert((isDigit(StrVal[0]) || ((StrVal[0] == '-' || StrVal[0] == '+') && + isDigit(StrVal[1]))) && "[-+]?[0-9] regex does not match!"); // Reparse stringized version! if (APFloat(APFloat::IEEEdouble(), StrVal).convertToDouble() == Val) { @@ -1373,9 +1385,19 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV, "assuming that double is 64 bits!"); APFloat apf = APF; // Floats are represented in ASCII IR as double, convert. - if (!isDouble) + // FIXME: We should allow 32-bit hex float and remove this. + if (!isDouble) { + // A signaling NaN is quieted on conversion, so we need to recreate the + // expected value after convert (quiet bit of the payload is clear). + bool IsSNAN = apf.isSignaling(); apf.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven, - &ignored); + &ignored); + if (IsSNAN) { + APInt Payload = apf.bitcastToAPInt(); + apf = APFloat::getSNaN(APFloat::IEEEdouble(), apf.isNegative(), + &Payload); + } + } Out << format_hex(apf.bitcastToAPInt().getZExtValue(), 0, /*Upper=*/true); return; } @@ -1433,6 +1455,13 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV, return; } + if (const auto *Equiv = dyn_cast<DSOLocalEquivalent>(CV)) { + Out << "dso_local_equivalent "; + WriteAsOperandInternal(Out, Equiv->getGlobalValue(), &TypePrinter, Machine, + Context); + return; + } + if (const ConstantArray *CA = dyn_cast<ConstantArray>(CV)) { Type *ETy = CA->getType()->getElementType(); Out << '['; @@ -1511,7 +1540,7 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV, } if (isa<ConstantVector>(CV) || isa<ConstantDataVector>(CV)) { - auto *CVVTy = cast<VectorType>(CV->getType()); + auto *CVVTy = cast<FixedVectorType>(CV->getType()); Type *ETy = CVVTy->getElementType(); Out << '<'; TypePrinter.print(ETy, Out); @@ -1539,6 +1568,11 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV, return; } + if (isa<PoisonValue>(CV)) { + Out << "poison"; + return; + } + if (isa<UndefValue>(CV)) { Out << "undef"; return; @@ -1889,6 +1923,57 @@ static void writeDISubrange(raw_ostream &Out, const DISubrange *N, Out << ")"; } +static void writeDIGenericSubrange(raw_ostream &Out, const DIGenericSubrange *N, + TypePrinting *TypePrinter, + SlotTracker *Machine, + const Module *Context) { + Out << "!DIGenericSubrange("; + MDFieldPrinter Printer(Out, TypePrinter, Machine, Context); + + auto IsConstant = [&](Metadata *Bound) -> bool { + if (auto *BE = dyn_cast_or_null<DIExpression>(Bound)) { + return BE->isSignedConstant(); + } + return false; + }; + + auto GetConstant = [&](Metadata *Bound) -> int64_t { + assert(IsConstant(Bound) && "Expected constant"); + auto *BE = dyn_cast_or_null<DIExpression>(Bound); + return static_cast<int64_t>(BE->getElement(1)); + }; + + auto *Count = N->getRawCountNode(); + if (IsConstant(Count)) + Printer.printInt("count", GetConstant(Count), + /* ShouldSkipZero */ false); + else + Printer.printMetadata("count", Count, /*ShouldSkipNull */ true); + + auto *LBound = N->getRawLowerBound(); + if (IsConstant(LBound)) + Printer.printInt("lowerBound", GetConstant(LBound), + /* ShouldSkipZero */ false); + else + Printer.printMetadata("lowerBound", LBound, /*ShouldSkipNull */ true); + + auto *UBound = N->getRawUpperBound(); + if (IsConstant(UBound)) + Printer.printInt("upperBound", GetConstant(UBound), + /* ShouldSkipZero */ false); + else + Printer.printMetadata("upperBound", UBound, /*ShouldSkipNull */ true); + + auto *Stride = N->getRawStride(); + if (IsConstant(Stride)) + Printer.printInt("stride", GetConstant(Stride), + /* ShouldSkipZero */ false); + else + Printer.printMetadata("stride", Stride, /*ShouldSkipNull */ true); + + Out << ")"; +} + static void writeDIEnumerator(raw_ostream &Out, const DIEnumerator *N, TypePrinting *, SlotTracker *, const Module *) { Out << "!DIEnumerator("; @@ -1916,6 +2001,23 @@ static void writeDIBasicType(raw_ostream &Out, const DIBasicType *N, Out << ")"; } +static void writeDIStringType(raw_ostream &Out, const DIStringType *N, + TypePrinting *TypePrinter, SlotTracker *Machine, + const Module *Context) { + Out << "!DIStringType("; + MDFieldPrinter Printer(Out, TypePrinter, Machine, Context); + if (N->getTag() != dwarf::DW_TAG_string_type) + Printer.printTag(N); + Printer.printString("name", N->getName()); + Printer.printMetadata("stringLength", N->getRawStringLength()); + Printer.printMetadata("stringLengthExpression", N->getRawStringLengthExp()); + Printer.printInt("size", N->getSizeInBits()); + Printer.printInt("align", N->getAlignInBits()); + Printer.printDwarfEnum("encoding", N->getEncoding(), + dwarf::AttributeEncodingString); + Out << ")"; +} + static void writeDIDerivedType(raw_ostream &Out, const DIDerivedType *N, TypePrinting *TypePrinter, SlotTracker *Machine, const Module *Context) { @@ -1962,6 +2064,13 @@ static void writeDICompositeType(raw_ostream &Out, const DICompositeType *N, Printer.printString("identifier", N->getIdentifier()); Printer.printMetadata("discriminator", N->getRawDiscriminator()); Printer.printMetadata("dataLocation", N->getRawDataLocation()); + Printer.printMetadata("associated", N->getRawAssociated()); + Printer.printMetadata("allocated", N->getRawAllocated()); + if (auto *RankConst = N->getRankConst()) + Printer.printInt("rank", RankConst->getSExtValue(), + /* ShouldSkipZero */ false); + else + Printer.printMetadata("rank", N->getRawRank(), /*ShouldSkipNull */ true); Out << ")"; } @@ -2136,6 +2245,7 @@ static void writeDIModule(raw_ostream &Out, const DIModule *N, Printer.printString("apinotes", N->getAPINotesFile()); Printer.printMetadata("file", N->getRawFile()); Printer.printInt("line", N->getLineNo()); + Printer.printBool("isDecl", N->getIsDecl(), /* Default */ false); Out << ")"; } @@ -3087,7 +3197,7 @@ void AssemblyWriter::printFunctionSummary(const FunctionSummary *FS) { printTypeIdInfo(*TIdInfo); auto PrintRange = [&](const ConstantRange &Range) { - Out << "[" << Range.getLower() << ", " << Range.getSignedMax() << "]"; + Out << "[" << Range.getSignedMin() << ", " << Range.getSignedMax() << "]"; }; if (!FS->paramAccesses().empty()) { @@ -3103,7 +3213,7 @@ void AssemblyWriter::printFunctionSummary(const FunctionSummary *FS) { FieldSeparator IFS; for (auto &Call : PS.Calls) { Out << IFS; - Out << "(callee: ^" << Machine.getGUIDSlot(Call.Callee); + Out << "(callee: ^" << Machine.getGUIDSlot(Call.Callee.getGUID()); Out << ", param: " << Call.ParamNo; Out << ", offset: "; PrintRange(Call.Offsets); @@ -4269,11 +4379,17 @@ void AssemblyWriter::writeAttribute(const Attribute &Attr, bool InAttrGroup) { } assert((Attr.hasAttribute(Attribute::ByVal) || + Attr.hasAttribute(Attribute::StructRet) || + Attr.hasAttribute(Attribute::ByRef) || Attr.hasAttribute(Attribute::Preallocated)) && "unexpected type attr"); if (Attr.hasAttribute(Attribute::ByVal)) { Out << "byval"; + } else if (Attr.hasAttribute(Attribute::StructRet)) { + Out << "sret"; + } else if (Attr.hasAttribute(Attribute::ByRef)) { + Out << "byref"; } else { Out << "preallocated"; } @@ -4366,7 +4482,7 @@ void Function::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW, void BasicBlock::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW, bool ShouldPreserveUseListOrder, bool IsForDebug) const { - SlotTracker SlotTable(this->getModule()); + SlotTracker SlotTable(this->getParent()); formatted_raw_ostream OS(ROS); AssemblyWriter W(OS, SlotTable, this->getModule(), AAW, IsForDebug, |
