+static void WriteMDNodes(raw_ostream &Out, TypePrinting &TypePrinter,
+ SlotTracker &Machine) {
+ SmallVector<const MDNode *, 16> Nodes;
+ Nodes.resize(Machine.mdnSize());
+ for (SlotTracker::ValueMap::iterator I =
+ Machine.mdnBegin(), E = Machine.mdnEnd(); I != E; ++I)
+ Nodes[I->second] = cast<MDNode>(I->first);
+
+ for (unsigned i = 0, e = Nodes.size(); i != e; ++i) {
+ Out << '!' << i << " = metadata ";
+ const MDNode *Node = Nodes[i];
+ Out << "!{";
+ for (MDNode::const_elem_iterator NI = Node->elem_begin(),
+ NE = Node->elem_end(); NI != NE;) {
+ const Value *V = *NI;
+ if (!V)
+ Out << "null";
+ else if (const MDNode *N = dyn_cast<MDNode>(V)) {
+ Out << "metadata ";
+ Out << '!' << Machine.getMetadataSlot(N);
+ }
+ else {
+ TypePrinter.print((*NI)->getType(), Out);
+ Out << ' ';
+ WriteAsOperandInternal(Out, *NI, TypePrinter, &Machine);
+ }
+ if (++NI != NE)
+ Out << ", ";
+ }
+ Out << "}\n";
+ }
+}
+
+static void WriteOptimizationInfo(raw_ostream &Out, const User *U) {
+ if (const OverflowingBinaryOperator *OBO =
+ dyn_cast<OverflowingBinaryOperator>(U)) {
+ if (OBO->hasNoUnsignedOverflow())
+ Out << " nuw";
+ if (OBO->hasNoSignedOverflow())
+ Out << " nsw";
+ } else if (const SDivOperator *Div = dyn_cast<SDivOperator>(U)) {
+ if (Div->isExact())
+ Out << " exact";
+ } else if (const GEPOperator *GEP = dyn_cast<GEPOperator>(U)) {
+ if (GEP->isInBounds())
+ Out << " inbounds";
+ }
+}
+