diff options
author | Bill Wendling <isanbard@gmail.com> | 2013-02-11 08:43:33 +0000 |
---|---|---|
committer | Bill Wendling <isanbard@gmail.com> | 2013-02-11 08:43:33 +0000 |
commit | b29ce26ea60f7516c853318ffbfc107fde9ad897 (patch) | |
tree | 24b16ea7c960b04ed253ecf581394c321fb135bb /lib/IR | |
parent | 595ef3e314e4c40b1f8b6b4f90b418a30a637242 (diff) | |
download | external_llvm-b29ce26ea60f7516c853318ffbfc107fde9ad897.zip external_llvm-b29ce26ea60f7516c853318ffbfc107fde9ad897.tar.gz external_llvm-b29ce26ea60f7516c853318ffbfc107fde9ad897.tar.bz2 |
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.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@174867 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/IR')
-rw-r--r-- | lib/IR/AsmWriter.cpp | 72 | ||||
-rw-r--r-- | lib/IR/AttributeImpl.h | 2 | ||||
-rw-r--r-- | lib/IR/Attributes.cpp | 31 |
3 files changed, 88 insertions, 17 deletions
diff --git a/lib/IR/AsmWriter.cpp b/lib/IR/AsmWriter.cpp index d3736a1..bf893e8 100644 --- a/lib/IR/AsmWriter.cpp +++ b/lib/IR/AsmWriter.cpp @@ -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(const Value *V) { // 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 Value *V) { 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(const MDNode *N) { 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(const Value *Operand, } 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 Module *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(const MDNode *Node) { 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 //===----------------------------------------------------------------------===// diff --git a/lib/IR/AttributeImpl.h b/lib/IR/AttributeImpl.h index 84f472d..7bb1fcc 100644 --- a/lib/IR/AttributeImpl.h +++ b/lib/IR/AttributeImpl.h @@ -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; diff --git a/lib/IR/Attributes.cpp b/lib/IR/Attributes.cpp index 267c1aa..d338d65 100644 --- a/lib/IR/Attributes.cpp +++ b/lib/IR/Attributes.cpp @@ -150,7 +150,7 @@ unsigned Attribute::getStackAlignment() const { 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() const { // 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() const { // // "kind" // "kind" = "value" - // "kind" = ( "value1" "value2" "value3" ) // if (isStringAttribute()) { std::string Result; @@ -246,8 +253,7 @@ std::string Attribute::getAsString() const { StringRef Val = pImpl->getValueAsString(); if (Val.empty()) return Result; - Result += " = "; - Result += '\"' + Val.str() + '"'; + Result += "=\"" + Val.str() + '"'; return Result; } @@ -451,11 +457,11 @@ unsigned AttributeSetNode::getStackAlignment() const { 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(unsigned Index) const { 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. |