[RISCV][NFCI] Use common MCELFStreamer code for attribute emission
authorAlex Bradbury <asb@igalia.com>
Sun, 12 Mar 2023 16:11:12 +0000 (16:11 +0000)
committerAlex Bradbury <asb@igalia.com>
Sun, 12 Mar 2023 16:11:12 +0000 (16:11 +0000)
D102894 introduced common code for the emission of ELF attributes. Our
implementation in RISC-V predates this, and basically copies the Arm
logic at the time. This patch removes that duplication and uses the
shared logic instead.

Differential Revision: https://reviews.llvm.org/D145570

llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp
llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h

index f69fc7c..40f38ee 100644 (file)
@@ -53,98 +53,28 @@ void RISCVTargetELFStreamer::emitDirectiveOptionRelax() {}
 void RISCVTargetELFStreamer::emitDirectiveOptionNoRelax() {}
 
 void RISCVTargetELFStreamer::emitAttribute(unsigned Attribute, unsigned Value) {
-  setAttributeItem(Attribute, Value, /*OverwriteExisting=*/true);
+  getStreamer().setAttributeItem(Attribute, Value, /*OverwriteExisting=*/true);
 }
 
 void RISCVTargetELFStreamer::emitTextAttribute(unsigned Attribute,
                                                StringRef String) {
-  setAttributeItem(Attribute, String, /*OverwriteExisting=*/true);
+  getStreamer().setAttributeItem(Attribute, String, /*OverwriteExisting=*/true);
 }
 
 void RISCVTargetELFStreamer::emitIntTextAttribute(unsigned Attribute,
                                                   unsigned IntValue,
                                                   StringRef StringValue) {
-  setAttributeItems(Attribute, IntValue, StringValue,
-                    /*OverwriteExisting=*/true);
+  getStreamer().setAttributeItems(Attribute, IntValue, StringValue,
+                                  /*OverwriteExisting=*/true);
 }
 
 void RISCVTargetELFStreamer::finishAttributeSection() {
-  if (Contents.empty())
+  RISCVELFStreamer &S = getStreamer();
+  if (S.Contents.empty())
     return;
 
-  if (AttributeSection) {
-    Streamer.switchSection(AttributeSection);
-  } else {
-    MCAssembler &MCA = getStreamer().getAssembler();
-    AttributeSection = MCA.getContext().getELFSection(
-        ".riscv.attributes", ELF::SHT_RISCV_ATTRIBUTES, 0);
-    Streamer.switchSection(AttributeSection);
-
-    Streamer.emitInt8(ELFAttrs::Format_Version);
-  }
-
-  // Vendor size + Vendor name + '\0'
-  const size_t VendorHeaderSize = 4 + CurrentVendor.size() + 1;
-
-  // Tag + Tag Size
-  const size_t TagHeaderSize = 1 + 4;
-
-  const size_t ContentsSize = calculateContentSize();
-
-  Streamer.emitInt32(VendorHeaderSize + TagHeaderSize + ContentsSize);
-  Streamer.emitBytes(CurrentVendor);
-  Streamer.emitInt8(0); // '\0'
-
-  Streamer.emitInt8(ELFAttrs::File);
-  Streamer.emitInt32(TagHeaderSize + ContentsSize);
-
-  // Size should have been accounted for already, now
-  // emit each field as its type (ULEB or String).
-  for (AttributeItem item : Contents) {
-    Streamer.emitULEB128IntValue(item.Tag);
-    switch (item.Type) {
-    default:
-      llvm_unreachable("Invalid attribute type");
-    case AttributeType::Numeric:
-      Streamer.emitULEB128IntValue(item.IntValue);
-      break;
-    case AttributeType::Text:
-      Streamer.emitBytes(item.StringValue);
-      Streamer.emitInt8(0); // '\0'
-      break;
-    case AttributeType::NumericAndText:
-      Streamer.emitULEB128IntValue(item.IntValue);
-      Streamer.emitBytes(item.StringValue);
-      Streamer.emitInt8(0); // '\0'
-      break;
-    }
-  }
-
-  Contents.clear();
-}
-
-size_t RISCVTargetELFStreamer::calculateContentSize() const {
-  size_t Result = 0;
-  for (AttributeItem item : Contents) {
-    switch (item.Type) {
-    case AttributeType::Hidden:
-      break;
-    case AttributeType::Numeric:
-      Result += getULEB128Size(item.Tag);
-      Result += getULEB128Size(item.IntValue);
-      break;
-    case AttributeType::Text:
-      Result += getULEB128Size(item.Tag);
-      Result += item.StringValue.size() + 1; // string + '\0'
-      break;
-    case AttributeType::NumericAndText:
-      Result += getULEB128Size(item.Tag);
-      Result += getULEB128Size(item.IntValue);
-      Result += item.StringValue.size() + 1; // string + '\0';
-      break;
-    }
-  }
-  return Result;
+  S.emitAttributesSection(CurrentVendor, ".riscv.attributes",
+                          ELF::SHT_RISCV_ATTRIBUTES, AttributeSection);
 }
 
 void RISCVTargetELFStreamer::finish() {
@@ -184,7 +114,6 @@ void RISCVTargetELFStreamer::finish() {
 
 void RISCVTargetELFStreamer::reset() {
   AttributeSection = nullptr;
-  Contents.clear();
 }
 
 void RISCVTargetELFStreamer::emitDirectiveVariantCC(MCSymbol &Symbol) {
index 80b8be2..cf758bc 100644 (file)
@@ -32,81 +32,16 @@ namespace llvm {
 
 class RISCVTargetELFStreamer : public RISCVTargetStreamer {
 private:
-  enum class AttributeType { Hidden, Numeric, Text, NumericAndText };
-
-  struct AttributeItem {
-    AttributeType Type;
-    unsigned Tag;
-    unsigned IntValue;
-    std::string StringValue;
-  };
-
   StringRef CurrentVendor;
-  SmallVector<AttributeItem, 64> Contents;
 
   MCSection *AttributeSection = nullptr;
   const MCSubtargetInfo &STI;
 
-  AttributeItem *getAttributeItem(unsigned Attribute) {
-    for (size_t i = 0; i < Contents.size(); ++i)
-      if (Contents[i].Tag == Attribute)
-        return &Contents[i];
-    return nullptr;
-  }
-
-  void setAttributeItem(unsigned Attribute, unsigned Value,
-                        bool OverwriteExisting) {
-    // Look for existing attribute item.
-    if (AttributeItem *Item = getAttributeItem(Attribute)) {
-      if (!OverwriteExisting)
-        return;
-      Item->Type = AttributeType::Numeric;
-      Item->IntValue = Value;
-      return;
-    }
-
-    // Create new attribute item.
-    Contents.push_back({AttributeType::Numeric, Attribute, Value, ""});
-  }
-
-  void setAttributeItem(unsigned Attribute, StringRef Value,
-                        bool OverwriteExisting) {
-    // Look for existing attribute item.
-    if (AttributeItem *Item = getAttributeItem(Attribute)) {
-      if (!OverwriteExisting)
-        return;
-      Item->Type = AttributeType::Text;
-      Item->StringValue = std::string(Value);
-      return;
-    }
-
-    // Create new attribute item.
-    Contents.push_back({AttributeType::Text, Attribute, 0, std::string(Value)});
-  }
-
-  void setAttributeItems(unsigned Attribute, unsigned IntValue,
-                         StringRef StringValue, bool OverwriteExisting) {
-    // Look for existing attribute item.
-    if (AttributeItem *Item = getAttributeItem(Attribute)) {
-      if (!OverwriteExisting)
-        return;
-      Item->Type = AttributeType::NumericAndText;
-      Item->IntValue = IntValue;
-      Item->StringValue = std::string(StringValue);
-      return;
-    }
-
-    // Create new attribute item.
-    Contents.push_back({AttributeType::NumericAndText, Attribute, IntValue,
-                        std::string(StringValue)});
-  }
-
   void emitAttribute(unsigned Attribute, unsigned Value) override;
   void emitTextAttribute(unsigned Attribute, StringRef String) override;
   void emitIntTextAttribute(unsigned Attribute, unsigned IntValue,
                             StringRef StringValue) override;
   void finishAttributeSection() override;
-  size_t calculateContentSize() const;
 
   void reset() override;