#include "llvm/LLVMContext.h"
#include "llvm/CallingConv.h"
#include "llvm/Constants.h"
+#include "llvm/DebugInfo.h"
#include "llvm/DerivedTypes.h"
#include "llvm/InlineAsm.h"
#include "llvm/IntrinsicInst.h"
#include "llvm/Operator.h"
#include "llvm/Module.h"
+#include "llvm/TypeFinder.h"
#include "llvm/ValueSymbolTable.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallString.h"
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;
}
+static void PrintCallingConv(unsigned cc, raw_ostream &Out)
+{
+ switch (cc) {
+ case CallingConv::Fast: Out << "fastcc"; break;
+ 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::Intel_OCL_BI: Out << "intel_ocl_bicc"; 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" << cc; break;
+ }
+}
+
// 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(StringRef Name, raw_ostream &Out) {
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;
case GlobalPrefix: OS << '@'; break;
case LabelPrefix: break;
bool NeedsQuotes = isdigit(Name[0]);
if (!NeedsQuotes) {
for (unsigned i = 0, e = Name.size(); i != e; ++i) {
- char C = Name[i];
+ // By making this unsigned, the value passed in to isalnum will always be
+ // in the range 0-255. This is important when building with MSVC because
+ // its implementation will assert. This situation can arise when dealing
+ // with UTF-8 multibyte characters.
+ unsigned char C = Name[i];
if (!isalnum(C) && C != '-' && C != '.' && C != '_') {
NeedsQuotes = true;
break;
/// TypePrinting - Type printing machinery.
namespace {
class TypePrinting {
- TypePrinting(const TypePrinting &); // DO NOT IMPLEMENT
- void operator=(const TypePrinting&); // DO NOT IMPLEMENT
+ TypePrinting(const TypePrinting &) LLVM_DELETED_FUNCTION;
+ void operator=(const TypePrinting&) LLVM_DELETED_FUNCTION;
public:
/// NamedTypes - The named types that are used by the current module.
- std::vector<StructType*> NamedTypes;
-
+ TypeFinder NamedTypes;
+
/// NumberedTypes - The numbered types, along with their value.
DenseMap<StructType*, unsigned> NumberedTypes;
-
+
TypePrinting() {}
~TypePrinting() {}
-
+
void incorporateTypes(const Module &M);
-
+
void print(Type *Ty, raw_ostream &OS);
-
+
void printStructBody(StructType *Ty, raw_ostream &OS);
};
} // end anonymous namespace.
void TypePrinting::incorporateTypes(const Module &M) {
- M.findUsedStructTypes(NamedTypes);
-
+ NamedTypes.run(M, false);
+
// The list of struct types we got back includes all the struct types, split
// the unnamed ones out to a numbering and remove the anonymous structs.
unsigned NextNumber = 0;
-
+
std::vector<StructType*>::iterator NextToUse = NamedTypes.begin(), I, E;
for (I = NamedTypes.begin(), E = NamedTypes.end(); I != E; ++I) {
StructType *STy = *I;
-
+
// Ignore anonymous types.
- if (STy->isAnonymous())
+ if (STy->isLiteral())
continue;
-
+
if (STy->getName().empty())
NumberedTypes[STy] = NextNumber++;
else
*NextToUse++ = STy;
}
-
+
NamedTypes.erase(NextToUse, NamedTypes.end());
}
void TypePrinting::print(Type *Ty, raw_ostream &OS) {
switch (Ty->getTypeID()) {
case Type::VoidTyID: OS << "void"; break;
+ case Type::HalfTyID: OS << "half"; break;
case Type::FloatTyID: OS << "float"; break;
case Type::DoubleTyID: OS << "double"; break;
case Type::X86_FP80TyID: OS << "x86_fp80"; break;
}
case Type::StructTyID: {
StructType *STy = cast<StructType>(Ty);
-
- if (STy->isAnonymous())
+
+ if (STy->isLiteral())
return printStructBody(STy, OS);
if (!STy->getName().empty())
return PrintLLVMName(OS, STy->getName(), LocalPrefix);
-
+
DenseMap<StructType*, unsigned>::iterator I = NumberedTypes.find(STy);
if (I != NumberedTypes.end())
OS << '%' << I->second;
else // Not enumerated, print the hex address.
- OS << "%\"type 0x" << STy << '\"';
+ OS << "%\"type " << STy << '\"';
return;
}
case Type::PointerTyID: {
OS << "opaque";
return;
}
-
+
if (STy->isPacked())
OS << '<';
-
+
if (STy->getNumElements() == 0) {
OS << "{}";
} else {
OS << ", ";
print(*I, OS);
}
-
+
OS << " }";
}
if (STy->isPacked())
/// Add all of the functions arguments, basic blocks, and instructions.
void processFunction();
- SlotTracker(const SlotTracker &); // DO NOT IMPLEMENT
- void operator=(const SlotTracker &); // DO NOT IMPLEMENT
+ SlotTracker(const SlotTracker &) LLVM_DELETED_FUNCTION;
+ void operator=(const SlotTracker &) LLVM_DELETED_FUNCTION;
};
} // end anonymous namespace
return new SlotTracker(FA->getParent());
if (const Instruction *I = dyn_cast<Instruction>(V))
- return new SlotTracker(I->getParent()->getParent());
+ if (I->getParent())
+ return new SlotTracker(I->getParent()->getParent());
if (const BasicBlock *BB = dyn_cast<BasicBlock>(V))
return new SlotTracker(BB->getParent());
// 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),
+ : TheModule(M), TheFunction(0), FunctionProcessed(false),
mNext(0), fNext(0), mdnNext(0) {
}
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()->isVoidTy() && !I->hasName())
CreateFunctionSlot(I);
-
+
// 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 ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) {
- if (&CFP->getValueAPF().getSemantics() == &APFloat::IEEEdouble ||
- &CFP->getValueAPF().getSemantics() == &APFloat::IEEEsingle) {
+ if (&CFP->getValueAPF().getSemantics() == &APFloat::IEEEsingle ||
+ &CFP->getValueAPF().getSemantics() == &APFloat::IEEEdouble) {
// We would like to output the FP constant value in exponential notation,
// but we cannot do this if doing so will lose precision. Check here to
// make sure that we only output it in exponential format if we can parse
// the value back and get the same value.
//
bool ignored;
+ bool isHalf = &CFP->getValueAPF().getSemantics()==&APFloat::IEEEhalf;
bool isDouble = &CFP->getValueAPF().getSemantics()==&APFloat::IEEEdouble;
- double Val = isDouble ? CFP->getValueAPF().convertToDouble() :
- CFP->getValueAPF().convertToFloat();
- 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
- // that the string matches the "[-+]?[0-9]" regex.
- //
- if ((StrVal[0] >= '0' && StrVal[0] <= '9') ||
- ((StrVal[0] == '-' || StrVal[0] == '+') &&
- (StrVal[1] >= '0' && StrVal[1] <= '9'))) {
- // Reparse stringized version!
- if (atof(StrVal.c_str()) == Val) {
- Out << StrVal.str();
- return;
+ bool isInf = CFP->getValueAPF().isInfinity();
+ bool isNaN = CFP->getValueAPF().isNaN();
+ if (!isHalf && !isInf && !isNaN) {
+ double Val = isDouble ? CFP->getValueAPF().convertToDouble() :
+ CFP->getValueAPF().convertToFloat();
+ 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
+ // that the string matches the "[-+]?[0-9]" regex.
+ //
+ if ((StrVal[0] >= '0' && StrVal[0] <= '9') ||
+ ((StrVal[0] == '-' || StrVal[0] == '+') &&
+ (StrVal[1] >= '0' && StrVal[1] <= '9'))) {
+ // Reparse stringized version!
+ if (APFloat(APFloat::IEEEdouble, StrVal).convertToDouble() == Val) {
+ Out << StrVal.str();
+ return;
+ }
}
}
// Otherwise we could not reparse it to exactly the same value, so we must
"assuming that double is 64 bits!");
char Buffer[40];
APFloat apf = CFP->getValueAPF();
- // Floats are represented in ASCII IR as double, convert.
+ // Halves and floats are represented in ASCII IR as double, convert.
if (!isDouble)
apf.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven,
&ignored);
return;
}
- // Some form of long double. These appear as a magic letter identifying
- // the type, then a fixed number of hex digits.
+ // Either half, or some form of long double.
+ // These appear as a magic letter identifying the type, then a
+ // fixed number of hex digits.
Out << "0x";
+ // Bit position, in the current word, of the next nibble to print.
+ int shiftcount;
+
if (&CFP->getValueAPF().getSemantics() == &APFloat::x87DoubleExtended) {
Out << 'K';
// api needed to prevent premature destruction
APInt api = CFP->getValueAPF().bitcastToAPInt();
const uint64_t* p = api.getRawData();
uint64_t word = p[1];
- int shiftcount=12;
+ shiftcount = 12;
int width = api.getBitWidth();
for (int j=0; j<width; j+=4, shiftcount-=4) {
unsigned int nibble = (word>>shiftcount) & 15;
}
}
return;
- } else if (&CFP->getValueAPF().getSemantics() == &APFloat::IEEEquad)
+ } else if (&CFP->getValueAPF().getSemantics() == &APFloat::IEEEquad) {
+ shiftcount = 60;
Out << 'L';
- else if (&CFP->getValueAPF().getSemantics() == &APFloat::PPCDoubleDouble)
+ } else if (&CFP->getValueAPF().getSemantics() == &APFloat::PPCDoubleDouble) {
+ shiftcount = 60;
Out << 'M';
- else
+ } else if (&CFP->getValueAPF().getSemantics() == &APFloat::IEEEhalf) {
+ shiftcount = 12;
+ Out << 'H';
+ } else
llvm_unreachable("Unsupported floating point type");
// api needed to prevent premature destruction
APInt api = CFP->getValueAPF().bitcastToAPInt();
const uint64_t* p = api.getRawData();
uint64_t word = *p;
- int shiftcount=60;
int width = api.getBitWidth();
for (int j=0; j<width; j+=4, shiftcount-=4) {
unsigned int nibble = (word>>shiftcount) & 15;
Out << "zeroinitializer";
return;
}
-
+
if (const BlockAddress *BA = dyn_cast<BlockAddress>(CV)) {
Out << "blockaddress(";
WriteAsOperandInternal(Out, BA->getFunction(), &TypePrinter, Machine,
}
if (const ConstantArray *CA = dyn_cast<ConstantArray>(CV)) {
+ Type *ETy = CA->getType()->getElementType();
+ Out << '[';
+ TypePrinter.print(ETy, Out);
+ Out << ' ';
+ WriteAsOperandInternal(Out, CA->getOperand(0),
+ &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,
+ Context);
+ }
+ Out << ']';
+ return;
+ }
+
+ if (const ConstantDataArray *CA = dyn_cast<ConstantDataArray>(CV)) {
// As a special case, print the array as a string if it is an array of
// i8 with ConstantInt values.
- //
- Type *ETy = CA->getType()->getElementType();
if (CA->isString()) {
Out << "c\"";
PrintEscapedString(CA->getAsString(), Out);
Out << '"';
- } else { // Cannot output in string format...
- Out << '[';
- if (CA->getNumOperands()) {
- TypePrinter.print(ETy, Out);
- Out << ' ';
- WriteAsOperandInternal(Out, CA->getOperand(0),
- &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,
- Context);
- }
- }
- Out << ']';
+ return;
}
+
+ Type *ETy = CA->getType()->getElementType();
+ Out << '[';
+ TypePrinter.print(ETy, Out);
+ Out << ' ';
+ WriteAsOperandInternal(Out, CA->getElementAsConstant(0),
+ &TypePrinter, Machine,
+ Context);
+ for (unsigned i = 1, e = CA->getNumElements(); i != e; ++i) {
+ Out << ", ";
+ TypePrinter.print(ETy, Out);
+ Out << ' ';
+ WriteAsOperandInternal(Out, CA->getElementAsConstant(i), &TypePrinter,
+ Machine, Context);
+ }
+ Out << ']';
return;
}
+
if (const ConstantStruct *CS = dyn_cast<ConstantStruct>(CV)) {
if (CS->getType()->isPacked())
Out << '<';
return;
}
- if (const ConstantVector *CP = dyn_cast<ConstantVector>(CV)) {
- Type *ETy = CP->getType()->getElementType();
- assert(CP->getNumOperands() > 0 &&
- "Number of operands for a PackedConst must be > 0");
+ if (isa<ConstantVector>(CV) || isa<ConstantDataVector>(CV)) {
+ Type *ETy = CV->getType()->getVectorElementType();
Out << '<';
TypePrinter.print(ETy, Out);
Out << ' ';
- WriteAsOperandInternal(Out, CP->getOperand(0), &TypePrinter, Machine,
- Context);
- for (unsigned i = 1, e = CP->getNumOperands(); i != e; ++i) {
+ WriteAsOperandInternal(Out, CV->getAggregateElement(0U), &TypePrinter,
+ Machine, Context);
+ for (unsigned i = 1, e = CV->getType()->getVectorNumElements(); i != e;++i){
Out << ", ";
TypePrinter.print(ETy, Out);
Out << ' ';
- WriteAsOperandInternal(Out, CP->getOperand(i), &TypePrinter, Machine,
- Context);
+ WriteAsOperandInternal(Out, CV->getAggregateElement(i), &TypePrinter,
+ Machine, Context);
}
Out << '>';
return;
else {
TypePrinter->print(V->getType(), Out);
Out << ' ';
- WriteAsOperandInternal(Out, Node->getOperand(mi),
+ WriteAsOperandInternal(Out, Node->getOperand(mi),
TypePrinter, Machine, Context);
}
if (mi + 1 != me)
Out << ", ";
}
-
+
Out << "}";
}
Out << "sideeffect ";
if (IA->isAlignStack())
Out << "alignstack ";
+ // We don't emit the AD_ATT dialect as it's the assumed default.
+ if (IA->getDialect() == InlineAsm::AD_Intel)
+ Out << "inteldialect ";
Out << '"';
PrintEscapedString(IA->getAsmString(), Out);
Out << "\", \"";
WriteMDNodeBodyInternal(Out, N, TypePrinter, Machine, Context);
return;
}
-
+
if (!Machine) {
if (N->isFunctionLocal())
Machine = new SlotTracker(N->getFunction());
char Prefix = '%';
int Slot;
+ // If we have a SlotTracker, use it.
if (Machine) {
if (const GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
Slot = Machine->getGlobalSlot(GV);
Prefix = '@';
} else {
Slot = Machine->getLocalSlot(V);
+
+ // If the local value didn't succeed, then we may be referring to a value
+ // from a different function. Translate it, as this can happen when using
+ // address of blocks.
+ if (Slot == -1)
+ if ((Machine = createSlotTracker(V))) {
+ Slot = Machine->getLocalSlot(V);
+ delete Machine;
+ }
}
- } else {
- Machine = createSlotTracker(V);
- if (Machine) {
- if (const GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
- Slot = Machine->getGlobalSlot(GV);
- Prefix = '@';
- } else {
- Slot = Machine->getLocalSlot(V);
- }
- delete Machine;
+ } else if ((Machine = createSlotTracker(V))) {
+ // Otherwise, create one to get the # and then destroy it.
+ if (const GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
+ Slot = Machine->getGlobalSlot(GV);
+ Prefix = '@';
} else {
- Slot = -1;
+ Slot = Machine->getLocalSlot(V);
}
+ delete Machine;
+ Machine = 0;
+ } else {
+ Slot = -1;
}
if (Slot != -1)
const Module *TheModule;
TypePrinting TypePrinter;
AssemblyAnnotationWriter *AnnotationWriter;
-
+
public:
inline AssemblyWriter(formatted_raw_ostream &o, SlotTracker &Mac,
const Module *M,
void printMDNodeBody(const MDNode *MD);
void printNamedMDNode(const NamedMDNode *NMD);
-
+
void printModule(const Module *M);
void writeOperand(const Value *Op, bool PrintType);
return;
switch (SynchScope) {
- default: Out << " <bad scope " << int(SynchScope) << ">"; break;
case SingleThread: Out << " singlethread"; break;
case CrossThread: break;
}
// Print the type
TypePrinter.print(Operand->getType(), Out);
// Print parameter attributes list
- if (Attrs != Attribute::None)
- Out << ' ' << Attribute::getAsString(Attrs);
+ if (Attrs.hasAttributes())
+ Out << ' ' << Attrs.getAsString();
Out << ' ';
// Print the operand
WriteAsOperandInternal(Out, Operand, &TypePrinter, &Machine, TheModule);
// Output all globals.
if (!M->global_empty()) Out << '\n';
for (Module::const_global_iterator I = M->global_begin(), E = M->global_end();
- I != E; ++I)
- printGlobal(I);
+ I != E; ++I) {
+ printGlobal(I); Out << '\n';
+ }
// Output all aliases.
if (!M->alias_empty()) Out << "\n";
// 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)
printNamedMDNode(I);
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::LinkOnceODRAutoHideLinkage:
+ Out << "linkonce_odr_auto_hide ";
+ break;
case GlobalValue::WeakAnyLinkage: Out << "weak "; break;
case GlobalValue::WeakODRLinkage: Out << "weak_odr "; break;
case GlobalValue::CommonLinkage: Out << "common "; break;
}
}
+static void PrintThreadLocalModel(GlobalVariable::ThreadLocalMode TLM,
+ formatted_raw_ostream &Out) {
+ switch (TLM) {
+ case GlobalVariable::NotThreadLocal:
+ break;
+ case GlobalVariable::GeneralDynamicTLSModel:
+ Out << "thread_local ";
+ break;
+ case GlobalVariable::LocalDynamicTLSModel:
+ Out << "thread_local(localdynamic) ";
+ break;
+ case GlobalVariable::InitialExecTLSModel:
+ Out << "thread_local(initialexec) ";
+ break;
+ case GlobalVariable::LocalExecTLSModel:
+ Out << "thread_local(localexec) ";
+ break;
+ }
+}
+
void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
if (GV->isMaterializable())
Out << "; Materializable\n";
PrintLinkage(GV->getLinkage(), Out);
PrintVisibility(GV->getVisibility(), Out);
+ PrintThreadLocalModel(GV->getThreadLocalMode(), Out);
- if (GV->isThreadLocal()) Out << "thread_local ";
if (unsigned AddressSpace = GV->getType()->getAddressSpace())
Out << "addrspace(" << AddressSpace << ") ";
if (GV->hasUnnamedAddr()) Out << "unnamed_addr ";
Out << ", align " << GV->getAlignment();
printInfoComment(*GV);
- Out << '\n';
}
void AssemblyWriter::printAlias(const GlobalAlias *GA) {
if (Aliasee == 0) {
TypePrinter.print(GA->getType(), Out);
Out << " <<NULL ALIASEE>>";
- } else if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Aliasee)) {
- TypePrinter.print(GV->getType(), Out);
- Out << ' ';
- PrintLLVMName(Out, GV);
- } else if (const Function *F = dyn_cast<Function>(Aliasee)) {
- TypePrinter.print(F->getFunctionType(), Out);
- Out << "* ";
-
- WriteAsOperandInternal(Out, F, &TypePrinter, &Machine, F->getParent());
- } else if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(Aliasee)) {
- TypePrinter.print(GA->getType(), Out);
- Out << ' ';
- PrintLLVMName(Out, GA);
} else {
- const ConstantExpr *CE = cast<ConstantExpr>(Aliasee);
- // The only valid GEP is an all zero GEP.
- assert((CE->getOpcode() == Instruction::BitCast ||
- CE->getOpcode() == Instruction::GetElementPtr) &&
- "Unsupported aliasee");
- writeOperand(CE, false);
+ writeOperand(Aliasee, !isa<ConstantExpr>(Aliasee));
}
printInfoComment(*GA);
if (TypePrinter.NumberedTypes.empty() &&
TypePrinter.NamedTypes.empty())
return;
-
+
Out << '\n';
-
+
// We know all the numbers that each type is used and we know that it is a
// dense assignment. Convert the map to an index table.
std::vector<StructType*> NumberedTypes(TypePrinter.NumberedTypes.size());
- for (DenseMap<StructType*, unsigned>::iterator I =
+ for (DenseMap<StructType*, unsigned>::iterator I =
TypePrinter.NumberedTypes.begin(), E = TypePrinter.NumberedTypes.end();
I != E; ++I) {
assert(I->second < NumberedTypes.size() && "Didn't get a dense numbering?");
NumberedTypes[I->second] = I->first;
}
-
+
// Emit all numbered types.
for (unsigned i = 0, e = NumberedTypes.size(); i != e; ++i) {
Out << '%' << i << " = type ";
-
+
// Make sure we print out at least one level of the type structure, so
// that we do not get %2 = type %2
TypePrinter.printStructBody(NumberedTypes[i], Out);
Out << '\n';
}
-
+
for (unsigned i = 0, e = TypePrinter.NamedTypes.size(); i != e; ++i) {
PrintLLVMName(Out, TypePrinter.NamedTypes[i]->getName(), LocalPrefix);
Out << " = type ";
PrintVisibility(F->getVisibility(), Out);
// Print the calling convention.
- switch (F->getCallingConv()) {
- case CallingConv::C: break; // default
- case CallingConv::Fast: Out << "fastcc "; break;
- 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;
+ if (F->getCallingConv() != CallingConv::C) {
+ PrintCallingConv(F->getCallingConv(), Out);
+ Out << " ";
}
FunctionType *FT = F->getFunctionType();
const AttrListPtr &Attrs = F->getAttributes();
Attributes RetAttrs = Attrs.getRetAttributes();
- if (RetAttrs != Attribute::None)
- Out << Attribute::getAsString(Attrs.getRetAttributes()) << ' ';
+ if (RetAttrs.hasAttributes())
+ Out << Attrs.getRetAttributes().getAsString() << ' ';
TypePrinter.print(F->getReturnType(), Out);
Out << ' ';
WriteAsOperandInternal(Out, F, &TypePrinter, &Machine, F->getParent());
TypePrinter.print(FT->getParamType(i), Out);
Attributes ArgAttrs = Attrs.getParamAttributes(i+1);
- if (ArgAttrs != Attribute::None)
- Out << ' ' << Attribute::getAsString(ArgAttrs);
+ if (ArgAttrs.hasAttributes())
+ Out << ' ' << ArgAttrs.getAsString();
}
}
if (F->hasUnnamedAddr())
Out << " unnamed_addr";
Attributes FnAttrs = Attrs.getFnAttributes();
- if (FnAttrs != Attribute::None)
- Out << ' ' << Attribute::getAsString(Attrs.getFnAttributes());
+ if (FnAttrs.hasAttributes())
+ Out << ' ' << Attrs.getFnAttributes().getAsString();
if (F->hasSection()) {
Out << " section \"";
PrintEscapedString(F->getSection(), Out);
TypePrinter.print(Arg->getType(), Out);
// Output parameter attributes list
- if (Attrs != Attribute::None)
- Out << ' ' << Attribute::getAsString(Attrs);
+ if (Attrs.hasAttributes())
+ Out << ' ' << Attrs.getAsString();
// Output name, if available...
if (Arg->hasName()) {
Out << '%' << SlotNum << " = ";
}
- // If this is a volatile load or store, print out the volatile marker.
- if ((isa<LoadInst>(I) && cast<LoadInst>(I).isVolatile()) ||
- (isa<StoreInst>(I) && cast<StoreInst>(I).isVolatile())) {
- Out << "volatile ";
- } else if (isa<CallInst>(I) && cast<CallInst>(I).isTailCall()) {
- // If this is a call, check if it's a tail call.
+ if (isa<CallInst>(I) && cast<CallInst>(I).isTailCall())
Out << "tail ";
- }
// Print out the opcode...
Out << I.getOpcodeName();
+ // If this is an atomic load or store, print out the atomic marker.
+ if ((isa<LoadInst>(I) && cast<LoadInst>(I).isAtomic()) ||
+ (isa<StoreInst>(I) && cast<StoreInst>(I).isAtomic()))
+ Out << " atomic";
+
+ // If this is a volatile operation, print out the volatile marker.
+ if ((isa<LoadInst>(I) && cast<LoadInst>(I).isVolatile()) ||
+ (isa<StoreInst>(I) && cast<StoreInst>(I).isVolatile()) ||
+ (isa<AtomicCmpXchgInst>(I) && cast<AtomicCmpXchgInst>(I).isVolatile()) ||
+ (isa<AtomicRMWInst>(I) && cast<AtomicRMWInst>(I).isVolatile()))
+ Out << " volatile";
+
// Print out optimization information.
WriteOptimizationInfo(Out, &I);
writeOperand(BI.getSuccessor(1), true);
} else if (isa<SwitchInst>(I)) {
+ SwitchInst& SI(cast<SwitchInst>(I));
// Special case switch instruction to get formatting nice and correct.
Out << ' ';
- writeOperand(Operand , true);
+ writeOperand(SI.getCondition(), true);
Out << ", ";
- writeOperand(I.getOperand(1), true);
+ writeOperand(SI.getDefaultDest(), true);
Out << " [";
-
- for (unsigned op = 2, Eop = I.getNumOperands(); op < Eop; op += 2) {
+ for (SwitchInst::CaseIt i = SI.case_begin(), e = SI.case_end();
+ i != e; ++i) {
Out << "\n ";
- writeOperand(I.getOperand(op ), true);
+ writeOperand(i.getCaseValue(), true);
Out << ", ";
- writeOperand(I.getOperand(op+1), true);
+ writeOperand(i.getCaseSuccessor(), true);
}
Out << "\n ]";
} else if (isa<IndirectBrInst>(I)) {
Out << ' ';
writeOperand(Operand, true);
Out << ", [";
-
+
for (unsigned i = 1, e = I.getNumOperands(); i != e; ++i) {
if (i != 1)
Out << ", ";
writeOperand(I.getOperand(1), true);
for (const unsigned *i = IVI->idx_begin(), *e = IVI->idx_end(); i != e; ++i)
Out << ", " << *i;
+ } else if (const LandingPadInst *LPI = dyn_cast<LandingPadInst>(&I)) {
+ Out << ' ';
+ TypePrinter.print(I.getType(), Out);
+ Out << " personality ";
+ writeOperand(I.getOperand(0), true); Out << '\n';
+
+ if (LPI->isCleanup())
+ Out << " cleanup";
+
+ for (unsigned i = 0, e = LPI->getNumClauses(); i != e; ++i) {
+ if (i != 0 || LPI->isCleanup()) Out << "\n";
+ if (LPI->isCatch(i))
+ Out << " catch ";
+ else
+ Out << " filter ";
+
+ writeOperand(LPI->getClause(i), true);
+ }
} else if (isa<ReturnInst>(I) && !Operand) {
Out << " void";
} else if (const CallInst *CI = dyn_cast<CallInst>(&I)) {
// Print the calling convention being used.
- switch (CI->getCallingConv()) {
- case CallingConv::C: break; // default
- case CallingConv::Fast: Out << " fastcc"; break;
- 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;
+ if (CI->getCallingConv() != CallingConv::C) {
+ Out << " ";
+ PrintCallingConv(CI->getCallingConv(), Out);
}
Operand = CI->getCalledValue();
Type *RetTy = FTy->getReturnType();
const AttrListPtr &PAL = CI->getAttributes();
- if (PAL.getRetAttributes() != Attribute::None)
- Out << ' ' << Attribute::getAsString(PAL.getRetAttributes());
+ if (PAL.getRetAttributes().hasAttributes())
+ Out << ' ' << PAL.getRetAttributes().getAsString();
// If possible, print out the short form of the call instruction. We can
// only do this if the first argument is a pointer to a nonvararg function,
writeParamOperand(CI->getArgOperand(op), PAL.getParamAttributes(op + 1));
}
Out << ')';
- if (PAL.getFnAttributes() != Attribute::None)
- Out << ' ' << Attribute::getAsString(PAL.getFnAttributes());
+ if (PAL.getFnAttributes().hasAttributes())
+ Out << ' ' << PAL.getFnAttributes().getAsString();
} else if (const InvokeInst *II = dyn_cast<InvokeInst>(&I)) {
Operand = II->getCalledValue();
PointerType *PTy = cast<PointerType>(Operand->getType());
const AttrListPtr &PAL = II->getAttributes();
// Print the calling convention being used.
- switch (II->getCallingConv()) {
- case CallingConv::C: break; // default
- case CallingConv::Fast: Out << " fastcc"; break;
- 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;
+ if (II->getCallingConv() != CallingConv::C) {
+ Out << " ";
+ PrintCallingConv(II->getCallingConv(), Out);
}
- if (PAL.getRetAttributes() != Attribute::None)
- Out << ' ' << Attribute::getAsString(PAL.getRetAttributes());
+ if (PAL.getRetAttributes().hasAttributes())
+ Out << ' ' << PAL.getRetAttributes().getAsString();
// If possible, print out the short form of the invoke instruction. We can
// only do this if the first argument is a pointer to a nonvararg function,
}
Out << ')';
- if (PAL.getFnAttributes() != Attribute::None)
- Out << ' ' << Attribute::getAsString(PAL.getFnAttributes());
+ if (PAL.getFnAttributes().hasAttributes())
+ Out << ' ' << PAL.getFnAttributes().getAsString();
Out << "\n to ";
writeOperand(II->getNormalDest(), true);
}
}
- // Print post operand alignment for load/store.
- if (isa<LoadInst>(I) && cast<LoadInst>(I).getAlignment()) {
- Out << ", align " << cast<LoadInst>(I).getAlignment();
- } else if (isa<StoreInst>(I) && cast<StoreInst>(I).getAlignment()) {
- Out << ", align " << cast<StoreInst>(I).getAlignment();
+ // Print atomic ordering/alignment for memory operations
+ if (const LoadInst *LI = dyn_cast<LoadInst>(&I)) {
+ if (LI->isAtomic())
+ writeAtomic(LI->getOrdering(), LI->getSynchScope());
+ if (LI->getAlignment())
+ Out << ", align " << LI->getAlignment();
+ } else if (const StoreInst *SI = dyn_cast<StoreInst>(&I)) {
+ if (SI->isAtomic())
+ writeAtomic(SI->getOrdering(), SI->getSynchScope());
+ if (SI->getAlignment())
+ Out << ", align " << SI->getAlignment();
} else if (const AtomicCmpXchgInst *CXI = dyn_cast<AtomicCmpXchgInst>(&I)) {
writeAtomic(CXI->getOrdering(), CXI->getSynchScope());
} else if (const AtomicRMWInst *RMWI = dyn_cast<AtomicRMWInst>(&I)) {
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))
+
+ Value *Op = Node->getOperand(0);
+ if (!Op || !isa<ConstantInt>(Op) || cast<ConstantInt>(Op)->getBitWidth() < 32)
return;
-
+
+ DIDescriptor Desc(Node);
+ if (Desc.getVersion() < LLVMDebugVersion11)
+ return;
+
+ unsigned Tag = Desc.getTag();
Out.PadToColumn(50);
- if (Tag == dwarf::DW_TAG_user_base)
+ if (dwarf::TagString(Tag)) {
+ Out << "; ";
+ Desc.print(Out);
+ } else 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 << " ]";
}
}
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]);
}
TypePrinting TP;
TP.print(const_cast<Type*>(this), OS);
-
+
// If the type is a named struct type, print the body as well.
if (StructType *STy = dyn_cast<StructType>(const_cast<Type*>(this)))
- if (!STy->isAnonymous()) {
+ if (!STy->isLiteral()) {
OS << " = type ";
TP.printStructBody(STy, OS);
}
// Module::dump() - Allow printing of Modules from the debugger.
void Module::dump() const { print(dbgs(), 0); }
+
+// NamedMDNode::dump() - Allow printing of NamedMDNodes from the debugger.
+void NamedMDNode::dump() const { print(dbgs(), 0); }