diff options
Diffstat (limited to 'lib/IR/AsmWriter.cpp')
-rw-r--r-- | lib/IR/AsmWriter.cpp | 72 |
1 files changed, 68 insertions, 4 deletions
diff --git a/lib/IR/AsmWriter.cpp b/lib/IR/AsmWriter.cpp index d3736a1bb4..bf893e855e 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 //===----------------------------------------------------------------------===// |