[llvm] r174867 - Add support for printing out the attribute groups.

Bill Wendling isanbard at gmail.com
Mon Feb 11 00:43:33 PST 2013


Author: void
Date: Mon Feb 11 02:43:33 2013
New Revision: 174867

URL: http://llvm.org/viewvc/llvm-project?rev=174867&view=rev
Log:
Add support for printing out the attribute groups.

This emits the attribute groups that are used by the functions. (It currently
doesn't print out return type or parameter attributes within attribute groups.)

Note: The functions still retrieve their attributes from the "old" bitcode
format (using the deprecated 'Raw()' method). This means that string attributes
within an attribute group will not show up during a disassembly. This will be
addressed in a future commit.

Modified:
    llvm/trunk/include/llvm/IR/Attributes.h
    llvm/trunk/lib/IR/AsmWriter.cpp
    llvm/trunk/lib/IR/AttributeImpl.h
    llvm/trunk/lib/IR/Attributes.cpp

Modified: llvm/trunk/include/llvm/IR/Attributes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Attributes.h?rev=174867&r1=174866&r2=174867&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Attributes.h (original)
+++ llvm/trunk/include/llvm/IR/Attributes.h Mon Feb 11 02:43:33 2013
@@ -171,7 +171,7 @@ public:
 
   /// \brief The Attribute is converted to a string of equivalent mnemonic. This
   /// is, presumably, for writing out the mnemonics for the assembly writer.
-  std::string getAsString() const;
+  std::string getAsString(bool InAttrGrp = false) const;
 
   /// \brief Equality and non-equality operators.
   bool operator==(Attribute A) const { return pImpl == A.pImpl; }
@@ -317,7 +317,7 @@ public:
   unsigned getStackAlignment(unsigned Index) const;
 
   /// \brief Return the attributes at the index as a string.
-  std::string getAsString(unsigned Index) const;
+  std::string getAsString(unsigned Index, bool InAttrGrp = false) const;
 
   typedef ArrayRef<Attribute>::iterator iterator;
 

Modified: llvm/trunk/lib/IR/AsmWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/AsmWriter.cpp?rev=174867&r1=174866&r2=174867&view=diff
==============================================================================
--- llvm/trunk/lib/IR/AsmWriter.cpp (original)
+++ llvm/trunk/lib/IR/AsmWriter.cpp Mon Feb 11 02:43:33 2013
@@ -347,6 +347,10 @@ private:
   /// mdnMap - Map for MDNodes.
   DenseMap<const MDNode*, unsigned> mdnMap;
   unsigned mdnNext;
+
+  /// asMap - The slot map for attribute sets.
+  DenseMap<AttributeSet, unsigned> asMap;
+  unsigned asNext;
 public:
   /// Construct from a module
   explicit SlotTracker(const Module *M);
@@ -358,6 +362,7 @@ public:
   int getLocalSlot(const Value *V);
   int getGlobalSlot(const GlobalValue *V);
   int getMetadataSlot(const MDNode *N);
+  int getAttributeGroupSlot(AttributeSet AS);
 
   /// If you'd like to deal with a function instead of just a module, use
   /// this method to get its data into the SlotTracker.
@@ -378,6 +383,13 @@ public:
   unsigned mdn_size() const { return mdnMap.size(); }
   bool mdn_empty() const { return mdnMap.empty(); }
 
+  /// AttributeSet map iterators.
+  typedef DenseMap<AttributeSet, unsigned>::iterator as_iterator;
+  as_iterator as_begin()   { return asMap.begin(); }
+  as_iterator as_end()     { return asMap.end(); }
+  unsigned as_size() const { return asMap.size(); }
+  bool as_empty() const    { return asMap.empty(); }
+
   /// This function does the actual initialization.
   inline void initialize();
 
@@ -392,6 +404,9 @@ private:
   /// CreateFunctionSlot - Insert the specified Value* into the slot table.
   void CreateFunctionSlot(const Value *V);
 
+  /// \brief Insert the specified AttributeSet into the slot table.
+  void CreateAttributeSetSlot(AttributeSet AS);
+
   /// Add all of the module level global variables (and their initializers)
   /// and function declarations, but not the contents of those functions.
   void processModule();
@@ -446,14 +461,14 @@ static SlotTracker *createSlotTracker(co
 // to be added to the slot table.
 SlotTracker::SlotTracker(const Module *M)
   : TheModule(M), TheFunction(0), FunctionProcessed(false),
-    mNext(0), fNext(0),  mdnNext(0) {
+    mNext(0), fNext(0),  mdnNext(0), asNext(0) {
 }
 
 // Function level constructor. Causes the contents of the Module and the one
 // function provided to be added to the slot table.
 SlotTracker::SlotTracker(const Function *F)
   : TheModule(F ? F->getParent() : 0), TheFunction(F), FunctionProcessed(false),
-    mNext(0), fNext(0), mdnNext(0) {
+    mNext(0), fNext(0), mdnNext(0), asNext(0) {
 }
 
 inline void SlotTracker::initialize() {
@@ -487,12 +502,18 @@ void SlotTracker::processModule() {
       CreateMetadataSlot(NMD->getOperand(i));
   }
 
-  // Add all the unnamed functions to the table.
   for (Module::const_iterator I = TheModule->begin(), E = TheModule->end();
-       I != E; ++I)
+       I != E; ++I) {
     if (!I->hasName())
+      // Add all the unnamed functions to the table.
       CreateModuleSlot(I);
 
+    // Add all the function attributes to the table.
+    AttributeSet FnAttrs = I->getAttributes().getFnAttributes();
+    if (FnAttrs.hasAttributes(AttributeSet::FunctionIndex))
+      CreateAttributeSetSlot(FnAttrs);
+  }
+
   ST_DEBUG("end processModule!\n");
 }
 
@@ -589,6 +610,14 @@ int SlotTracker::getLocalSlot(const Valu
   return FI == fMap.end() ? -1 : (int)FI->second;
 }
 
+int SlotTracker::getAttributeGroupSlot(AttributeSet AS) {
+  // Check for uninitialized state and do lazy initialization.
+  initialize();
+
+  // Find the AttributeSet in the module map.
+  as_iterator AI = asMap.find(AS);
+  return AI == asMap.end() ? -1 : (int)AI->second;
+}
 
 /// CreateModuleSlot - Insert the specified GlobalValue* into the slot table.
 void SlotTracker::CreateModuleSlot(const GlobalValue *V) {
@@ -640,6 +669,18 @@ void SlotTracker::CreateMetadataSlot(con
       CreateMetadataSlot(Op);
 }
 
+void SlotTracker::CreateAttributeSetSlot(AttributeSet AS) {
+  assert(AS.hasAttributes(AttributeSet::FunctionIndex) &&
+         "Doesn't need a slot!");
+
+  as_iterator I = asMap.find(AS);
+  if (I != asMap.end())
+    return;
+
+  unsigned DestSlot = asNext++;
+  asMap[AS] = DestSlot;
+}
+
 //===----------------------------------------------------------------------===//
 // AsmWriter Implementation
 //===----------------------------------------------------------------------===//
@@ -1201,6 +1242,7 @@ public:
   void writeAtomic(AtomicOrdering Ordering, SynchronizationScope SynchScope);
 
   void writeAllMDNodes();
+  void writeAllAttributeGroups();
 
   void printTypeIdentities();
   void printGlobal(const GlobalVariable *GV);
@@ -1268,6 +1310,8 @@ void AssemblyWriter::writeParamOperand(c
 }
 
 void AssemblyWriter::printModule(const Module *M) {
+  Machine.initialize();
+
   if (!M->getModuleIdentifier().empty() &&
       // Don't print the ID if it will start a new line (which would
       // require a comment char before it).
@@ -1322,6 +1366,12 @@ void AssemblyWriter::printModule(const M
   for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I)
     printFunction(I);
 
+  // Output all attribute groups.
+  if (!Machine.as_empty()) {
+    Out << '\n';
+    writeAllAttributeGroups();
+  }
+
   // Output named metadata.
   if (!M->named_metadata_empty()) Out << '\n';
 
@@ -2063,6 +2113,20 @@ void AssemblyWriter::printMDNodeBody(con
   Out << "\n";
 }
 
+void AssemblyWriter::writeAllAttributeGroups() {
+  std::vector<std::pair<AttributeSet, unsigned> > asVec;
+  asVec.resize(Machine.as_size());
+
+  for (SlotTracker::as_iterator I = Machine.as_begin(), E = Machine.as_end();
+       I != E; ++I)
+    asVec[I->second] = *I;
+
+  for (std::vector<std::pair<AttributeSet, unsigned> >::iterator
+         I = asVec.begin(), E = asVec.end(); I != E; ++I)
+    Out << "attributes #" << I->second << " = { "
+        << I->first.getAsString(AttributeSet::FunctionIndex, true) << " }\n";
+}
+
 //===----------------------------------------------------------------------===//
 //                       External Interface declarations
 //===----------------------------------------------------------------------===//

Modified: llvm/trunk/lib/IR/AttributeImpl.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/AttributeImpl.h?rev=174867&r1=174866&r2=174867&view=diff
==============================================================================
--- llvm/trunk/lib/IR/AttributeImpl.h (original)
+++ llvm/trunk/lib/IR/AttributeImpl.h Mon Feb 11 02:43:33 2013
@@ -174,7 +174,7 @@ public:
 
   unsigned getAlignment() const;
   unsigned getStackAlignment() const;
-  std::string getAsString() const;
+  std::string getAsString(bool InAttrGrp) const;
 
   typedef SmallVectorImpl<Attribute>::iterator       iterator;
   typedef SmallVectorImpl<Attribute>::const_iterator const_iterator;

Modified: llvm/trunk/lib/IR/Attributes.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Attributes.cpp?rev=174867&r1=174866&r2=174867&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Attributes.cpp (original)
+++ llvm/trunk/lib/IR/Attributes.cpp Mon Feb 11 02:43:33 2013
@@ -150,7 +150,7 @@ unsigned Attribute::getStackAlignment()
   return pImpl->getValueAsInt();
 }
 
-std::string Attribute::getAsString() const {
+std::string Attribute::getAsString(bool InAttrGrp) const {
   if (!pImpl) return "";
 
   if (hasAttribute(Attribute::AddressSafety))
@@ -221,15 +221,23 @@ std::string Attribute::getAsString() con
   //
   if (hasAttribute(Attribute::Alignment)) {
     std::string Result;
-    Result += "align ";
+    Result += "align";
+    Result += (InAttrGrp) ? "=" : " ";
     Result += utostr(getValueAsInt());
     return Result;
   }
+
   if (hasAttribute(Attribute::StackAlignment)) {
     std::string Result;
-    Result += "alignstack(";
-    Result += utostr(getValueAsInt());
-    Result += ")";
+    Result += "alignstack";
+    if (InAttrGrp) {
+      Result += "=";
+      Result += utostr(getValueAsInt());
+    } else {
+      Result += "(";
+      Result += utostr(getValueAsInt());
+      Result += ")";
+    }
     return Result;
   }
 
@@ -237,7 +245,6 @@ std::string Attribute::getAsString() con
   //
   //   "kind"
   //   "kind" = "value"
-  //   "kind" = ( "value1" "value2" "value3" )
   //
   if (isStringAttribute()) {
     std::string Result;
@@ -246,8 +253,7 @@ std::string Attribute::getAsString() con
     StringRef Val = pImpl->getValueAsString();
     if (Val.empty()) return Result;
 
-    Result += " = ";
-    Result += '\"' + Val.str() + '"';
+    Result += "=\"" + Val.str() + '"';
     return Result;
   }
 
@@ -451,11 +457,11 @@ unsigned AttributeSetNode::getStackAlign
   return 0;
 }
 
-std::string AttributeSetNode::getAsString() const {
+std::string AttributeSetNode::getAsString(bool InAttrGrp) const {
   std::string Str = "";
   for (SmallVectorImpl<Attribute>::const_iterator I = AttrList.begin(),
          E = AttrList.end(); I != E; ) {
-    Str += I->getAsString();
+    Str += I->getAsString(InAttrGrp);
     if (++I != E) Str += " ";
   }
   return Str;
@@ -783,9 +789,10 @@ unsigned AttributeSet::getStackAlignment
   return ASN ? ASN->getStackAlignment() : 0;
 }
 
-std::string AttributeSet::getAsString(unsigned Index) const {
+std::string AttributeSet::getAsString(unsigned Index,
+                                      bool InAttrGrp) const {
   AttributeSetNode *ASN = getAttributes(Index);
-  return ASN ? ASN->getAsString() : std::string("");
+  return ASN ? ASN->getAsString(InAttrGrp) : std::string("");
 }
 
 /// \brief The attributes for the specified index are returned.





More information about the llvm-commits mailing list