#include "llvm/Assembly/Writer.h"
#include "llvm/Assembly/PrintModulePass.h"
-#include "llvm/Assembly/AsmAnnotationWriter.h"
+#include "llvm/Assembly/AssemblyAnnotationWriter.h"
+#include "llvm/LLVMContext.h"
#include "llvm/CallingConv.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/InlineAsm.h"
-#include "llvm/Instruction.h"
-#include "llvm/Instructions.h"
-#include "llvm/LLVMContext.h"
+#include "llvm/IntrinsicInst.h"
#include "llvm/Operator.h"
-#include "llvm/Metadata.h"
#include "llvm/Module.h"
#include "llvm/ValueSymbolTable.h"
#include "llvm/TypeSymbolTable.h"
#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/CFG.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/FormattedStream.h"
#include <algorithm>
#include <cctype>
-#include <map>
using namespace llvm;
+static cl::opt<bool>
+EnableDebugInfoComment("enable-debug-info-comment", cl::Hidden,
+ cl::desc("Enable debug info comments"));
+
+
// Make virtual table appear in this compilation unit.
AssemblyAnnotationWriter::~AssemblyAnnotationWriter() {}
const Function *M = I->getParent() ? I->getParent()->getParent() : 0;
return M ? M->getParent() : 0;
}
-
+
if (const GlobalValue *GV = dyn_cast<GlobalValue>(V))
return GV->getParent();
return 0;
// PrintEscapedString - Print each character of the specified string, escaping
// it if it is not printable or if it is an escape char.
-static void PrintEscapedString(const StringRef &Name,
- raw_ostream &Out) {
+static void PrintEscapedString(StringRef Name, raw_ostream &Out) {
for (unsigned i = 0, e = Name.size(); i != e; ++i) {
unsigned char C = Name[i];
if (isprint(C) && C != '\\' && C != '"')
/// PrintLLVMName - Turn the specified name into an 'LLVM name', which is either
/// prefixed with % (if the string only contains simple characters) or is
/// surrounded with ""'s (if it has special chars in it). Print it out.
-static void PrintLLVMName(raw_ostream &OS, const StringRef &Name,
- PrefixType Prefix) {
- assert(Name.data() && "Cannot get empty name!");
+static void PrintLLVMName(raw_ostream &OS, StringRef Name, PrefixType Prefix) {
+ assert(!Name.empty() && "Cannot get empty name!");
switch (Prefix) {
default: llvm_unreachable("Bad prefix!");
case NoPrefix: break;
// TypePrinting Class: Type printing machinery
//===----------------------------------------------------------------------===//
-static DenseMap<const Type *, std::string> &getTypeNamesMap(void *M) {
- return *static_cast<DenseMap<const Type *, std::string>*>(M);
-}
-
-void TypePrinting::clear() {
- getTypeNamesMap(TypeNames).clear();
-}
-
-bool TypePrinting::hasTypeName(const Type *Ty) const {
- return getTypeNamesMap(TypeNames).count(Ty);
-}
-
-void TypePrinting::addTypeName(const Type *Ty, const std::string &N) {
- getTypeNamesMap(TypeNames).insert(std::make_pair(Ty, N));
-}
-
-
-TypePrinting::TypePrinting() {
- TypeNames = new DenseMap<const Type *, std::string>();
-}
+/// TypePrinting - Type printing machinery.
+namespace {
+class TypePrinting {
+ DenseMap<const Type *, std::string> TypeNames;
+ TypePrinting(const TypePrinting &); // DO NOT IMPLEMENT
+ void operator=(const TypePrinting&); // DO NOT IMPLEMENT
+public:
+ TypePrinting() {}
+ ~TypePrinting() {}
+
+ void clear() {
+ TypeNames.clear();
+ }
+
+ void print(const Type *Ty, raw_ostream &OS, bool IgnoreTopLevelName = false);
+
+ void printAtLeastOneLevel(const Type *Ty, raw_ostream &OS) {
+ print(Ty, OS, true);
+ }
+
+ /// hasTypeName - Return true if the type has a name in TypeNames, false
+ /// otherwise.
+ bool hasTypeName(const Type *Ty) const {
+ return TypeNames.count(Ty);
+ }
-TypePrinting::~TypePrinting() {
- delete &getTypeNamesMap(TypeNames);
-}
+
+ /// addTypeName - Add a name for the specified type if it doesn't already have
+ /// one. This name will be printed instead of the structural version of the
+ /// type in order to make the output more concise.
+ void addTypeName(const Type *Ty, const std::string &N) {
+ TypeNames.insert(std::make_pair(Ty, N));
+ }
+
+private:
+ void CalcTypeName(const Type *Ty, SmallVectorImpl<const Type *> &TypeStack,
+ raw_ostream &OS, bool IgnoreTopLevelName = false);
+};
+} // end anonymous namespace.
/// CalcTypeName - Write the specified type to the specified raw_ostream, making
/// use of type names or up references to shorten the type name where possible.
raw_ostream &OS, bool IgnoreTopLevelName) {
// Check to see if the type is named.
if (!IgnoreTopLevelName) {
- DenseMap<const Type *, std::string> &TM = getTypeNamesMap(TypeNames);
+ DenseMap<const Type *, std::string> &TM = TypeNames;
DenseMap<const Type *, std::string>::iterator I = TM.find(Ty);
if (I != TM.end()) {
OS << I->second;
case Type::PPC_FP128TyID: OS << "ppc_fp128"; break;
case Type::LabelTyID: OS << "label"; break;
case Type::MetadataTyID: OS << "metadata"; break;
+ case Type::X86_MMXTyID: OS << "x86_mmx"; break;
case Type::IntegerTyID:
OS << 'i' << cast<IntegerType>(Ty)->getBitWidth();
break;
const StructType *STy = cast<StructType>(Ty);
if (STy->isPacked())
OS << '<';
- OS << "{ ";
+ OS << '{';
for (StructType::element_iterator I = STy->element_begin(),
E = STy->element_end(); I != E; ++I) {
+ OS << ' ';
CalcTypeName(*I, TypeStack, OS);
- if (next(I) != STy->element_end())
+ if (llvm::next(I) == STy->element_end())
+ OS << ' ';
+ else
OS << ',';
- OS << ' ';
}
OS << '}';
if (STy->isPacked())
void TypePrinting::print(const Type *Ty, raw_ostream &OS,
bool IgnoreTopLevelName) {
// Check to see if the type is named.
- DenseMap<const Type*, std::string> &TM = getTypeNamesMap(TypeNames);
if (!IgnoreTopLevelName) {
- DenseMap<const Type*, std::string>::iterator I = TM.find(Ty);
- if (I != TM.end()) {
+ DenseMap<const Type*, std::string>::iterator I = TypeNames.find(Ty);
+ if (I != TypeNames.end()) {
OS << I->second;
return;
}
// Cache type name for later use.
if (!IgnoreTopLevelName)
- TM.insert(std::make_pair(Ty, TypeOS.str()));
+ TypeNames.insert(std::make_pair(Ty, TypeOS.str()));
}
namespace {
return;
// If this is a structure or opaque type, add a name for the type.
- if (((isa<StructType>(Ty) && cast<StructType>(Ty)->getNumElements())
- || isa<OpaqueType>(Ty)) && !TP.hasTypeName(Ty)) {
+ if (((Ty->isStructTy() && cast<StructType>(Ty)->getNumElements())
+ || Ty->isOpaqueTy()) && !TP.hasTypeName(Ty)) {
TP.addTypeName(Ty, "%"+utostr(unsigned(NumberedTypes.size())));
NumberedTypes.push_back(Ty);
}
// they are used too often to have a single useful name.
if (const PointerType *PTy = dyn_cast<PointerType>(Ty)) {
const Type *PETy = PTy->getElementType();
- if ((PETy->isPrimitiveType() || PETy->isInteger()) &&
- !isa<OpaqueType>(PETy))
+ if ((PETy->isPrimitiveType() || PETy->isIntegerTy()) &&
+ !PETy->isOpaqueTy())
continue;
}
// Likewise don't insert primitives either.
- if (Ty->isInteger() || Ty->isPrimitiveType())
+ if (Ty->isIntegerTy() || Ty->isPrimitiveType())
continue;
// Get the name as a string and insert it into TypeNames.
const Function* TheFunction;
bool FunctionProcessed;
- /// TheMDNode - The MDNode for which we are holding slot numbers.
- const MDNode *TheMDNode;
-
- /// TheNamedMDNode - The MDNode for which we are holding slot numbers.
- const NamedMDNode *TheNamedMDNode;
-
/// mMap - The TypePlanes map for the module level data.
ValueMap mMap;
unsigned mNext;
unsigned fNext;
/// mdnMap - Map for MDNodes.
- ValueMap mdnMap;
+ DenseMap<const MDNode*, unsigned> mdnMap;
unsigned mdnNext;
public:
/// Construct from a module
explicit SlotTracker(const Module *M);
/// Construct from a function, starting out in incorp state.
explicit SlotTracker(const Function *F);
- /// Construct from a mdnode.
- explicit SlotTracker(const MDNode *N);
- /// Construct from a named mdnode.
- explicit SlotTracker(const NamedMDNode *N);
/// Return the slot number of the specified value in it's type
/// plane. If something is not in the SlotTracker, return -1.
void purgeFunction();
/// MDNode map iterators.
- ValueMap::iterator mdnBegin() { return mdnMap.begin(); }
- ValueMap::iterator mdnEnd() { return mdnMap.end(); }
- unsigned mdnSize() const { return mdnMap.size(); }
- bool mdnEmpty() const { return mdnMap.empty(); }
+ typedef DenseMap<const MDNode*, unsigned>::iterator mdn_iterator;
+ mdn_iterator mdn_begin() { return mdnMap.begin(); }
+ mdn_iterator mdn_end() { return mdnMap.end(); }
+ unsigned mdn_size() const { return mdnMap.size(); }
+ bool mdn_empty() const { return mdnMap.empty(); }
/// This function does the actual initialization.
inline void initialize();
/// Add all of the functions arguments, basic blocks, and instructions.
void processFunction();
- /// Add all MDNode operands.
- void processMDNode();
-
- /// Add all MDNode operands.
- void processNamedMDNode();
-
SlotTracker(const SlotTracker &); // DO NOT IMPLEMENT
void operator=(const SlotTracker &); // DO NOT IMPLEMENT
};
if (const Function *Func = dyn_cast<Function>(V))
return new SlotTracker(Func);
+ if (const MDNode *MD = dyn_cast<MDNode>(V)) {
+ if (!MD->isFunctionLocal())
+ return new SlotTracker(MD->getFunction());
+
+ return new SlotTracker((Function *)0);
+ }
+
return 0;
}
#if 0
-#define ST_DEBUG(X) errs() << X
+#define ST_DEBUG(X) dbgs() << X
#else
#define ST_DEBUG(X)
#endif
// Module level constructor. Causes the contents of the Module (sans functions)
// to be added to the slot table.
SlotTracker::SlotTracker(const Module *M)
- : TheModule(M), TheFunction(0), FunctionProcessed(false), TheMDNode(0),
- TheNamedMDNode(0), mNext(0), fNext(0), mdnNext(0) {
+ : TheModule(M), TheFunction(0), FunctionProcessed(false),
+ mNext(0), fNext(0), mdnNext(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),
- TheMDNode(0), TheNamedMDNode(0), mNext(0), fNext(0), mdnNext(0) {
-}
-
-// Constructor to handle single MDNode.
-SlotTracker::SlotTracker(const MDNode *C)
- : TheModule(0), TheFunction(0), FunctionProcessed(false), TheMDNode(C),
- TheNamedMDNode(0), mNext(0), fNext(0), mdnNext(0) {
-}
-
-// Constructor to handle single NamedMDNode.
-SlotTracker::SlotTracker(const NamedMDNode *N)
- : TheModule(0), TheFunction(0), FunctionProcessed(false), TheMDNode(0),
- TheNamedMDNode(N), mNext(0), fNext(0), mdnNext(0) {
+ mNext(0), fNext(0), mdnNext(0) {
}
inline void SlotTracker::initialize() {
if (TheFunction && !FunctionProcessed)
processFunction();
-
- if (TheMDNode)
- processMDNode();
-
- if (TheNamedMDNode)
- processNamedMDNode();
}
// Iterate through all the global variables, functions, and global
E = TheModule->global_end(); I != E; ++I) {
if (!I->hasName())
CreateModuleSlot(I);
- if (I->hasInitializer()) {
- if (MDNode *N = dyn_cast<MDNode>(I->getInitializer()))
- CreateMetadataSlot(N);
- }
}
// Add metadata used by named metadata.
I = TheModule->named_metadata_begin(),
E = TheModule->named_metadata_end(); I != E; ++I) {
const NamedMDNode *NMD = I;
- for (unsigned i = 0, e = NMD->getNumElements(); i != e; ++i) {
- MDNode *MD = dyn_cast_or_null<MDNode>(NMD->getElement(i));
- if (MD)
- CreateMetadataSlot(MD);
- }
+ for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i)
+ CreateMetadataSlot(NMD->getOperand(i));
}
// Add all the unnamed functions to the table.
ST_DEBUG("Inserting Instructions:\n");
- MetadataContext &TheMetadata = TheFunction->getContext().getMetadata();
- typedef SmallVector<std::pair<unsigned, MDNode*>, 2> MDMapTy;
- MDMapTy MDs;
+ SmallVector<std::pair<unsigned, MDNode*>, 4> MDForInst;
// Add all of the basic blocks and instructions with no names.
for (Function::const_iterator BB = TheFunction->begin(),
E = TheFunction->end(); BB != E; ++BB) {
if (!BB->hasName())
CreateFunctionSlot(BB);
+
for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E;
++I) {
- if (I->getType() != Type::getVoidTy(TheFunction->getContext()) &&
- !I->hasName())
+ if (!I->getType()->isVoidTy() && !I->hasName())
CreateFunctionSlot(I);
- for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i)
- if (MDNode *N = dyn_cast_or_null<MDNode>(I->getOperand(i)))
- CreateMetadataSlot(N);
+
+ // Intrinsics can directly use metadata. We allow direct calls to any
+ // llvm.foo function here, because the target may not be linked into the
+ // optimizer.
+ if (const CallInst *CI = dyn_cast<CallInst>(I)) {
+ if (Function *F = CI->getCalledFunction())
+ if (F->getName().startswith("llvm."))
+ for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i)
+ if (MDNode *N = dyn_cast_or_null<MDNode>(I->getOperand(i)))
+ CreateMetadataSlot(N);
+ }
// Process metadata attached with this instruction.
- MDs.clear();
- TheMetadata.getMDs(I, MDs);
- for (MDMapTy::const_iterator MI = MDs.begin(), ME = MDs.end(); MI != ME;
- ++MI)
- CreateMetadataSlot(MI->second);
+ I->getAllMetadata(MDForInst);
+ for (unsigned i = 0, e = MDForInst.size(); i != e; ++i)
+ CreateMetadataSlot(MDForInst[i].second);
+ MDForInst.clear();
}
}
ST_DEBUG("end processFunction!\n");
}
-/// processMDNode - Process TheMDNode.
-void SlotTracker::processMDNode() {
- ST_DEBUG("begin processMDNode!\n");
- mdnNext = 0;
- CreateMetadataSlot(TheMDNode);
- TheMDNode = 0;
- ST_DEBUG("end processMDNode!\n");
-}
-
-/// processNamedMDNode - Process TheNamedMDNode.
-void SlotTracker::processNamedMDNode() {
- ST_DEBUG("begin processNamedMDNode!\n");
- mdnNext = 0;
- for (unsigned i = 0, e = TheNamedMDNode->getNumElements(); i != e; ++i) {
- MDNode *MD = dyn_cast_or_null<MDNode>(TheNamedMDNode->getElement(i));
- if (MD)
- CreateMetadataSlot(MD);
- }
- TheNamedMDNode = 0;
- ST_DEBUG("end processNamedMDNode!\n");
-}
-
/// Clean up after incorporating a function. This is the only way to get out of
/// the function incorporation state that affects get*Slot/Create*Slot. Function
/// incorporation state is indicated by TheFunction != 0.
return MI == mMap.end() ? -1 : (int)MI->second;
}
-/// getGlobalSlot - Get the slot number of a MDNode.
+/// getMetadataSlot - Get the slot number of a MDNode.
int SlotTracker::getMetadataSlot(const MDNode *N) {
// Check for uninitialized state and do lazy initialization.
initialize();
// Find the type plane in the module map
- ValueMap::iterator MI = mdnMap.find(N);
+ mdn_iterator MI = mdnMap.find(N);
return MI == mdnMap.end() ? -1 : (int)MI->second;
}
/// CreateModuleSlot - Insert the specified GlobalValue* into the slot table.
void SlotTracker::CreateModuleSlot(const GlobalValue *V) {
assert(V && "Can't insert a null Value into SlotTracker!");
- assert(V->getType() != Type::getVoidTy(V->getContext()) &&
- "Doesn't need a slot!");
+ assert(!V->getType()->isVoidTy() && "Doesn't need a slot!");
assert(!V->hasName() && "Doesn't need a slot!");
unsigned DestSlot = mNext++;
/// CreateSlot - Create a new slot for the specified value if it has no name.
void SlotTracker::CreateFunctionSlot(const Value *V) {
- assert(V->getType() != Type::getVoidTy(TheFunction->getContext()) &&
- !V->hasName() && "Doesn't need a slot!");
+ assert(!V->getType()->isVoidTy() && !V->hasName() && "Doesn't need a slot!");
unsigned DestSlot = fNext++;
fMap[V] = DestSlot;
void SlotTracker::CreateMetadataSlot(const MDNode *N) {
assert(N && "Can't insert a null Value into SlotTracker!");
- // Don't insert if N is a function-local metadata.
- if (N->isFunctionLocal())
- return;
-
- ValueMap::iterator I = mdnMap.find(N);
- if (I != mdnMap.end())
- return;
-
- unsigned DestSlot = mdnNext++;
- mdnMap[N] = DestSlot;
+ // Don't insert if N is a function-local metadata, these are always printed
+ // inline.
+ if (!N->isFunctionLocal()) {
+ mdn_iterator I = mdnMap.find(N);
+ if (I != mdnMap.end())
+ return;
- 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);
+ unsigned DestSlot = mdnNext++;
+ mdnMap[N] = DestSlot;
}
+
+ // Recursively add any MDNodes referenced by operands.
+ for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i)
+ if (const MDNode *Op = dyn_cast_or_null<MDNode>(N->getOperand(i)))
+ CreateMetadataSlot(Op);
}
//===----------------------------------------------------------------------===//
static void WriteAsOperandInternal(raw_ostream &Out, const Value *V,
TypePrinting *TypePrinter,
- SlotTracker *Machine);
+ SlotTracker *Machine,
+ const Module *Context);
static const char *getPredicateText(unsigned predicate) {
const char * pred = "unknown";
switch (predicate) {
- case FCmpInst::FCMP_FALSE: pred = "false"; break;
- case FCmpInst::FCMP_OEQ: pred = "oeq"; break;
- case FCmpInst::FCMP_OGT: pred = "ogt"; break;
- case FCmpInst::FCMP_OGE: pred = "oge"; break;
- case FCmpInst::FCMP_OLT: pred = "olt"; break;
- case FCmpInst::FCMP_OLE: pred = "ole"; break;
- case FCmpInst::FCMP_ONE: pred = "one"; break;
- case FCmpInst::FCMP_ORD: pred = "ord"; break;
- case FCmpInst::FCMP_UNO: pred = "uno"; break;
- case FCmpInst::FCMP_UEQ: pred = "ueq"; break;
- case FCmpInst::FCMP_UGT: pred = "ugt"; break;
- case FCmpInst::FCMP_UGE: pred = "uge"; break;
- case FCmpInst::FCMP_ULT: pred = "ult"; break;
- case FCmpInst::FCMP_ULE: pred = "ule"; break;
- case FCmpInst::FCMP_UNE: pred = "une"; break;
- case FCmpInst::FCMP_TRUE: pred = "true"; break;
- case ICmpInst::ICMP_EQ: pred = "eq"; break;
- case ICmpInst::ICMP_NE: pred = "ne"; break;
- case ICmpInst::ICMP_SGT: pred = "sgt"; break;
- case ICmpInst::ICMP_SGE: pred = "sge"; break;
- case ICmpInst::ICMP_SLT: pred = "slt"; break;
- case ICmpInst::ICMP_SLE: pred = "sle"; break;
- case ICmpInst::ICMP_UGT: pred = "ugt"; break;
- case ICmpInst::ICMP_UGE: pred = "uge"; break;
- case ICmpInst::ICMP_ULT: pred = "ult"; break;
- case ICmpInst::ICMP_ULE: pred = "ule"; break;
+ case FCmpInst::FCMP_FALSE: pred = "false"; break;
+ case FCmpInst::FCMP_OEQ: pred = "oeq"; break;
+ case FCmpInst::FCMP_OGT: pred = "ogt"; break;
+ case FCmpInst::FCMP_OGE: pred = "oge"; break;
+ case FCmpInst::FCMP_OLT: pred = "olt"; break;
+ case FCmpInst::FCMP_OLE: pred = "ole"; break;
+ case FCmpInst::FCMP_ONE: pred = "one"; break;
+ case FCmpInst::FCMP_ORD: pred = "ord"; break;
+ case FCmpInst::FCMP_UNO: pred = "uno"; break;
+ case FCmpInst::FCMP_UEQ: pred = "ueq"; break;
+ case FCmpInst::FCMP_UGT: pred = "ugt"; break;
+ case FCmpInst::FCMP_UGE: pred = "uge"; break;
+ case FCmpInst::FCMP_ULT: pred = "ult"; break;
+ case FCmpInst::FCMP_ULE: pred = "ule"; break;
+ case FCmpInst::FCMP_UNE: pred = "une"; break;
+ case FCmpInst::FCMP_TRUE: pred = "true"; break;
+ case ICmpInst::ICMP_EQ: pred = "eq"; break;
+ case ICmpInst::ICMP_NE: pred = "ne"; break;
+ case ICmpInst::ICMP_SGT: pred = "sgt"; break;
+ case ICmpInst::ICMP_SGE: pred = "sge"; break;
+ case ICmpInst::ICMP_SLT: pred = "slt"; break;
+ case ICmpInst::ICMP_SLE: pred = "sle"; break;
+ case ICmpInst::ICMP_UGT: pred = "ugt"; break;
+ case ICmpInst::ICMP_UGE: pred = "uge"; break;
+ case ICmpInst::ICMP_ULT: pred = "ult"; break;
+ case ICmpInst::ICMP_ULE: pred = "ule"; break;
}
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;
- 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 (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 << "metadata ";
- Out << '!' << Machine.getMetadataSlot(N);
- }
- else {
- TypePrinter.print(V->getType(), Out);
- Out << ' ';
- WriteAsOperandInternal(Out, Node->getElement(mi),
- &TypePrinter, &Machine);
- }
- if (mi + 1 != me)
- Out << ", ";
- }
-
- Out << "}";
- WriteMDNodeComment(Node, Out);
- Out << "\n";
- }
-}
static void WriteOptimizationInfo(raw_ostream &Out, const User *U) {
if (const OverflowingBinaryOperator *OBO =
Out << " nuw";
if (OBO->hasNoSignedWrap())
Out << " nsw";
- } else if (const SDivOperator *Div = dyn_cast<SDivOperator>(U)) {
+ } else if (const PossiblyExactOperator *Div =
+ dyn_cast<PossiblyExactOperator>(U)) {
if (Div->isExact())
Out << " exact";
} else if (const GEPOperator *GEP = dyn_cast<GEPOperator>(U)) {
}
}
-static void WriteConstantInt(raw_ostream &Out, const Constant *CV,
- TypePrinting &TypePrinter, SlotTracker *Machine) {
+static void WriteConstantInternal(raw_ostream &Out, const Constant *CV,
+ TypePrinting &TypePrinter,
+ SlotTracker *Machine,
+ const Module *Context) {
if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
- if (CI->getType() == Type::getInt1Ty(CV->getContext())) {
+ if (CI->getType()->isIntegerTy(1)) {
Out << (CI->getZExtValue() ? "true" : "false");
return;
}
bool isDouble = &CFP->getValueAPF().getSemantics()==&APFloat::IEEEdouble;
double Val = isDouble ? CFP->getValueAPF().convertToDouble() :
CFP->getValueAPF().convertToFloat();
- std::string StrVal = ftostr(CFP->getValueAPF());
+ SmallString<128> StrVal;
+ raw_svector_ostream(StrVal) << Val;
// Check to make sure that the stringized number is not some string like
// "Inf" or NaN, that atof will accept, but the lexer will not. Check
(StrVal[1] >= '0' && StrVal[1] <= '9'))) {
// Reparse stringized version!
if (atof(StrVal.c_str()) == Val) {
- Out << StrVal;
+ Out << StrVal.str();
return;
}
}
if (const BlockAddress *BA = dyn_cast<BlockAddress>(CV)) {
Out << "blockaddress(";
- WriteAsOperandInternal(Out, BA->getFunction(), &TypePrinter, Machine);
+ WriteAsOperandInternal(Out, BA->getFunction(), &TypePrinter, Machine,
+ Context);
Out << ", ";
- WriteAsOperandInternal(Out, BA->getBasicBlock(), &TypePrinter, Machine);
+ WriteAsOperandInternal(Out, BA->getBasicBlock(), &TypePrinter, Machine,
+ Context);
Out << ")";
return;
}
TypePrinter.print(ETy, Out);
Out << ' ';
WriteAsOperandInternal(Out, CA->getOperand(0),
- &TypePrinter, Machine);
+ &TypePrinter, Machine,
+ Context);
for (unsigned i = 1, e = CA->getNumOperands(); i != e; ++i) {
Out << ", ";
TypePrinter.print(ETy, Out);
Out << ' ';
- WriteAsOperandInternal(Out, CA->getOperand(i), &TypePrinter, Machine);
+ WriteAsOperandInternal(Out, CA->getOperand(i), &TypePrinter, Machine,
+ Context);
}
}
Out << ']';
TypePrinter.print(CS->getOperand(0)->getType(), Out);
Out << ' ';
- WriteAsOperandInternal(Out, CS->getOperand(0), &TypePrinter, Machine);
+ WriteAsOperandInternal(Out, CS->getOperand(0), &TypePrinter, Machine,
+ Context);
for (unsigned i = 1; i < N; i++) {
Out << ", ";
TypePrinter.print(CS->getOperand(i)->getType(), Out);
Out << ' ';
- WriteAsOperandInternal(Out, CS->getOperand(i), &TypePrinter, Machine);
+ WriteAsOperandInternal(Out, CS->getOperand(i), &TypePrinter, Machine,
+ Context);
}
Out << ' ';
}
Out << '<';
TypePrinter.print(ETy, Out);
Out << ' ';
- WriteAsOperandInternal(Out, CP->getOperand(0), &TypePrinter, Machine);
+ WriteAsOperandInternal(Out, CP->getOperand(0), &TypePrinter, Machine,
+ Context);
for (unsigned i = 1, e = CP->getNumOperands(); i != e; ++i) {
Out << ", ";
TypePrinter.print(ETy, Out);
Out << ' ';
- WriteAsOperandInternal(Out, CP->getOperand(i), &TypePrinter, Machine);
+ WriteAsOperandInternal(Out, CP->getOperand(i), &TypePrinter, Machine,
+ Context);
}
Out << '>';
return;
return;
}
- if (const MDNode *Node = dyn_cast<MDNode>(CV)) {
- Out << "!" << Machine->getMetadataSlot(Node);
- return;
- }
-
if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV)) {
Out << CE->getOpcodeName();
WriteOptimizationInfo(Out, CE);
for (User::const_op_iterator OI=CE->op_begin(); OI != CE->op_end(); ++OI) {
TypePrinter.print((*OI)->getType(), Out);
Out << ' ';
- WriteAsOperandInternal(Out, *OI, &TypePrinter, Machine);
+ WriteAsOperandInternal(Out, *OI, &TypePrinter, Machine, Context);
if (OI+1 != CE->op_end())
Out << ", ";
}
if (CE->hasIndices()) {
- const SmallVector<unsigned, 4> &Indices = CE->getIndices();
+ ArrayRef<unsigned> Indices = CE->getIndices();
for (unsigned i = 0, e = Indices.size(); i != e; ++i)
Out << ", " << Indices[i];
}
Out << "<placeholder or erroneous Constant>";
}
+static void WriteMDNodeBodyInternal(raw_ostream &Out, const MDNode *Node,
+ TypePrinting *TypePrinter,
+ SlotTracker *Machine,
+ const Module *Context) {
+ Out << "!{";
+ for (unsigned mi = 0, me = Node->getNumOperands(); mi != me; ++mi) {
+ const Value *V = Node->getOperand(mi);
+ if (V == 0)
+ Out << "null";
+ else {
+ TypePrinter->print(V->getType(), Out);
+ Out << ' ';
+ WriteAsOperandInternal(Out, Node->getOperand(mi),
+ TypePrinter, Machine, Context);
+ }
+ if (mi + 1 != me)
+ Out << ", ";
+ }
+
+ Out << "}";
+}
+
/// WriteAsOperand - Write the name of the specified value out to the specified
/// ostream. This can be useful when you just want to print int %reg126, not
///
static void WriteAsOperandInternal(raw_ostream &Out, const Value *V,
TypePrinting *TypePrinter,
- SlotTracker *Machine) {
+ SlotTracker *Machine,
+ const Module *Context) {
if (V->hasName()) {
PrintLLVMName(Out, V);
return;
const Constant *CV = dyn_cast<Constant>(V);
if (CV && !isa<GlobalValue>(CV)) {
assert(TypePrinter && "Constants require TypePrinting!");
- WriteConstantInt(Out, CV, *TypePrinter, Machine);
+ WriteConstantInternal(Out, CV, *TypePrinter, Machine, Context);
return;
}
if (const MDNode *N = dyn_cast<MDNode>(V)) {
if (N->isFunctionLocal()) {
// 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 << '}';
+ WriteMDNodeBodyInternal(Out, N, TypePrinter, Machine, Context);
return;
}
- Out << '!' << Machine->getMetadataSlot(N);
+ if (!Machine) {
+ if (N->isFunctionLocal())
+ Machine = new SlotTracker(N->getFunction());
+ else
+ Machine = new SlotTracker(Context);
+ }
+ int Slot = Machine->getMetadataSlot(N);
+ if (Slot == -1)
+ Out << "<badref>";
+ else
+ Out << '!' << Slot;
return;
}
// Fast path: Don't construct and populate a TypePrinting object if we
// won't be needing any types printed.
if (!PrintType &&
- (!isa<Constant>(V) || V->hasName() || isa<GlobalValue>(V))) {
- WriteAsOperandInternal(Out, V, 0, 0);
+ ((!isa<Constant>(V) && !isa<MDNode>(V)) ||
+ V->hasName() || isa<GlobalValue>(V))) {
+ WriteAsOperandInternal(Out, V, 0, 0, Context);
return;
}
Out << ' ';
}
- WriteAsOperandInternal(Out, V, &TypePrinter, 0);
+ WriteAsOperandInternal(Out, V, &TypePrinter, 0, Context);
}
namespace {
TypePrinting TypePrinter;
AssemblyAnnotationWriter *AnnotationWriter;
std::vector<const Type*> NumberedTypes;
- SmallVector<StringRef, 8> MDNames;
public:
inline AssemblyWriter(formatted_raw_ostream &o, SlotTracker &Mac,
AssemblyAnnotationWriter *AAW)
: Out(o), Machine(Mac), TheModule(M), AnnotationWriter(AAW) {
AddModuleTypesToPrinter(TypePrinter, NumberedTypes, M);
- // FIXME: Provide MDPrinter
- if (M)
- M->getContext().getMetadata().getMDKindNames(MDNames);
- }
-
- void write(const Module *M) { printModule(M); }
-
- void write(const GlobalValue *G) {
- if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(G))
- printGlobal(GV);
- else if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(G))
- printAlias(GA);
- else if (const Function *F = dyn_cast<Function>(G))
- printFunction(F);
- else
- llvm_unreachable("Unknown global");
}
- void write(const BasicBlock *BB) { printBasicBlock(BB); }
- void write(const Instruction *I) { printInstruction(*I); }
+ void printMDNodeBody(const MDNode *MD);
+ void printNamedMDNode(const NamedMDNode *NMD);
+
+ void printModule(const Module *M);
void writeOperand(const Value *Op, bool PrintType);
void writeParamOperand(const Value *Operand, Attributes Attrs);
-private:
- void printModule(const Module *M);
+ void writeAllMDNodes();
+
void printTypeSymbolTable(const TypeSymbolTable &ST);
void printGlobal(const GlobalVariable *GV);
void printAlias(const GlobalAlias *GV);
void printBasicBlock(const BasicBlock *BB);
void printInstruction(const Instruction &I);
+private:
// printInfoComment - Print a little comment after the instruction indicating
// which slot it occupies.
void printInfoComment(const Value &V);
};
} // end of anonymous namespace
-
void AssemblyWriter::writeOperand(const Value *Operand, bool PrintType) {
if (Operand == 0) {
Out << "<null operand!>";
- } else {
- if (PrintType) {
- TypePrinter.print(Operand->getType(), Out);
- Out << ' ';
- }
- WriteAsOperandInternal(Out, Operand, &TypePrinter, &Machine);
+ return;
}
+ if (PrintType) {
+ TypePrinter.print(Operand->getType(), Out);
+ Out << ' ';
+ }
+ WriteAsOperandInternal(Out, Operand, &TypePrinter, &Machine, TheModule);
}
void AssemblyWriter::writeParamOperand(const Value *Operand,
Attributes Attrs) {
if (Operand == 0) {
Out << "<null operand!>";
- } else {
- // Print the type
- TypePrinter.print(Operand->getType(), Out);
- // Print parameter attributes list
- if (Attrs != Attribute::None)
- Out << ' ' << Attribute::getAsString(Attrs);
- Out << ' ';
- // Print the operand
- WriteAsOperandInternal(Out, Operand, &TypePrinter, &Machine);
+ return;
}
+
+ // Print the type
+ TypePrinter.print(Operand->getType(), Out);
+ // Print parameter attributes list
+ if (Attrs != Attribute::None)
+ Out << ' ' << Attribute::getAsString(Attrs);
+ Out << ' ';
+ // Print the operand
+ WriteAsOperandInternal(Out, Operand, &TypePrinter, &Machine, TheModule);
}
void AssemblyWriter::printModule(const Module *M) {
CurPos = NewLine+1;
NewLine = Asm.find_first_of('\n', CurPos);
}
- Out << "module asm \"";
- PrintEscapedString(std::string(Asm.begin()+CurPos, Asm.end()), Out);
- Out << "\"\n";
+ std::string rest(Asm.begin()+CurPos, Asm.end());
+ if (!rest.empty()) {
+ Out << "module asm \"";
+ PrintEscapedString(rest, Out);
+ Out << "\"\n";
+ }
}
// Loop over the dependent libraries and emit them.
// Output named metadata.
if (!M->named_metadata_empty()) Out << '\n';
+
for (Module::const_named_metadata_iterator I = M->named_metadata_begin(),
- E = M->named_metadata_end(); I != E; ++I) {
- const NamedMDNode *NMD = I;
- Out << "!" << NMD->getName() << " = !{";
- for (unsigned i = 0, e = NMD->getNumElements(); i != e; ++i) {
- if (i) Out << ", ";
- MDNode *MD = dyn_cast_or_null<MDNode>(NMD->getElement(i));
- Out << '!' << Machine.getMetadataSlot(MD);
- }
- Out << "}\n";
- }
+ E = M->named_metadata_end(); I != E; ++I)
+ printNamedMDNode(I);
// Output metadata.
- if (!Machine.mdnEmpty()) Out << '\n';
- WriteMDNodes(Out, TypePrinter, Machine);
+ if (!Machine.mdn_empty()) {
+ Out << '\n';
+ writeAllMDNodes();
+ }
+}
+
+void AssemblyWriter::printNamedMDNode(const NamedMDNode *NMD) {
+ Out << '!';
+ StringRef Name = NMD->getName();
+ if (Name.empty()) {
+ Out << "<empty name> ";
+ } else {
+ if (isalpha(Name[0]) || Name[0] == '-' || Name[0] == '$' ||
+ Name[0] == '.' || Name[0] == '_')
+ Out << Name[0];
+ else
+ Out << '\\' << hexdigit(Name[0] >> 4) << hexdigit(Name[0] & 0x0F);
+ for (unsigned i = 1, e = Name.size(); i != e; ++i) {
+ unsigned char C = Name[i];
+ if (isalnum(C) || C == '-' || C == '$' || C == '.' || C == '_')
+ Out << C;
+ else
+ Out << '\\' << hexdigit(C >> 4) << hexdigit(C & 0x0F);
+ }
+ }
+ Out << " = !{";
+ for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) {
+ if (i) Out << ", ";
+ int Slot = Machine.getMetadataSlot(NMD->getOperand(i));
+ if (Slot == -1)
+ Out << "<badref>";
+ else
+ Out << '!' << Slot;
+ }
+ Out << "}\n";
}
+
static void PrintLinkage(GlobalValue::LinkageTypes LT,
formatted_raw_ostream &Out) {
switch (LT) {
case GlobalValue::ExternalLinkage: break;
case GlobalValue::PrivateLinkage: Out << "private "; break;
case GlobalValue::LinkerPrivateLinkage: Out << "linker_private "; break;
+ case GlobalValue::LinkerPrivateWeakLinkage:
+ Out << "linker_private_weak ";
+ break;
+ case GlobalValue::LinkerPrivateWeakDefAutoLinkage:
+ Out << "linker_private_weak_def_auto ";
+ break;
case GlobalValue::InternalLinkage: Out << "internal "; break;
case GlobalValue::LinkOnceAnyLinkage: Out << "linkonce "; break;
case GlobalValue::LinkOnceODRLinkage: Out << "linkonce_odr "; break;
case GlobalValue::AvailableExternallyLinkage:
Out << "available_externally ";
break;
- // This is invalid syntax and just a debugging aid.
- case GlobalValue::GhostLinkage: Out << "ghost "; break;
}
}
static void PrintVisibility(GlobalValue::VisibilityTypes Vis,
formatted_raw_ostream &Out) {
switch (Vis) {
- default: llvm_unreachable("Invalid visibility style!");
case GlobalValue::DefaultVisibility: break;
case GlobalValue::HiddenVisibility: Out << "hidden "; break;
case GlobalValue::ProtectedVisibility: Out << "protected "; break;
}
void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
- WriteAsOperandInternal(Out, GV, &TypePrinter, &Machine);
+ if (GV->isMaterializable())
+ Out << "; Materializable\n";
+
+ WriteAsOperandInternal(Out, GV, &TypePrinter, &Machine, GV->getParent());
Out << " = ";
if (!GV->hasInitializer() && GV->hasExternalLinkage())
if (GV->isThreadLocal()) Out << "thread_local ";
if (unsigned AddressSpace = GV->getType()->getAddressSpace())
Out << "addrspace(" << AddressSpace << ") ";
+ if (GV->hasUnnamedAddr()) Out << "unnamed_addr ";
Out << (GV->isConstant() ? "constant " : "global ");
TypePrinter.print(GV->getType()->getElementType(), Out);
writeOperand(GV->getInitializer(), false);
}
- if (GV->hasSection())
- Out << ", section \"" << GV->getSection() << '"';
+ if (GV->hasSection()) {
+ Out << ", section \"";
+ PrintEscapedString(GV->getSection(), Out);
+ Out << '"';
+ }
if (GV->getAlignment())
Out << ", align " << GV->getAlignment();
}
void AssemblyWriter::printAlias(const GlobalAlias *GA) {
+ if (GA->isMaterializable())
+ Out << "; Materializable\n";
+
// Don't crash when dumping partially built GA
if (!GA->hasName())
Out << "<<nameless>> = ";
TypePrinter.print(F->getFunctionType(), Out);
Out << "* ";
- WriteAsOperandInternal(Out, F, &TypePrinter, &Machine);
+ WriteAsOperandInternal(Out, F, &TypePrinter, &Machine, F->getParent());
} else if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(Aliasee)) {
TypePrinter.print(GA->getType(), Out);
Out << ' ';
if (AnnotationWriter) AnnotationWriter->emitFunctionAnnot(F, Out);
+ if (F->isMaterializable())
+ Out << "; Materializable\n";
+
if (F->isDeclaration())
Out << "declare ";
else
case CallingConv::Cold: Out << "coldcc "; break;
case CallingConv::X86_StdCall: Out << "x86_stdcallcc "; break;
case CallingConv::X86_FastCall: Out << "x86_fastcallcc "; break;
+ case CallingConv::X86_ThisCall: Out << "x86_thiscallcc "; 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;
+ case CallingConv::PTX_Kernel: Out << "ptx_kernel "; break;
+ case CallingConv::PTX_Device: Out << "ptx_device "; break;
default: Out << "cc" << F->getCallingConv() << " "; break;
}
Out << Attribute::getAsString(Attrs.getRetAttributes()) << ' ';
TypePrinter.print(F->getReturnType(), Out);
Out << ' ';
- WriteAsOperandInternal(Out, F, &TypePrinter, &Machine);
+ WriteAsOperandInternal(Out, F, &TypePrinter, &Machine, F->getParent());
Out << '(';
Machine.incorporateFunction(F);
Out << "..."; // Output varargs portion of signature!
}
Out << ')';
+ if (F->hasUnnamedAddr())
+ Out << " unnamed_addr";
Attributes FnAttrs = Attrs.getFnAttributes();
if (FnAttrs != Attribute::None)
Out << ' ' << Attribute::getAsString(Attrs.getFnAttributes());
- if (F->hasSection())
- Out << " section \"" << F->getSection() << '"';
+ if (F->hasSection()) {
+ Out << " section \"";
+ PrintEscapedString(F->getSection(), Out);
+ Out << '"';
+ }
if (F->getAlignment())
Out << " align " << F->getAlignment();
if (F->hasGC())
Out << " gc \"" << F->getGC() << '"';
if (F->isDeclaration()) {
- Out << "\n";
+ Out << '\n';
} else {
Out << " {";
-
- // Output all of its basic blocks... for the function
+ // Output all of the function's basic blocks.
for (Function::const_iterator I = F->begin(), E = F->end(); I != E; ++I)
printBasicBlock(I);
Out.PadToColumn(50);
Out << "; Error: Block without parent!";
} else if (BB != &BB->getParent()->getEntryBlock()) { // Not the entry block?
- // Output predecessors for the block...
+ // Output predecessors for the block.
Out.PadToColumn(50);
Out << ";";
- pred_const_iterator PI = pred_begin(BB), PE = pred_end(BB);
+ const_pred_iterator PI = pred_begin(BB), PE = pred_end(BB);
if (PI == PE) {
Out << " No predecessors!";
if (AnnotationWriter) AnnotationWriter->emitBasicBlockEndAnnot(BB, Out);
}
+/// printDebugLoc - Print DebugLoc.
+static void printDebugLoc(const DebugLoc &DL, formatted_raw_ostream &OS) {
+ OS << DL.getLine() << ":" << DL.getCol();
+ if (MDNode *N = DL.getInlinedAt(getGlobalContext())) {
+ DebugLoc IDL = DebugLoc::getFromDILocation(N);
+ if (!IDL.isUnknown()) {
+ OS << "@";
+ printDebugLoc(IDL,OS);
+ }
+ }
+}
/// printInfoComment - Print a little comment after the instruction indicating
/// which slot it occupies.
///
void AssemblyWriter::printInfoComment(const Value &V) {
- if (V.getType() != Type::getVoidTy(V.getContext())) {
- Out.PadToColumn(50);
- Out << "; <";
- TypePrinter.print(V.getType(), Out);
- Out << "> [#uses=" << V.getNumUses() << ']'; // Output # uses
+ if (AnnotationWriter) {
+ AnnotationWriter->printInfoComment(V, Out);
+ return;
+ } else if (EnableDebugInfoComment) {
+ bool Padded = false;
+ if (const Instruction *I = dyn_cast<Instruction>(&V)) {
+ const DebugLoc &DL = I->getDebugLoc();
+ if (!DL.isUnknown()) {
+ if (!Padded) {
+ Out.PadToColumn(50);
+ Padded = true;
+ Out << ";";
+ }
+ Out << " [debug line = ";
+ printDebugLoc(DL,Out);
+ Out << "]";
+ }
+ if (const DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(I)) {
+ const MDNode *Var = DDI->getVariable();
+ if (!Padded) {
+ Out.PadToColumn(50);
+ Padded = true;
+ Out << ";";
+ }
+ if (Var && Var->getNumOperands() >= 2)
+ if (MDString *MDS = dyn_cast_or_null<MDString>(Var->getOperand(2)))
+ Out << " [debug variable = " << MDS->getString() << "]";
+ }
+ else if (const DbgValueInst *DVI = dyn_cast<DbgValueInst>(I)) {
+ const MDNode *Var = DVI->getVariable();
+ if (!Padded) {
+ Out.PadToColumn(50);
+ Padded = true;
+ Out << ";";
+ }
+ if (Var && Var->getNumOperands() >= 2)
+ if (MDString *MDS = dyn_cast_or_null<MDString>(Var->getOperand(2)))
+ Out << " [debug variable = " << MDS->getString() << "]";
+ }
+ }
}
}
if (I.hasName()) {
PrintLLVMName(Out, &I);
Out << " = ";
- } else if (I.getType() != Type::getVoidTy(I.getContext())) {
+ } else if (!I.getType()->isVoidTy()) {
// Print out the def slot taken.
int SlotNum = Machine.getLocalSlot(&I);
if (SlotNum == -1)
writeOperand(I.getOperand(i), true);
}
Out << ']';
- } else if (isa<PHINode>(I)) {
+ } else if (const PHINode *PN = dyn_cast<PHINode>(&I)) {
Out << ' ';
TypePrinter.print(I.getType(), Out);
Out << ' ';
- for (unsigned op = 0, Eop = I.getNumOperands(); op < Eop; op += 2) {
+ for (unsigned op = 0, Eop = PN->getNumIncomingValues(); op < Eop; ++op) {
if (op) Out << ", ";
Out << "[ ";
- writeOperand(I.getOperand(op ), false); Out << ", ";
- writeOperand(I.getOperand(op+1), false); Out << " ]";
+ writeOperand(PN->getIncomingValue(op), false); Out << ", ";
+ writeOperand(PN->getIncomingBlock(op), false); Out << " ]";
}
} else if (const ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(&I)) {
Out << ' ';
case CallingConv::Cold: Out << " coldcc"; break;
case CallingConv::X86_StdCall: Out << " x86_stdcallcc"; break;
case CallingConv::X86_FastCall: Out << " x86_fastcallcc"; break;
+ case CallingConv::X86_ThisCall: Out << " x86_thiscallcc"; 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;
+ case CallingConv::PTX_Kernel: Out << " ptx_kernel"; break;
+ case CallingConv::PTX_Device: Out << " ptx_device"; break;
default: Out << " cc" << CI->getCallingConv(); break;
}
+ Operand = CI->getCalledValue();
const PointerType *PTy = cast<PointerType>(Operand->getType());
const FunctionType *FTy = cast<FunctionType>(PTy->getElementType());
const Type *RetTy = FTy->getReturnType();
//
Out << ' ';
if (!FTy->isVarArg() &&
- (!isa<PointerType>(RetTy) ||
- !isa<FunctionType>(cast<PointerType>(RetTy)->getElementType()))) {
+ (!RetTy->isPointerTy() ||
+ !cast<PointerType>(RetTy)->getElementType()->isFunctionTy())) {
TypePrinter.print(RetTy, Out);
Out << ' ';
writeOperand(Operand, false);
writeOperand(Operand, true);
}
Out << '(';
- for (unsigned op = 1, Eop = I.getNumOperands(); op < Eop; ++op) {
- if (op > 1)
+ for (unsigned op = 0, Eop = CI->getNumArgOperands(); op < Eop; ++op) {
+ if (op > 0)
Out << ", ";
- writeParamOperand(I.getOperand(op), PAL.getParamAttributes(op));
+ writeParamOperand(CI->getArgOperand(op), PAL.getParamAttributes(op + 1));
}
Out << ')';
if (PAL.getFnAttributes() != Attribute::None)
Out << ' ' << Attribute::getAsString(PAL.getFnAttributes());
} else if (const InvokeInst *II = dyn_cast<InvokeInst>(&I)) {
+ Operand = II->getCalledValue();
const PointerType *PTy = cast<PointerType>(Operand->getType());
const FunctionType *FTy = cast<FunctionType>(PTy->getElementType());
const Type *RetTy = FTy->getReturnType();
case CallingConv::Cold: Out << " coldcc"; break;
case CallingConv::X86_StdCall: Out << " x86_stdcallcc"; break;
case CallingConv::X86_FastCall: Out << " x86_fastcallcc"; break;
+ case CallingConv::X86_ThisCall: Out << " x86_thiscallcc"; 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;
+ case CallingConv::PTX_Kernel: Out << " ptx_kernel"; break;
+ case CallingConv::PTX_Device: Out << " ptx_device"; break;
default: Out << " cc" << II->getCallingConv(); break;
}
//
Out << ' ';
if (!FTy->isVarArg() &&
- (!isa<PointerType>(RetTy) ||
- !isa<FunctionType>(cast<PointerType>(RetTy)->getElementType()))) {
+ (!RetTy->isPointerTy() ||
+ !cast<PointerType>(RetTy)->getElementType()->isFunctionTy())) {
TypePrinter.print(RetTy, Out);
Out << ' ';
writeOperand(Operand, false);
writeOperand(Operand, true);
}
Out << '(';
- for (unsigned op = 3, Eop = I.getNumOperands(); op < Eop; ++op) {
- if (op > 3)
+ for (unsigned op = 0, Eop = II->getNumArgOperands(); op < Eop; ++op) {
+ if (op)
Out << ", ";
- writeParamOperand(I.getOperand(op), PAL.getParamAttributes(op-2));
+ writeParamOperand(II->getArgOperand(op), PAL.getParamAttributes(op + 1));
}
Out << ')';
}
// Print Metadata info.
- if (!MDNames.empty()) {
- MetadataContext &TheMetadata = I.getContext().getMetadata();
- typedef SmallVector<std::pair<unsigned, 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);
+ SmallVector<std::pair<unsigned, MDNode*>, 4> InstMD;
+ I.getAllMetadata(InstMD);
+ if (!InstMD.empty()) {
+ SmallVector<StringRef, 8> MDNames;
+ I.getType()->getContext().getMDKindNames(MDNames);
+ for (unsigned i = 0, e = InstMD.size(); i != e; ++i) {
+ unsigned Kind = InstMD[i].first;
+ if (Kind < MDNames.size()) {
+ Out << ", !" << MDNames[Kind];
+ } else {
+ Out << ", !<unknown kind #" << Kind << ">";
+ }
+ Out << ' ';
+ WriteAsOperandInternal(Out, InstMD[i].second, &TypePrinter, &Machine,
+ TheModule);
+ }
}
printInfoComment(I);
}
+static void WriteMDNodeComment(const MDNode *Node,
+ formatted_raw_ostream &Out) {
+ if (Node->getNumOperands() < 1)
+ return;
+ ConstantInt *CI = dyn_cast_or_null<ConstantInt>(Node->getOperand(0));
+ if (!CI) return;
+ APInt Val = CI->getValue();
+ APInt Tag = Val & ~APInt(Val.getBitWidth(), LLVMDebugVersionMask);
+ if (Val.ult(LLVMDebugVersion))
+ return;
+
+ Out.PadToColumn(50);
+ if (Tag == dwarf::DW_TAG_user_base)
+ Out << "; [ DW_TAG_user_base ]";
+ else if (Tag.isIntN(32)) {
+ if (const char *TagName = dwarf::TagString(Tag.getZExtValue()))
+ Out << "; [ " << TagName << " ]";
+ }
+}
+
+void AssemblyWriter::writeAllMDNodes() {
+ SmallVector<const MDNode *, 16> Nodes;
+ Nodes.resize(Machine.mdn_size());
+ for (SlotTracker::mdn_iterator I = Machine.mdn_begin(), E = Machine.mdn_end();
+ I != E; ++I)
+ Nodes[I->second] = cast<MDNode>(I->first);
+
+ for (unsigned i = 0, e = Nodes.size(); i != e; ++i) {
+ Out << '!' << i << " = metadata ";
+ printMDNodeBody(Nodes[i]);
+ }
+}
+
+void AssemblyWriter::printMDNodeBody(const MDNode *Node) {
+ WriteMDNodeBodyInternal(Out, Node, &TypePrinter, &Machine, TheModule);
+ WriteMDNodeComment(Node, Out);
+ Out << "\n";
+}
//===----------------------------------------------------------------------===//
// External Interface declarations
SlotTracker SlotTable(this);
formatted_raw_ostream OS(ROS);
AssemblyWriter W(OS, SlotTable, this, AAW);
- W.write(this);
+ W.printModule(this);
+}
+
+void NamedMDNode::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW) const {
+ SlotTracker SlotTable(getParent());
+ formatted_raw_ostream OS(ROS);
+ AssemblyWriter W(OS, SlotTable, getParent(), AAW);
+ W.printNamedMDNode(this);
}
void Type::print(raw_ostream &OS) const {
if (const Instruction *I = dyn_cast<Instruction>(this)) {
const Function *F = I->getParent() ? I->getParent()->getParent() : 0;
SlotTracker SlotTable(F);
- AssemblyWriter W(OS, SlotTable, F ? F->getParent() : 0, AAW);
- W.write(I);
+ AssemblyWriter W(OS, SlotTable, getModuleFromVal(I), AAW);
+ W.printInstruction(*I);
} else if (const BasicBlock *BB = dyn_cast<BasicBlock>(this)) {
SlotTracker SlotTable(BB->getParent());
- AssemblyWriter W(OS, SlotTable,
- BB->getParent() ? BB->getParent()->getParent() : 0, AAW);
- W.write(BB);
+ AssemblyWriter W(OS, SlotTable, getModuleFromVal(BB), AAW);
+ W.printBasicBlock(BB);
} else if (const GlobalValue *GV = dyn_cast<GlobalValue>(this)) {
SlotTracker SlotTable(GV->getParent());
AssemblyWriter W(OS, SlotTable, GV->getParent(), AAW);
- W.write(GV);
- } else if (const MDString *MDS = dyn_cast<MDString>(this)) {
- TypePrinting TypePrinter;
- TypePrinter.print(MDS->getType(), OS);
- OS << ' ';
- OS << "!\"";
- PrintEscapedString(MDS->getString(), OS);
- OS << '"';
+ if (const GlobalVariable *V = dyn_cast<GlobalVariable>(GV))
+ W.printGlobal(V);
+ else if (const Function *F = dyn_cast<Function>(GV))
+ W.printFunction(F);
+ else
+ W.printAlias(cast<GlobalAlias>(GV));
} else if (const MDNode *N = dyn_cast<MDNode>(this)) {
- SlotTracker SlotTable(N);
- TypePrinting TypePrinter;
- SlotTable.initialize();
- WriteMDNodes(OS, TypePrinter, SlotTable);
- } else if (const NamedMDNode *N = dyn_cast<NamedMDNode>(this)) {
- SlotTracker SlotTable(N);
- TypePrinting TypePrinter;
- SlotTable.initialize();
- OS << "!" << N->getName() << " = !{";
- for (unsigned i = 0, e = N->getNumElements(); i != e; ++i) {
- if (i) OS << ", ";
- MDNode *MD = dyn_cast_or_null<MDNode>(N->getElement(i));
- if (MD)
- OS << '!' << SlotTable.getMetadataSlot(MD);
- else
- OS << "null";
- }
- OS << "}\n";
- WriteMDNodes(OS, TypePrinter, SlotTable);
+ const Function *F = N->getFunction();
+ SlotTracker SlotTable(F);
+ AssemblyWriter W(OS, SlotTable, F ? F->getParent() : 0, AAW);
+ W.printMDNodeBody(N);
} else if (const Constant *C = dyn_cast<Constant>(this)) {
TypePrinting TypePrinter;
TypePrinter.print(C->getType(), OS);
OS << ' ';
- WriteConstantInt(OS, C, TypePrinter, 0);
- } else if (const Argument *A = dyn_cast<Argument>(this)) {
- WriteAsOperand(OS, this, true,
- A->getParent() ? A->getParent()->getParent() : 0);
- } else if (isa<InlineAsm>(this)) {
+ WriteConstantInternal(OS, C, TypePrinter, 0, 0);
+ } else if (isa<InlineAsm>(this) || isa<MDString>(this) ||
+ isa<Argument>(this)) {
WriteAsOperand(OS, this, true, 0);
} else {
// Otherwise we don't know what it is. Call the virtual function to
}
// Value::dump - allow easy printing of Values from the debugger.
-void Value::dump() const { print(errs()); errs() << '\n'; }
+void Value::dump() const { print(dbgs()); dbgs() << '\n'; }
// Type::dump - allow easy printing of Types from the debugger.
// This one uses type names from the given context module
void Type::dump(const Module *Context) const {
- WriteTypeSymbolic(errs(), this, Context);
- errs() << '\n';
+ WriteTypeSymbolic(dbgs(), this, Context);
+ dbgs() << '\n';
}
// Type::dump - allow easy printing of Types from the debugger.
void Type::dump() const { dump(0); }
// Module::dump() - Allow printing of Modules from the debugger.
-void Module::dump() const { print(errs(), 0); }
+void Module::dump() const { print(dbgs(), 0); }