/// 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);
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.
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();
/// 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();
// 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() {
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");
}
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) {
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
//===----------------------------------------------------------------------===//
void writeAtomic(AtomicOrdering Ordering, SynchronizationScope SynchScope);
void writeAllMDNodes();
+ void writeAllAttributeGroups();
void printTypeIdentities();
void printGlobal(const GlobalVariable *GV);
}
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).
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';
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
//===----------------------------------------------------------------------===//
return pImpl->getValueAsInt();
}
-std::string Attribute::getAsString() const {
+std::string Attribute::getAsString(bool InAttrGrp) const {
if (!pImpl) return "";
if (hasAttribute(Attribute::AddressSafety))
//
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;
}
//
// "kind"
// "kind" = "value"
- // "kind" = ( "value1" "value2" "value3" )
//
if (isStringAttribute()) {
std::string Result;
StringRef Val = pImpl->getValueAsString();
if (Val.empty()) return Result;
- Result += " = ";
- Result += '\"' + Val.str() + '"';
+ Result += "=\"" + Val.str() + '"';
return Result;
}
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;
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.