X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FVMCore%2FAsmWriter.cpp;h=b72c17f667fb50c869be2474a24bbf9da6c23654;hb=95d8afc5f2898b59240b0c0cd78d6f54140a91b8;hp=825a7c1b66f009f69dc53f723cdd7321f8e2c78a;hpb=10c6d12a9fd4dab411091f64db4db69670b88850;p=oota-llvm.git diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp index 825a7c1b66f..b72c17f667f 100644 --- a/lib/VMCore/AsmWriter.cpp +++ b/lib/VMCore/AsmWriter.cpp @@ -20,11 +20,13 @@ #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" @@ -58,12 +60,31 @@ static const Module *getModuleFromVal(const Value *V) { const Function *M = I->getParent() ? I->getParent()->getParent() : 0; return M ? M->getParent() : 0; } - + if (const GlobalValue *GV = dyn_cast(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) { @@ -89,7 +110,6 @@ enum PrefixType { 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; @@ -100,7 +120,11 @@ static void PrintLLVMName(raw_ostream &OS, StringRef Name, PrefixType Prefix) { 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; @@ -136,50 +160,50 @@ static void PrintLLVMName(raw_ostream &OS, const Value *V) { /// 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 NamedTypes; - + TypeFinder NamedTypes; + /// NumberedTypes - The numbered types, along with their value. DenseMap 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::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()); } @@ -189,6 +213,7 @@ void TypePrinting::incorporateTypes(const Module &M) { 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; @@ -220,18 +245,18 @@ void TypePrinting::print(Type *Ty, raw_ostream &OS) { } case Type::StructTyID: { StructType *STy = cast(Ty); - - if (STy->isAnonymous()) + + if (STy->isLiteral()) return printStructBody(STy, OS); if (!STy->getName().empty()) return PrintLLVMName(OS, STy->getName(), LocalPrefix); - + DenseMap::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: { @@ -267,10 +292,10 @@ void TypePrinting::printStructBody(StructType *STy, raw_ostream &OS) { OS << "opaque"; return; } - + if (STy->isPacked()) OS << '<'; - + if (STy->getNumElements() == 0) { OS << "{}"; } else { @@ -281,7 +306,7 @@ void TypePrinting::printStructBody(StructType *STy, raw_ostream &OS) { OS << ", "; print(*I, OS); } - + OS << " }"; } if (STy->isPacked()) @@ -374,8 +399,8 @@ private: /// 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 @@ -386,7 +411,8 @@ static SlotTracker *createSlotTracker(const Value *V) { return new SlotTracker(FA->getParent()); if (const Instruction *I = dyn_cast(V)) - return new SlotTracker(I->getParent()->getParent()); + if (I->getParent()) + return new SlotTracker(I->getParent()->getParent()); if (const BasicBlock *BB = dyn_cast(V)) return new SlotTracker(BB->getParent()); @@ -419,7 +445,7 @@ static SlotTracker *createSlotTracker(const Value *V) { // 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) { } @@ -490,12 +516,12 @@ void SlotTracker::processFunction() { 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. @@ -707,31 +733,36 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV, } if (const ConstantFP *CFP = dyn_cast(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 @@ -742,7 +773,7 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV, "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); @@ -752,16 +783,20 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV, 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>shiftcount) & 15; @@ -777,17 +812,21 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV, } } 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>shiftcount) & 15; @@ -809,7 +848,7 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV, Out << "zeroinitializer"; return; } - + if (const BlockAddress *BA = dyn_cast(CV)) { Out << "blockaddress("; WriteAsOperandInternal(Out, BA->getFunction(), &TypePrinter, Machine, @@ -822,35 +861,53 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV, } if (const ConstantArray *CA = dyn_cast(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(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(CV)) { if (CS->getType()->isPacked()) Out << '<'; @@ -881,21 +938,19 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV, return; } - if (const ConstantVector *CP = dyn_cast(CV)) { - Type *ETy = CP->getType()->getElementType(); - assert(CP->getNumOperands() > 0 && - "Number of operands for a PackedConst must be > 0"); + if (isa(CV) || isa(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; @@ -956,13 +1011,13 @@ static void WriteMDNodeBodyInternal(raw_ostream &Out, const MDNode *Node, 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 << "}"; } @@ -993,6 +1048,9 @@ static void WriteAsOperandInternal(raw_ostream &Out, const Value *V, 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 << "\", \""; @@ -1007,7 +1065,7 @@ static void WriteAsOperandInternal(raw_ostream &Out, const Value *V, WriteMDNodeBodyInternal(Out, N, TypePrinter, Machine, Context); return; } - + if (!Machine) { if (N->isFunctionLocal()) Machine = new SlotTracker(N->getFunction()); @@ -1037,26 +1095,35 @@ static void WriteAsOperandInternal(raw_ostream &Out, const Value *V, char Prefix = '%'; int Slot; + // If we have a SlotTracker, use it. if (Machine) { if (const GlobalValue *GV = dyn_cast(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(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(V)) { + Slot = Machine->getGlobalSlot(GV); + Prefix = '@'; } else { - Slot = -1; + Slot = Machine->getLocalSlot(V); } + delete Machine; + Machine = 0; + } else { + Slot = -1; } if (Slot != -1) @@ -1098,7 +1165,7 @@ class AssemblyWriter { const Module *TheModule; TypePrinting TypePrinter; AssemblyAnnotationWriter *AnnotationWriter; - + public: inline AssemblyWriter(formatted_raw_ostream &o, SlotTracker &Mac, const Module *M, @@ -1110,7 +1177,7 @@ public: void printMDNodeBody(const MDNode *MD); void printNamedMDNode(const NamedMDNode *NMD); - + void printModule(const Module *M); void writeOperand(const Value *Op, bool PrintType); @@ -1152,7 +1219,6 @@ void AssemblyWriter::writeAtomic(AtomicOrdering Ordering, return; switch (SynchScope) { - default: Out << " "; break; case SingleThread: Out << " singlethread"; break; case CrossThread: break; } @@ -1178,8 +1244,8 @@ void AssemblyWriter::writeParamOperand(const Value *Operand, // 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); @@ -1241,8 +1307,9 @@ void AssemblyWriter::printModule(const Module *M) { // 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"; @@ -1256,7 +1323,7 @@ void AssemblyWriter::printModule(const Module *M) { // 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); @@ -1309,12 +1376,12 @@ static void PrintLinkage(GlobalValue::LinkageTypes LT, 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; @@ -1338,6 +1405,26 @@ static void PrintVisibility(GlobalValue::VisibilityTypes Vis, } } +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"; @@ -1350,8 +1437,8 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) { 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 "; @@ -1372,7 +1459,6 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) { Out << ", align " << GV->getAlignment(); printInfoComment(*GV); - Out << '\n'; } void AssemblyWriter::printAlias(const GlobalAlias *GA) { @@ -1397,26 +1483,8 @@ void AssemblyWriter::printAlias(const GlobalAlias *GA) { if (Aliasee == 0) { TypePrinter.print(GA->getType(), Out); Out << " <>"; - } else if (const GlobalVariable *GV = dyn_cast(Aliasee)) { - TypePrinter.print(GV->getType(), Out); - Out << ' '; - PrintLLVMName(Out, GV); - } else if (const Function *F = dyn_cast(Aliasee)) { - TypePrinter.print(F->getFunctionType(), Out); - Out << "* "; - - WriteAsOperandInternal(Out, F, &TypePrinter, &Machine, F->getParent()); - } else if (const GlobalAlias *GA = dyn_cast(Aliasee)) { - TypePrinter.print(GA->getType(), Out); - Out << ' '; - PrintLLVMName(Out, GA); } else { - const ConstantExpr *CE = cast(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(Aliasee)); } printInfoComment(*GA); @@ -1427,29 +1495,29 @@ void AssemblyWriter::printTypeIdentities() { 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 NumberedTypes(TypePrinter.NumberedTypes.size()); - for (DenseMap::iterator I = + for (DenseMap::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 "; @@ -1481,27 +1549,16 @@ void AssemblyWriter::printFunction(const Function *F) { 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()); @@ -1530,8 +1587,8 @@ void AssemblyWriter::printFunction(const Function *F) { 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(); } } @@ -1544,8 +1601,8 @@ void AssemblyWriter::printFunction(const Function *F) { 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); @@ -1578,8 +1635,8 @@ void AssemblyWriter::printArgument(const Argument *Arg, 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()) { @@ -1668,18 +1725,24 @@ void AssemblyWriter::printInstruction(const Instruction &I) { Out << '%' << SlotNum << " = "; } - // If this is a volatile load or store, print out the volatile marker. - if ((isa(I) && cast(I).isVolatile()) || - (isa(I) && cast(I).isVolatile())) { - Out << "volatile "; - } else if (isa(I) && cast(I).isTailCall()) { - // If this is a call, check if it's a tail call. + if (isa(I) && cast(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(I) && cast(I).isAtomic()) || + (isa(I) && cast(I).isAtomic())) + Out << " atomic"; + + // If this is a volatile operation, print out the volatile marker. + if ((isa(I) && cast(I).isVolatile()) || + (isa(I) && cast(I).isVolatile()) || + (isa(I) && cast(I).isVolatile()) || + (isa(I) && cast(I).isVolatile())) + Out << " volatile"; + // Print out optimization information. WriteOptimizationInfo(Out, &I); @@ -1705,18 +1768,19 @@ void AssemblyWriter::printInstruction(const Instruction &I) { writeOperand(BI.getSuccessor(1), true); } else if (isa(I)) { + SwitchInst& SI(cast(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(I)) { @@ -1724,7 +1788,7 @@ void AssemblyWriter::printInstruction(const Instruction &I) { Out << ' '; writeOperand(Operand, true); Out << ", ["; - + for (unsigned i = 1, e = I.getNumOperands(); i != e; ++i) { if (i != 1) Out << ", "; @@ -1753,24 +1817,31 @@ void AssemblyWriter::printInstruction(const Instruction &I) { 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(&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(I) && !Operand) { Out << " void"; } else if (const CallInst *CI = dyn_cast(&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(); @@ -1779,8 +1850,8 @@ void AssemblyWriter::printInstruction(const Instruction &I) { 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, @@ -1803,8 +1874,8 @@ void AssemblyWriter::printInstruction(const Instruction &I) { 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(&I)) { Operand = II->getCalledValue(); PointerType *PTy = cast(Operand->getType()); @@ -1813,24 +1884,13 @@ void AssemblyWriter::printInstruction(const Instruction &I) { 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, @@ -1854,8 +1914,8 @@ void AssemblyWriter::printInstruction(const Instruction &I) { } 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); @@ -1922,11 +1982,17 @@ void AssemblyWriter::printInstruction(const Instruction &I) { } } - // Print post operand alignment for load/store. - if (isa(I) && cast(I).getAlignment()) { - Out << ", align " << cast(I).getAlignment(); - } else if (isa(I) && cast(I).getAlignment()) { - Out << ", align " << cast(I).getAlignment(); + // Print atomic ordering/alignment for memory operations + if (const LoadInst *LI = dyn_cast(&I)) { + if (LI->isAtomic()) + writeAtomic(LI->getOrdering(), LI->getSynchScope()); + if (LI->getAlignment()) + Out << ", align " << LI->getAlignment(); + } else if (const StoreInst *SI = dyn_cast(&I)) { + if (SI->isAtomic()) + writeAtomic(SI->getOrdering(), SI->getSynchScope()); + if (SI->getAlignment()) + Out << ", align " << SI->getAlignment(); } else if (const AtomicCmpXchgInst *CXI = dyn_cast(&I)) { writeAtomic(CXI->getOrdering(), CXI->getSynchScope()); } else if (const AtomicRMWInst *RMWI = dyn_cast(&I)) { @@ -1960,19 +2026,22 @@ static void WriteMDNodeComment(const MDNode *Node, formatted_raw_ostream &Out) { if (Node->getNumOperands() < 1) return; - ConstantInt *CI = dyn_cast_or_null(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(Op) || cast(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 << " ]"; } } @@ -1982,7 +2051,7 @@ void AssemblyWriter::writeAllMDNodes() { for (SlotTracker::mdn_iterator I = Machine.mdn_begin(), E = Machine.mdn_end(); I != E; ++I) Nodes[I->second] = cast(I->first); - + for (unsigned i = 0, e = Nodes.size(); i != e; ++i) { Out << '!' << i << " = metadata "; printMDNodeBody(Nodes[i]); @@ -2020,10 +2089,10 @@ void Type::print(raw_ostream &OS) const { } TypePrinting TP; TP.print(const_cast(this), OS); - + // If the type is a named struct type, print the body as well. if (StructType *STy = dyn_cast(const_cast(this))) - if (!STy->isAnonymous()) { + if (!STy->isLiteral()) { OS << " = type "; TP.printStructBody(STy, OS); } @@ -2086,3 +2155,6 @@ void Type::dump() const { print(dbgs()); } // 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); }