#include "llvm/InlineAsm.h"
#include "llvm/Instruction.h"
#include "llvm/Instructions.h"
+#include "llvm/LLVMContext.h"
#include "llvm/Operator.h"
#include "llvm/Metadata.h"
#include "llvm/Module.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/CFG.h"
+#include "llvm/Support/Dwarf.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/FormattedStream.h"
ST_DEBUG("Inserting Instructions:\n");
- Metadata &TheMetadata = TheFunction->getContext().getMetadata();
+ MetadataContext &TheMetadata = TheFunction->getContext().getMetadata();
+ typedef SmallVector<std::pair<unsigned, TrackingVH<MDNode> >, 2> MDMapTy;
+ MDMapTy MDs;
// Add all of the basic blocks and instructions with no names.
for (Function::const_iterator BB = TheFunction->begin(),
CreateMetadataSlot(N);
// Process metadata attached with this instruction.
- const Metadata::MDMapTy *MDs = TheMetadata.getMDs(I);
- if (MDs)
- for (Metadata::MDMapTy::const_iterator MI = MDs->begin(),
- ME = MDs->end(); MI != ME; ++MI)
- if (MDNode *MDN = dyn_cast_or_null<MDNode>(MI->second))
- CreateMetadataSlot(MDN);
+ MDs.clear();
+ TheMetadata.getMDs(I, MDs);
+ for (MDMapTy::const_iterator MI = MDs.begin(), ME = MDs.end(); MI != ME;
+ ++MI)
+ CreateMetadataSlot(MI->second);
}
}
void SlotTracker::CreateMetadataSlot(const MDNode *N) {
assert(N && "Can't insert a null Value into SlotTracker!");
+ // Don't insert if N contains an instruction.
+ for (unsigned i = 0, e = N->getNumElements(); i != e; ++i)
+ if (N->getElement(i) && isa<Instruction>(N->getElement(i)))
+ return;
+
ValueMap::iterator I = mdnMap.find(N);
if (I != mdnMap.end())
return;
unsigned DestSlot = mdnNext++;
mdnMap[N] = DestSlot;
- for (MDNode::const_elem_iterator MDI = N->elem_begin(),
- MDE = N->elem_end(); MDI != MDE; ++MDI) {
- const Value *TV = *MDI;
+ for (unsigned i = 0, e = N->getNumElements(); i != e; ++i) {
+ const Value *TV = N->getElement(i);
if (TV)
if (const MDNode *N2 = dyn_cast<MDNode>(TV))
CreateMetadataSlot(N2);
return pred;
}
+static void WriteMDNodeComment(const MDNode *Node,
+ formatted_raw_ostream &Out) {
+ if (Node->getNumElements() < 1)
+ return;
+ ConstantInt *CI = dyn_cast_or_null<ConstantInt>(Node->getElement(0));
+ if (!CI) return;
+ unsigned Val = CI->getZExtValue();
+ unsigned Tag = Val & ~LLVMDebugVersionMask;
+ if (Val >= LLVMDebugVersion) {
+ if (Tag == dwarf::DW_TAG_auto_variable)
+ Out << "; [ DW_TAG_auto_variable ]";
+ else if (Tag == dwarf::DW_TAG_arg_variable)
+ Out << "; [ DW_TAG_arg_variable ]";
+ else if (Tag == dwarf::DW_TAG_return_variable)
+ Out << "; [ DW_TAG_return_variable ]";
+ else if (Tag == dwarf::DW_TAG_vector_type)
+ Out << "; [ DW_TAG_vector_type ]";
+ else if (Tag == dwarf::DW_TAG_user_base)
+ Out << "; [ DW_TAG_user_base ]";
+ else
+ Out << "; [" << dwarf::TagString(Tag) << " ]";
+ }
+}
+
static void WriteMDNodes(formatted_raw_ostream &Out, TypePrinting &TypePrinter,
SlotTracker &Machine) {
SmallVector<const MDNode *, 16> Nodes;
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;
+ for (unsigned mi = 0, me = Node->getNumElements(); mi != me; ++mi) {
+ const Value *V = Node->getElement(mi);
if (!V)
Out << "null";
else if (const MDNode *N = dyn_cast<MDNode>(V)) {
Out << '!' << Machine.getMetadataSlot(N);
}
else {
- TypePrinter.print((*NI)->getType(), Out);
+ TypePrinter.print(V->getType(), Out);
Out << ' ';
- WriteAsOperandInternal(Out, *NI, &TypePrinter, &Machine);
+ WriteAsOperandInternal(Out, Node->getElement(mi),
+ &TypePrinter, &Machine);
}
- if (++NI != NE)
+ if (mi + 1 != me)
Out << ", ";
}
- Out << "}\n";
+
+ Out << "}";
+ WriteMDNodeComment(Node, Out);
+ Out << "\n";
}
}
Out << "zeroinitializer";
return;
}
+
+ if (const BlockAddress *BA = dyn_cast<BlockAddress>(CV)) {
+ Out << "blockaddress(";
+ WriteAsOperandInternal(Out, BA->getFunction(), &TypePrinter, Machine);
+ Out << ", ";
+ WriteAsOperandInternal(Out, BA->getBasicBlock(), &TypePrinter, Machine);
+ Out << ")";
+ return;
+ }
if (const ConstantArray *CA = dyn_cast<ConstantArray>(CV)) {
// As a special case, print the array as a string if it is an array of
Out << "asm ";
if (IA->hasSideEffects())
Out << "sideeffect ";
+ if (IA->isAlignStack())
+ Out << "alignstack ";
Out << '"';
PrintEscapedString(IA->getAsmString(), Out);
Out << "\", \"";
}
if (const MDNode *N = dyn_cast<MDNode>(V)) {
+ if (Machine->getMetadataSlot(N) == -1) {
+ // Print metadata inline, not via slot reference number.
+ Out << "!{";
+ for (unsigned mi = 0, me = N->getNumElements(); mi != me; ++mi) {
+ const Value *Val = N->getElement(mi);
+ if (!Val)
+ Out << "null";
+ else {
+ TypePrinter->print(N->getElement(0)->getType(), Out);
+ Out << ' ';
+ WriteAsOperandInternal(Out, N->getElement(0), TypePrinter, Machine);
+ }
+ if (mi + 1 != me)
+ Out << ", ";
+ }
+ Out << '}';
+ return;
+ }
+
Out << '!' << Machine->getMetadataSlot(N);
return;
}
return;
}
+ if (V->getValueID() == Value::PseudoSourceValueVal ||
+ V->getValueID() == Value::FixedStackPseudoSourceValueVal) {
+ V->print(Out);
+ return;
+ }
+
char Prefix = '%';
int Slot;
if (Machine) {
TypePrinting TypePrinter;
AssemblyAnnotationWriter *AnnotationWriter;
std::vector<const Type*> NumberedTypes;
-
- // Each MDNode is assigned unique MetadataIDNo.
- std::map<const MDNode *, unsigned> MDNodes;
- unsigned MetadataIDNo;
+ DenseMap<unsigned, StringRef> MDNames;
public:
inline AssemblyWriter(formatted_raw_ostream &o, SlotTracker &Mac,
const Module *M,
AssemblyAnnotationWriter *AAW)
- : Out(o), Machine(Mac), TheModule(M), AnnotationWriter(AAW), MetadataIDNo(0) {
+ : Out(o), Machine(Mac), TheModule(M), AnnotationWriter(AAW) {
AddModuleTypesToPrinter(TypePrinter, NumberedTypes, M);
+ // FIXME: Provide MDPrinter
+ if (M) {
+ MetadataContext &TheMetadata = M->getContext().getMetadata();
+ SmallVector<std::pair<unsigned, StringRef>, 4> Names;
+ TheMetadata.getHandlerNames(Names);
+ for (SmallVector<std::pair<unsigned, StringRef>, 4>::iterator
+ I = Names.begin(),
+ E = Names.end(); I != E; ++I) {
+ MDNames[I->first] = I->second;
+ }
+ }
}
void write(const Module *M) { printModule(M); }
case GlobalValue::AvailableExternallyLinkage:
Out << "available_externally ";
break;
- case GlobalValue::GhostLinkage:
- llvm_unreachable("GhostLinkage not allowed in AsmWriter!");
+ // This is invalid syntax and just a debugging aid.
+ case GlobalValue::GhostLinkage: Out << "ghost "; break;
}
}
case CallingConv::ARM_APCS: Out << "arm_apcscc "; break;
case CallingConv::ARM_AAPCS: Out << "arm_aapcscc "; break;
case CallingConv::ARM_AAPCS_VFP:Out << "arm_aapcs_vfpcc "; break;
+ case CallingConv::MSP430_INTR: Out << "msp430_intrcc "; break;
default: Out << "cc" << F->getCallingConv() << " "; break;
}
writeOperand(BI.getSuccessor(1), true);
} else if (isa<SwitchInst>(I)) {
- // Special case switch statement to get formatting nice and correct...
+ // Special case switch instruction to get formatting nice and correct.
Out << ' ';
writeOperand(Operand , true);
Out << ", ";
writeOperand(I.getOperand(op+1), true);
}
Out << "\n ]";
+ } else if (isa<IndirectBrInst>(I)) {
+ // Special case indirectbr instruction to get formatting nice and correct.
+ Out << ' ';
+ writeOperand(Operand, true);
+ Out << ", [";
+
+ for (unsigned i = 1, e = I.getNumOperands(); i != e; ++i) {
+ if (i != 1)
+ Out << ", ";
+ writeOperand(I.getOperand(i), true);
+ }
+ Out << ']';
} else if (isa<PHINode>(I)) {
Out << ' ';
TypePrinter.print(I.getType(), Out);
case CallingConv::ARM_APCS: Out << " arm_apcscc "; break;
case CallingConv::ARM_AAPCS: Out << " arm_aapcscc "; break;
case CallingConv::ARM_AAPCS_VFP:Out << " arm_aapcs_vfpcc "; break;
+ case CallingConv::MSP430_INTR: Out << " msp430_intrcc "; break;
default: Out << " cc" << CI->getCallingConv(); break;
}
case CallingConv::ARM_APCS: Out << " arm_apcscc "; break;
case CallingConv::ARM_AAPCS: Out << " arm_aapcscc "; break;
case CallingConv::ARM_AAPCS_VFP:Out << " arm_aapcs_vfpcc "; break;
+ case CallingConv::MSP430_INTR: Out << " msp430_intrcc "; break;
default: Out << " cc" << II->getCallingConv(); break;
}
Out << " unwind ";
writeOperand(II->getUnwindDest(), true);
- } else if (const AllocationInst *AI = dyn_cast<AllocationInst>(&I)) {
+ } else if (const AllocaInst *AI = dyn_cast<AllocaInst>(&I)) {
Out << ' ';
TypePrinter.print(AI->getType()->getElementType(), Out);
if (!AI->getArraySize() || AI->isArrayAllocation()) {
Out << ", align " << cast<StoreInst>(I).getAlignment();
}
- // Print DebugInfo
- Metadata &TheMetadata = I.getContext().getMetadata();
- unsigned MDDbgKind = TheMetadata.getMDKind("dbg");
- if (const MDNode *Dbg = TheMetadata.getMD(MDDbgKind, &I))
- Out << ", dbg !" << Machine.getMetadataSlot(Dbg);
+ // Print Metadata info
+ if (!MDNames.empty()) {
+ MetadataContext &TheMetadata = I.getContext().getMetadata();
+ typedef SmallVector<std::pair<unsigned, TrackingVH<MDNode> >, 2> MDMapTy;
+ MDMapTy MDs;
+ TheMetadata.getMDs(&I, MDs);
+ for (MDMapTy::const_iterator MI = MDs.begin(), ME = MDs.end(); MI != ME;
+ ++MI)
+ Out << ", !" << MDNames[MI->first]
+ << " !" << Machine.getMetadataSlot(MI->second);
+ }
printInfoComment(I);
}
} else if (isa<InlineAsm>(this)) {
WriteAsOperand(OS, this, true, 0);
} else {
- llvm_unreachable("Unknown value to print out!");
+ // Otherwise we don't know what it is. Call the virtual function to
+ // allow a subclass to print itself.
+ printCustom(OS);
}
}
+// Value::printCustom - subclasses should override this to implement printing.
+void Value::printCustom(raw_ostream &OS) const {
+ llvm_unreachable("Unknown value to print out!");
+}
+
// Value::dump - allow easy printing of Values from the debugger.
void Value::dump() const { print(errs()); errs() << '\n'; }