X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FVMCore%2FAsmWriter.cpp;h=7deba0d0382c0d4401de900aad5587bb3ca13c55;hb=5cd8ea2fd3a88639bc6556e9564a95bcdd9598db;hp=8ee364edbb3d342e2ac465bf28e3caabaeff094f;hpb=c65b72ca26cafb988a72dafa25dc5796094b74f8;p=oota-llvm.git diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp index 8ee364edbb3..7deba0d0382 100644 --- a/lib/VMCore/AsmWriter.cpp +++ b/lib/VMCore/AsmWriter.cpp @@ -16,7 +16,8 @@ #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" @@ -25,18 +26,18 @@ #include "llvm/Operator.h" #include "llvm/Module.h" #include "llvm/ValueSymbolTable.h" -#include "llvm/TypeSymbolTable.h" -#include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/CFG.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 #include -#include using namespace llvm; // Make virtual table appear in this compilation unit. @@ -60,15 +61,12 @@ static const Module *getModuleFromVal(const Value *V) { if (const GlobalValue *GV = dyn_cast(V)) return GV->getParent(); - if (const NamedMDNode *NMD = dyn_cast(V)) - return NMD->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 != '"') @@ -88,9 +86,8 @@ enum PrefixType { /// 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; @@ -136,60 +133,60 @@ static void PrintLLVMName(raw_ostream &OS, const Value *V) { // TypePrinting Class: Type printing machinery //===----------------------------------------------------------------------===// -static DenseMap &getTypeNamesMap(void *M) { - return *static_cast*>(M); -} - -void TypePrinting::clear() { - getTypeNamesMap(TypeNames).clear(); -} +/// TypePrinting - Type printing machinery. +namespace { +class TypePrinting { + TypePrinting(const TypePrinting &); // DO NOT IMPLEMENT + void operator=(const TypePrinting&); // DO NOT IMPLEMENT +public: -bool TypePrinting::hasTypeName(const Type *Ty) const { - return getTypeNamesMap(TypeNames).count(Ty); -} + /// NamedTypes - The named types that are used by the current module. + std::vector NamedTypes; + + /// NumberedTypes - The numbered types, along with their value. + DenseMap NumberedTypes; + -void TypePrinting::addTypeName(const Type *Ty, const std::string &N) { - getTypeNamesMap(TypeNames).insert(std::make_pair(Ty, N)); -} + TypePrinting() {} + ~TypePrinting() {} + + void incorporateTypes(const Module &M); + + void print(Type *Ty, raw_ostream &OS); + + void printStructBody(StructType *Ty, raw_ostream &OS); +}; +} // end anonymous namespace. -TypePrinting::TypePrinting() { - TypeNames = new DenseMap(); +void TypePrinting::incorporateTypes(const Module &M) { + M.findUsedStructTypes(NamedTypes); + + // 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()) + continue; + + if (STy->getName().empty()) + NumberedTypes[STy] = NextNumber++; + else + *NextToUse++ = STy; + } + + NamedTypes.erase(NextToUse, NamedTypes.end()); } -TypePrinting::~TypePrinting() { - delete &getTypeNamesMap(TypeNames); -} /// 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. -void TypePrinting::CalcTypeName(const Type *Ty, - SmallVectorImpl &TypeStack, - raw_ostream &OS, bool IgnoreTopLevelName) { - // Check to see if the type is named. - if (!IgnoreTopLevelName) { - DenseMap &TM = getTypeNamesMap(TypeNames); - DenseMap::iterator I = TM.find(Ty); - if (I != TM.end()) { - OS << I->second; - return; - } - } - - // Check to see if the Type is already on the stack... - unsigned Slot = 0, CurSize = TypeStack.size(); - while (Slot < CurSize && TypeStack[Slot] != Ty) ++Slot; // Scan for type - - // This is another base case for the recursion. In this case, we know - // that we have looped back to a type that we have previously visited. - // Generate the appropriate upreference to handle this. - if (Slot < CurSize) { - OS << '\\' << unsigned(CurSize-Slot); // Here's the upreference - return; - } - - TypeStack.push_back(Ty); // Recursive case: Add us to the stack.. - +void TypePrinting::print(Type *Ty, raw_ostream &OS) { switch (Ty->getTypeID()) { case Type::VoidTyID: OS << "void"; break; case Type::FloatTyID: OS << "float"; break; @@ -199,259 +196,99 @@ void TypePrinting::CalcTypeName(const Type *Ty, 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(Ty)->getBitWidth(); - break; + return; case Type::FunctionTyID: { - const FunctionType *FTy = cast(Ty); - CalcTypeName(FTy->getReturnType(), TypeStack, OS); + FunctionType *FTy = cast(Ty); + print(FTy->getReturnType(), OS); OS << " ("; for (FunctionType::param_iterator I = FTy->param_begin(), E = FTy->param_end(); I != E; ++I) { if (I != FTy->param_begin()) OS << ", "; - CalcTypeName(*I, TypeStack, OS); + print(*I, OS); } if (FTy->isVarArg()) { if (FTy->getNumParams()) OS << ", "; OS << "..."; } OS << ')'; - break; + return; } case Type::StructTyID: { - const StructType *STy = cast(Ty); - if (STy->isPacked()) - OS << '<'; - OS << "{ "; - for (StructType::element_iterator I = STy->element_begin(), - E = STy->element_end(); I != E; ++I) { - CalcTypeName(*I, TypeStack, OS); - if (next(I) != STy->element_end()) - OS << ','; - OS << ' '; - } - OS << '}'; - if (STy->isPacked()) - OS << '>'; - break; + StructType *STy = cast(Ty); + + if (STy->isAnonymous()) + 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 << '\"'; + return; } case Type::PointerTyID: { - const PointerType *PTy = cast(Ty); - CalcTypeName(PTy->getElementType(), TypeStack, OS); + PointerType *PTy = cast(Ty); + print(PTy->getElementType(), OS); if (unsigned AddressSpace = PTy->getAddressSpace()) OS << " addrspace(" << AddressSpace << ')'; OS << '*'; - break; + return; } case Type::ArrayTyID: { - const ArrayType *ATy = cast(Ty); + ArrayType *ATy = cast(Ty); OS << '[' << ATy->getNumElements() << " x "; - CalcTypeName(ATy->getElementType(), TypeStack, OS); + print(ATy->getElementType(), OS); OS << ']'; - break; + return; } case Type::VectorTyID: { - const VectorType *PTy = cast(Ty); + VectorType *PTy = cast(Ty); OS << "<" << PTy->getNumElements() << " x "; - CalcTypeName(PTy->getElementType(), TypeStack, OS); + print(PTy->getElementType(), OS); OS << '>'; - break; + return; } - case Type::OpaqueTyID: - OS << "opaque"; - break; default: OS << ""; - break; + return; } - - TypeStack.pop_back(); // Remove self from stack. } -/// printTypeInt - The internal guts of printing out a type that has a -/// potentially named portion. -/// -void TypePrinting::print(const Type *Ty, raw_ostream &OS, - bool IgnoreTopLevelName) { - // Check to see if the type is named. - DenseMap &TM = getTypeNamesMap(TypeNames); - if (!IgnoreTopLevelName) { - DenseMap::iterator I = TM.find(Ty); - if (I != TM.end()) { - OS << I->second; - return; - } +void TypePrinting::printStructBody(StructType *STy, raw_ostream &OS) { + if (STy->isOpaque()) { + OS << "opaque"; + return; } - - // Otherwise we have a type that has not been named but is a derived type. - // Carefully recurse the type hierarchy to print out any contained symbolic - // names. - SmallVector TypeStack; - std::string TypeName; - - raw_string_ostream TypeOS(TypeName); - CalcTypeName(Ty, TypeStack, TypeOS, IgnoreTopLevelName); - OS << TypeOS.str(); - - // Cache type name for later use. - if (!IgnoreTopLevelName) - TM.insert(std::make_pair(Ty, TypeOS.str())); -} - -namespace { - class TypeFinder { - // To avoid walking constant expressions multiple times and other IR - // objects, we keep several helper maps. - DenseSet VisitedConstants; - DenseSet VisitedTypes; - - TypePrinting &TP; - std::vector &NumberedTypes; - public: - TypeFinder(TypePrinting &tp, std::vector &numberedTypes) - : TP(tp), NumberedTypes(numberedTypes) {} - - void Run(const Module &M) { - // Get types from the type symbol table. This gets opaque types referened - // only through derived named types. - const TypeSymbolTable &ST = M.getTypeSymbolTable(); - for (TypeSymbolTable::const_iterator TI = ST.begin(), E = ST.end(); - TI != E; ++TI) - IncorporateType(TI->second); - - // Get types from global variables. - for (Module::const_global_iterator I = M.global_begin(), - E = M.global_end(); I != E; ++I) { - IncorporateType(I->getType()); - if (I->hasInitializer()) - IncorporateValue(I->getInitializer()); - } - - // Get types from aliases. - for (Module::const_alias_iterator I = M.alias_begin(), - E = M.alias_end(); I != E; ++I) { - IncorporateType(I->getType()); - IncorporateValue(I->getAliasee()); - } - - // Get types from functions. - for (Module::const_iterator FI = M.begin(), E = M.end(); FI != E; ++FI) { - IncorporateType(FI->getType()); - - for (Function::const_iterator BB = FI->begin(), E = FI->end(); - BB != E;++BB) - for (BasicBlock::const_iterator II = BB->begin(), - E = BB->end(); II != E; ++II) { - const Instruction &I = *II; - // Incorporate the type of the instruction and all its operands. - IncorporateType(I.getType()); - for (User::const_op_iterator OI = I.op_begin(), OE = I.op_end(); - OI != OE; ++OI) - IncorporateValue(*OI); - } - } - } - - private: - void IncorporateType(const Type *Ty) { - // Check to see if we're already visited this type. - if (!VisitedTypes.insert(Ty).second) - return; - - // If this is a structure or opaque type, add a name for the type. - if (((isa(Ty) && cast(Ty)->getNumElements()) - || isa(Ty)) && !TP.hasTypeName(Ty)) { - TP.addTypeName(Ty, "%"+utostr(unsigned(NumberedTypes.size()))); - NumberedTypes.push_back(Ty); - } - - // Recursively walk all contained types. - for (Type::subtype_iterator I = Ty->subtype_begin(), - E = Ty->subtype_end(); I != E; ++I) - IncorporateType(*I); - } - - /// IncorporateValue - This method is used to walk operand lists finding - /// types hiding in constant expressions and other operands that won't be - /// walked in other ways. GlobalValues, basic blocks, instructions, and - /// inst operands are all explicitly enumerated. - void IncorporateValue(const Value *V) { - if (V == 0 || !isa(V) || isa(V)) return; - - // Already visited? - if (!VisitedConstants.insert(V).second) - return; - - // Check this type. - IncorporateType(V->getType()); - - // Look in operands for types. - const Constant *C = cast(V); - for (Constant::const_op_iterator I = C->op_begin(), - E = C->op_end(); I != E;++I) - IncorporateValue(*I); - } - }; -} // end anonymous namespace - - -/// AddModuleTypesToPrinter - Add all of the symbolic type names for types in -/// the specified module to the TypePrinter and all numbered types to it and the -/// NumberedTypes table. -static void AddModuleTypesToPrinter(TypePrinting &TP, - std::vector &NumberedTypes, - const Module *M) { - if (M == 0) return; - - // If the module has a symbol table, take all global types and stuff their - // names into the TypeNames map. - const TypeSymbolTable &ST = M->getTypeSymbolTable(); - for (TypeSymbolTable::const_iterator TI = ST.begin(), E = ST.end(); - TI != E; ++TI) { - const Type *Ty = cast(TI->second); - - // As a heuristic, don't insert pointer to primitive types, because - // they are used too often to have a single useful name. - if (const PointerType *PTy = dyn_cast(Ty)) { - const Type *PETy = PTy->getElementType(); - if ((PETy->isPrimitiveType() || PETy->isInteger()) && - !isa(PETy)) - continue; + + if (STy->isPacked()) + OS << '<'; + + if (STy->getNumElements() == 0) { + OS << "{}"; + } else { + StructType::element_iterator I = STy->element_begin(); + OS << "{ "; + print(*I++, OS); + for (StructType::element_iterator E = STy->element_end(); I != E; ++I) { + OS << ", "; + print(*I, OS); } - - // Likewise don't insert primitives either. - if (Ty->isInteger() || Ty->isPrimitiveType()) - continue; - - // Get the name as a string and insert it into TypeNames. - std::string NameStr; - raw_string_ostream NameROS(NameStr); - formatted_raw_ostream NameOS(NameROS); - PrintLLVMName(NameOS, TI->first, LocalPrefix); - NameOS.flush(); - TP.addTypeName(Ty, NameStr); + + OS << " }"; } - - // Walk the entire module to find references to unnamed structure and opaque - // types. This is required for correctness by opaque types (because multiple - // uses of an unnamed opaque type needs to be referred to by the same ID) and - // it shrinks complex recursive structure types substantially in some cases. - TypeFinder(TP, NumberedTypes).Run(*M); + if (STy->isPacked()) + OS << '>'; } -/// WriteTypeSymbolic - This attempts to write the specified type as a symbolic -/// type, iff there is an entry in the modules symbol table for the specified -/// type or one of it's component types. -/// -void llvm::WriteTypeSymbolic(raw_ostream &OS, const Type *Ty, const Module *M) { - TypePrinting Printer; - std::vector NumberedTypes; - AddModuleTypesToPrinter(Printer, NumberedTypes, M); - Printer.print(Ty, OS); -} //===----------------------------------------------------------------------===// // SlotTracker Class: Enumerate slot numbers for unnamed values @@ -474,11 +311,11 @@ private: const Function* TheFunction; bool FunctionProcessed; - /// mMap - The TypePlanes map for the module level data. + /// mMap - The slot map for the module level data. ValueMap mMap; unsigned mNext; - /// fMap - The TypePlanes map for the function level data. + /// fMap - The slot map for the function level data. ValueMap fMap; unsigned fNext; @@ -563,11 +400,18 @@ static SlotTracker *createSlotTracker(const Value *V) { if (const Function *Func = dyn_cast(V)) return new SlotTracker(Func); + if (const MDNode *MD = dyn_cast(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 @@ -613,11 +457,8 @@ void SlotTracker::processModule() { I = TheModule->named_metadata_begin(), E = TheModule->named_metadata_end(); I != E; ++I) { const NamedMDNode *NMD = I; - for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) { - // FIXME: Change accessor to be type safe. - if (MDNode *MD = cast_or_null(NMD->getOperand(i))) - CreateMetadataSlot(MD); - } + for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) + CreateMetadataSlot(NMD->getOperand(i)); } // Add all the unnamed functions to the table. @@ -655,11 +496,16 @@ void SlotTracker::processFunction() { if (!I->getType()->isVoidTy() && !I->hasName()) CreateFunctionSlot(I); - // Intrinsics can directly use metadata. - if (isa(I)) - for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) - if (MDNode *N = dyn_cast_or_null(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(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(I->getOperand(i))) + CreateMetadataSlot(N); + } // Process metadata attached with this instruction. I->getAllMetadata(MDForInst); @@ -690,7 +536,7 @@ int SlotTracker::getGlobalSlot(const GlobalValue *V) { // Check for uninitialized state and do lazy initialization. initialize(); - // Find the type plane in the module map + // Find the value in the module map ValueMap::iterator MI = mMap.find(V); return MI == mMap.end() ? -1 : (int)MI->second; } @@ -700,7 +546,7 @@ int SlotTracker::getMetadataSlot(const MDNode *N) { // Check for uninitialized state and do lazy initialization. initialize(); - // Find the type plane in the module map + // Find the MDNode in the module map mdn_iterator MI = mdnMap.find(N); return MI == mdnMap.end() ? -1 : (int)MI->second; } @@ -753,15 +599,14 @@ void SlotTracker::CreateMetadataSlot(const MDNode *N) { // Don't insert if N is a function-local metadata, these are always printed // inline. - if (N->isFunctionLocal()) - return; - - mdn_iterator I = mdnMap.find(N); - if (I != mdnMap.end()) - return; + if (!N->isFunctionLocal()) { + mdn_iterator I = mdnMap.find(N); + if (I != mdnMap.end()) + return; - unsigned DestSlot = mdnNext++; - mdnMap[N] = DestSlot; + unsigned DestSlot = mdnNext++; + mdnMap[N] = DestSlot; + } // Recursively add any MDNodes referenced by operands. for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) @@ -775,7 +620,8 @@ void SlotTracker::CreateMetadataSlot(const MDNode *N) { static void WriteAsOperandInternal(raw_ostream &Out, const Value *V, TypePrinting *TypePrinter, - SlotTracker *Machine); + SlotTracker *Machine, + const Module *Context); @@ -812,6 +658,23 @@ static const char *getPredicateText(unsigned predicate) { return pred; } +static void writeAtomicRMWOperation(raw_ostream &Out, + AtomicRMWInst::BinOp Op) { + switch (Op) { + default: Out << " "; break; + case AtomicRMWInst::Xchg: Out << " xchg"; break; + case AtomicRMWInst::Add: Out << " add"; break; + case AtomicRMWInst::Sub: Out << " sub"; break; + case AtomicRMWInst::And: Out << " and"; break; + case AtomicRMWInst::Nand: Out << " nand"; break; + case AtomicRMWInst::Or: Out << " or"; break; + case AtomicRMWInst::Xor: Out << " xor"; break; + case AtomicRMWInst::Max: Out << " max"; break; + case AtomicRMWInst::Min: Out << " min"; break; + case AtomicRMWInst::UMax: Out << " umax"; break; + case AtomicRMWInst::UMin: Out << " umin"; break; + } +} static void WriteOptimizationInfo(raw_ostream &Out, const User *U) { if (const OverflowingBinaryOperator *OBO = @@ -820,7 +683,8 @@ static void WriteOptimizationInfo(raw_ostream &Out, const User *U) { Out << " nuw"; if (OBO->hasNoSignedWrap()) Out << " nsw"; - } else if (const SDivOperator *Div = dyn_cast(U)) { + } else if (const PossiblyExactOperator *Div = + dyn_cast(U)) { if (Div->isExact()) Out << " exact"; } else if (const GEPOperator *GEP = dyn_cast(U)) { @@ -829,10 +693,12 @@ static void WriteOptimizationInfo(raw_ostream &Out, const User *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(CV)) { - if (CI->getType() == Type::getInt1Ty(CV->getContext())) { + if (CI->getType()->isIntegerTy(1)) { Out << (CI->getZExtValue() ? "true" : "false"); return; } @@ -852,7 +718,8 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV, 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 @@ -863,7 +730,7 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV, (StrVal[1] >= '0' && StrVal[1] <= '9'))) { // Reparse stringized version! if (atof(StrVal.c_str()) == Val) { - Out << StrVal; + Out << StrVal.str(); return; } } @@ -945,9 +812,11 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV, if (const BlockAddress *BA = dyn_cast(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; } @@ -956,7 +825,7 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV, // As a special case, print the array as a string if it is an array of // i8 with ConstantInt values. // - const Type *ETy = CA->getType()->getElementType(); + Type *ETy = CA->getType()->getElementType(); if (CA->isString()) { Out << "c\""; PrintEscapedString(CA->getAsString(), Out); @@ -967,12 +836,14 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV, 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 << ']'; @@ -990,14 +861,16 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV, 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 << ' '; } @@ -1009,18 +882,20 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV, } if (const ConstantVector *CP = dyn_cast(CV)) { - const Type *ETy = CP->getType()->getElementType(); + Type *ETy = CP->getType()->getElementType(); assert(CP->getNumOperands() > 0 && "Number of operands for a PackedConst must be > 0"); 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; @@ -1036,11 +911,6 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV, return; } - if (const MDNode *Node = dyn_cast(CV)) { - Out << "!" << Machine->getMetadataSlot(Node); - return; - } - if (const ConstantExpr *CE = dyn_cast(CV)) { Out << CE->getOpcodeName(); WriteOptimizationInfo(Out, CE); @@ -1051,13 +921,13 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV, 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 &Indices = CE->getIndices(); + ArrayRef Indices = CE->getIndices(); for (unsigned i = 0, e = Indices.size(); i != e; ++i) Out << ", " << Indices[i]; } @@ -1076,7 +946,8 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV, static void WriteMDNodeBodyInternal(raw_ostream &Out, const MDNode *Node, TypePrinting *TypePrinter, - SlotTracker *Machine) { + SlotTracker *Machine, + const Module *Context) { Out << "!{"; for (unsigned mi = 0, me = Node->getNumOperands(); mi != me; ++mi) { const Value *V = Node->getOperand(mi); @@ -1086,7 +957,7 @@ static void WriteMDNodeBodyInternal(raw_ostream &Out, const MDNode *Node, TypePrinter->print(V->getType(), Out); Out << ' '; WriteAsOperandInternal(Out, Node->getOperand(mi), - TypePrinter, Machine); + TypePrinter, Machine, Context); } if (mi + 1 != me) Out << ", "; @@ -1102,7 +973,8 @@ static void WriteMDNodeBodyInternal(raw_ostream &Out, const MDNode *Node, /// 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; @@ -1111,7 +983,7 @@ static void WriteAsOperandInternal(raw_ostream &Out, const Value *V, const Constant *CV = dyn_cast(V); if (CV && !isa(CV)) { assert(TypePrinter && "Constants require TypePrinting!"); - WriteConstantInt(Out, CV, *TypePrinter, Machine); + WriteConstantInternal(Out, CV, *TypePrinter, Machine, Context); return; } @@ -1132,11 +1004,21 @@ static void WriteAsOperandInternal(raw_ostream &Out, const Value *V, if (const MDNode *N = dyn_cast(V)) { if (N->isFunctionLocal()) { // Print metadata inline, not via slot reference number. - WriteMDNodeBodyInternal(Out, N, TypePrinter, Machine); + 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 << ""; + else + Out << '!' << Slot; return; } @@ -1189,22 +1071,23 @@ void llvm::WriteAsOperand(raw_ostream &Out, const Value *V, // Fast path: Don't construct and populate a TypePrinting object if we // won't be needing any types printed. if (!PrintType && - (!isa(V) || V->hasName() || isa(V))) { - WriteAsOperandInternal(Out, V, 0, 0); + ((!isa(V) && !isa(V)) || + V->hasName() || isa(V))) { + WriteAsOperandInternal(Out, V, 0, 0, Context); return; } if (Context == 0) Context = getModuleFromVal(V); TypePrinting TypePrinter; - std::vector NumberedTypes; - AddModuleTypesToPrinter(TypePrinter, NumberedTypes, Context); + if (Context) + TypePrinter.incorporateTypes(*Context); if (PrintType) { TypePrinter.print(V->getType(), Out); Out << ' '; } - WriteAsOperandInternal(Out, V, &TypePrinter, 0); + WriteAsOperandInternal(Out, V, &TypePrinter, 0, Context); } namespace { @@ -1215,17 +1098,14 @@ class AssemblyWriter { const Module *TheModule; TypePrinting TypePrinter; AssemblyAnnotationWriter *AnnotationWriter; - std::vector NumberedTypes; - SmallVector MDNames; public: inline AssemblyWriter(formatted_raw_ostream &o, SlotTracker &Mac, const Module *M, AssemblyAnnotationWriter *AAW) : Out(o), Machine(Mac), TheModule(M), AnnotationWriter(AAW) { - AddModuleTypesToPrinter(TypePrinter, NumberedTypes, M); if (M) - M->getMDKindNames(MDNames); + TypePrinter.incorporateTypes(*M); } void printMDNodeBody(const MDNode *MD); @@ -1235,25 +1115,25 @@ public: void writeOperand(const Value *Op, bool PrintType); void writeParamOperand(const Value *Operand, Attributes Attrs); + void writeAtomic(AtomicOrdering Ordering, SynchronizationScope SynchScope); void writeAllMDNodes(); - void printTypeSymbolTable(const TypeSymbolTable &ST); + void printTypeIdentities(); void printGlobal(const GlobalVariable *GV); void printAlias(const GlobalAlias *GV); void printFunction(const Function *F); void printArgument(const Argument *FA, Attributes Attrs); void printBasicBlock(const BasicBlock *BB); void printInstruction(const Instruction &I); -private: +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 << ""; @@ -1263,7 +1143,29 @@ void AssemblyWriter::writeOperand(const Value *Operand, bool PrintType) { TypePrinter.print(Operand->getType(), Out); Out << ' '; } - WriteAsOperandInternal(Out, Operand, &TypePrinter, &Machine); + WriteAsOperandInternal(Out, Operand, &TypePrinter, &Machine, TheModule); +} + +void AssemblyWriter::writeAtomic(AtomicOrdering Ordering, + SynchronizationScope SynchScope) { + if (Ordering == NotAtomic) + return; + + switch (SynchScope) { + default: Out << " "; break; + case SingleThread: Out << " singlethread"; break; + case CrossThread: break; + } + + switch (Ordering) { + default: Out << " "; break; + case Unordered: Out << " unordered"; break; + case Monotonic: Out << " monotonic"; break; + case Acquire: Out << " acquire"; break; + case Release: Out << " release"; break; + case AcquireRelease: Out << " acq_rel"; break; + case SequentiallyConsistent: Out << " seq_cst"; break; + } } void AssemblyWriter::writeParamOperand(const Value *Operand, @@ -1280,7 +1182,7 @@ void AssemblyWriter::writeParamOperand(const Value *Operand, Out << ' ' << Attribute::getAsString(Attrs); Out << ' '; // Print the operand - WriteAsOperandInternal(Out, Operand, &TypePrinter, &Machine); + WriteAsOperandInternal(Out, Operand, &TypePrinter, &Machine, TheModule); } void AssemblyWriter::printModule(const Module *M) { @@ -1311,9 +1213,12 @@ 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. @@ -1331,9 +1236,7 @@ void AssemblyWriter::printModule(const Module *M) { Out << " ]"; } - // Loop over the symbol table, emitting all id'd types. - if (!M->getTypeSymbolTable().empty() || !NumberedTypes.empty()) Out << '\n'; - printTypeSymbolTable(M->getTypeSymbolTable()); + printTypeIdentities(); // Output all globals. if (!M->global_empty()) Out << '\n'; @@ -1366,13 +1269,32 @@ void AssemblyWriter::printModule(const Module *M) { } void AssemblyWriter::printNamedMDNode(const NamedMDNode *NMD) { - Out << "!" << NMD->getName() << " = !{"; + Out << '!'; + StringRef Name = NMD->getName(); + if (Name.empty()) { + Out << " "; + } 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 << ", "; - // FIXME: Change accessor to be typesafe. - // FIXME: This doesn't handle null?? - MDNode *MD = cast_or_null(NMD->getOperand(i)); - Out << '!' << Machine.getMetadataSlot(MD); + int Slot = Machine.getMetadataSlot(NMD->getOperand(i)); + if (Slot == -1) + Out << ""; + else + Out << '!' << Slot; } Out << "}\n"; } @@ -1384,6 +1306,12 @@ static void PrintLinkage(GlobalValue::LinkageTypes 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; @@ -1397,8 +1325,6 @@ static void PrintLinkage(GlobalValue::LinkageTypes LT, case GlobalValue::AvailableExternallyLinkage: Out << "available_externally "; break; - // This is invalid syntax and just a debugging aid. - case GlobalValue::GhostLinkage: Out << "ghost "; break; } } @@ -1413,7 +1339,10 @@ static void PrintVisibility(GlobalValue::VisibilityTypes Vis, } 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()) @@ -1425,6 +1354,7 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) { 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); @@ -1433,8 +1363,11 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) { 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(); @@ -1443,6 +1376,9 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) { } void AssemblyWriter::printAlias(const GlobalAlias *GA) { + if (GA->isMaterializable()) + Out << "; Materializable\n"; + // Don't crash when dumping partially built GA if (!GA->hasName()) Out << "<> = "; @@ -1458,52 +1394,51 @@ void AssemblyWriter::printAlias(const GlobalAlias *GA) { const Constant *Aliasee = GA->getAliasee(); - 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); - } else if (const GlobalAlias *GA = dyn_cast(Aliasee)) { + if (Aliasee == 0) { TypePrinter.print(GA->getType(), Out); - Out << ' '; - PrintLLVMName(Out, GA); + Out << " <>"; } 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); Out << '\n'; } -void AssemblyWriter::printTypeSymbolTable(const TypeSymbolTable &ST) { +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 = + 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.printAtLeastOneLevel(NumberedTypes[i], Out); + TypePrinter.printStructBody(NumberedTypes[i], Out); Out << '\n'; } - - // Print the named types. - for (TypeSymbolTable::const_iterator TI = ST.begin(), TE = ST.end(); - TI != TE; ++TI) { - PrintLLVMName(Out, TI->first, LocalPrefix); + + for (unsigned i = 0, e = TypePrinter.NamedTypes.size(); i != e; ++i) { + PrintLLVMName(Out, TypePrinter.NamedTypes[i]->getName(), LocalPrefix); Out << " = type "; // Make sure we print out at least one level of the type structure, so // that we do not get %FILE = type %FILE - TypePrinter.printAtLeastOneLevel(TI->second, Out); + TypePrinter.printStructBody(TypePrinter.NamedTypes[i], Out); Out << '\n'; } } @@ -1516,6 +1451,9 @@ void AssemblyWriter::printFunction(const Function *F) { if (AnnotationWriter) AnnotationWriter->emitFunctionAnnot(F, Out); + if (F->isMaterializable()) + Out << "; Materializable\n"; + if (F->isDeclaration()) Out << "declare "; else @@ -1531,21 +1469,24 @@ void AssemblyWriter::printFunction(const Function *F) { 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; } - const FunctionType *FT = F->getFunctionType(); + FunctionType *FT = F->getFunctionType(); const AttrListPtr &Attrs = F->getAttributes(); Attributes RetAttrs = Attrs.getRetAttributes(); if (RetAttrs != Attribute::None) 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); @@ -1582,21 +1523,25 @@ void AssemblyWriter::printFunction(const Function *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); @@ -1645,10 +1590,10 @@ void AssemblyWriter::printBasicBlock(const BasicBlock *BB) { 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!"; @@ -1675,17 +1620,14 @@ void AssemblyWriter::printBasicBlock(const BasicBlock *BB) { if (AnnotationWriter) AnnotationWriter->emitBasicBlockEndAnnot(BB, Out); } - /// printInfoComment - Print a little comment after the instruction indicating /// which slot it occupies. /// void AssemblyWriter::printInfoComment(const Value &V) { - if (V.getType()->isVoidTy()) return; - - Out.PadToColumn(50); - Out << "; <"; - TypePrinter.print(V.getType(), Out); - Out << "> [#uses=" << V.getNumUses() << ']'; // Output # uses + if (AnnotationWriter) { + AnnotationWriter->printInfoComment(V, Out); + return; + } } // This member is called for each Instruction in a function.. @@ -1727,6 +1669,10 @@ void AssemblyWriter::printInstruction(const Instruction &I) { if (const CmpInst *CI = dyn_cast(&I)) Out << ' ' << getPredicateText(CI->getPredicate()); + // Print out the atomicrmw operation + if (const AtomicRMWInst *RMWI = dyn_cast(&I)) + writeAtomicRMWOperation(Out, RMWI->getOperation()); + // Print out the type of the operands... const Value *Operand = I.getNumOperands() ? I.getOperand(0) : 0; @@ -1767,16 +1713,16 @@ void AssemblyWriter::printInstruction(const Instruction &I) { writeOperand(I.getOperand(i), true); } Out << ']'; - } else if (isa(I)) { + } else if (const PHINode *PN = dyn_cast(&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(&I)) { Out << ' '; @@ -1799,16 +1745,20 @@ void AssemblyWriter::printInstruction(const Instruction &I) { 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; } - const PointerType *PTy = cast(Operand->getType()); - const FunctionType *FTy = cast(PTy->getElementType()); - const Type *RetTy = FTy->getReturnType(); + Operand = CI->getCalledValue(); + PointerType *PTy = cast(Operand->getType()); + FunctionType *FTy = cast(PTy->getElementType()); + Type *RetTy = FTy->getReturnType(); const AttrListPtr &PAL = CI->getAttributes(); if (PAL.getRetAttributes() != Attribute::None) @@ -1820,8 +1770,8 @@ void AssemblyWriter::printInstruction(const Instruction &I) { // Out << ' '; if (!FTy->isVarArg() && - (!isa(RetTy) || - !isa(cast(RetTy)->getElementType()))) { + (!RetTy->isPointerTy() || + !cast(RetTy)->getElementType()->isFunctionTy())) { TypePrinter.print(RetTy, Out); Out << ' '; writeOperand(Operand, false); @@ -1829,18 +1779,19 @@ void AssemblyWriter::printInstruction(const Instruction &I) { 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(&I)) { - const PointerType *PTy = cast(Operand->getType()); - const FunctionType *FTy = cast(PTy->getElementType()); - const Type *RetTy = FTy->getReturnType(); + Operand = II->getCalledValue(); + PointerType *PTy = cast(Operand->getType()); + FunctionType *FTy = cast(PTy->getElementType()); + Type *RetTy = FTy->getReturnType(); const AttrListPtr &PAL = II->getAttributes(); // Print the calling convention being used. @@ -1850,10 +1801,13 @@ void AssemblyWriter::printInstruction(const Instruction &I) { 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; } @@ -1866,8 +1820,8 @@ void AssemblyWriter::printInstruction(const Instruction &I) { // Out << ' '; if (!FTy->isVarArg() && - (!isa(RetTy) || - !isa(cast(RetTy)->getElementType()))) { + (!RetTy->isPointerTy() || + !cast(RetTy)->getElementType()->isFunctionTy())) { TypePrinter.print(RetTy, Out); Out << ' '; writeOperand(Operand, false); @@ -1875,10 +1829,10 @@ void AssemblyWriter::printInstruction(const Instruction &I) { 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 << ')'; @@ -1920,7 +1874,7 @@ void AssemblyWriter::printInstruction(const Instruction &I) { // omit the type from all but the first operand. If the instruction has // different type operands (for example br), then they are all printed. bool PrintAllTypes = false; - const Type *TheType = Operand->getType(); + Type *TheType = Operand->getType(); // Select, Store and ShuffleVector always print all types. if (isa(I) || isa(I) || isa(I) @@ -1955,43 +1909,53 @@ void AssemblyWriter::printInstruction(const Instruction &I) { Out << ", align " << cast(I).getAlignment(); } else if (isa(I) && cast(I).getAlignment()) { Out << ", align " << cast(I).getAlignment(); + } else if (const AtomicCmpXchgInst *CXI = dyn_cast(&I)) { + writeAtomic(CXI->getOrdering(), CXI->getSynchScope()); + } else if (const AtomicRMWInst *RMWI = dyn_cast(&I)) { + writeAtomic(RMWI->getOrdering(), RMWI->getSynchScope()); + } else if (const FenceInst *FI = dyn_cast(&I)) { + writeAtomic(FI->getOrdering(), FI->getSynchScope()); } // Print Metadata info. - if (!MDNames.empty()) { - SmallVector, 4> InstMD; - I.getAllMetadata(InstMD); - for (unsigned i = 0, e = InstMD.size(); i != e; ++i) - Out << ", !" << MDNames[InstMD[i].first] - << " !" << Machine.getMetadataSlot(InstMD[i].second); + SmallVector, 4> InstMD; + I.getAllMetadata(InstMD); + if (!InstMD.empty()) { + SmallVector 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 << ", !"; + } + Out << ' '; + WriteAsOperandInternal(Out, InstMD[i].second, &TypePrinter, &Machine, + TheModule); + } } printInfoComment(I); } static void WriteMDNodeComment(const MDNode *Node, - formatted_raw_ostream &Out) { + formatted_raw_ostream &Out) { if (Node->getNumOperands() < 1) return; ConstantInt *CI = dyn_cast_or_null(Node->getOperand(0)); if (!CI) return; - unsigned Val = CI->getZExtValue(); - unsigned Tag = Val & ~LLVMDebugVersionMask; - if (Val < LLVMDebugVersion) + APInt Val = CI->getValue(); + APInt Tag = Val & ~APInt(Val.getBitWidth(), LLVMDebugVersionMask); + if (Val.ult(LLVMDebugVersion)) return; Out.PadToColumn(50); - 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) + if (Tag == dwarf::DW_TAG_user_base) Out << "; [ DW_TAG_user_base ]"; - else if (const char *TagName = dwarf::TagString(Tag)) - Out << "; [ " << TagName << " ]"; + else if (Tag.isIntN(32)) { + if (const char *TagName = dwarf::TagString(Tag.getZExtValue())) + Out << "; [ " << TagName << " ]"; + } } void AssemblyWriter::writeAllMDNodes() { @@ -2008,7 +1972,7 @@ void AssemblyWriter::writeAllMDNodes() { } void AssemblyWriter::printMDNodeBody(const MDNode *Node) { - WriteMDNodeBodyInternal(Out, Node, &TypePrinter, &Machine); + WriteMDNodeBodyInternal(Out, Node, &TypePrinter, &Machine, TheModule); WriteMDNodeComment(Node, Out); Out << "\n"; } @@ -2024,12 +1988,27 @@ void Module::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW) const { 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 (this == 0) { OS << ""; return; } - TypePrinting().print(this, OS); + 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()) { + OS << " = type "; + TP.printStructBody(STy, OS); + } } void Value::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW) const { @@ -2041,7 +2020,7 @@ void Value::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW) const { if (const Instruction *I = dyn_cast(this)) { const Function *F = I->getParent() ? I->getParent()->getParent() : 0; SlotTracker SlotTable(F); - AssemblyWriter W(OS, SlotTable, getModuleFromVal(F), AAW); + AssemblyWriter W(OS, SlotTable, getModuleFromVal(I), AAW); W.printInstruction(*I); } else if (const BasicBlock *BB = dyn_cast(this)) { SlotTracker SlotTable(BB->getParent()); @@ -2057,18 +2036,15 @@ void Value::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW) const { else W.printAlias(cast(GV)); } else if (const MDNode *N = dyn_cast(this)) { - SlotTracker SlotTable((Function*)0); - AssemblyWriter W(OS, SlotTable, 0, AAW); + const Function *F = N->getFunction(); + SlotTracker SlotTable(F); + AssemblyWriter W(OS, SlotTable, F ? F->getParent() : 0, AAW); W.printMDNodeBody(N); - } else if (const NamedMDNode *N = dyn_cast(this)) { - SlotTracker SlotTable(N->getParent()); - AssemblyWriter W(OS, SlotTable, N->getParent(), AAW); - W.printNamedMDNode(N); } else if (const Constant *C = dyn_cast(this)) { TypePrinting TypePrinter; TypePrinter.print(C->getType(), OS); OS << ' '; - WriteConstantInt(OS, C, TypePrinter, 0); + WriteConstantInternal(OS, C, TypePrinter, 0, 0); } else if (isa(this) || isa(this) || isa(this)) { WriteAsOperand(OS, this, true, 0); @@ -2085,17 +2061,10 @@ void Value::printCustom(raw_ostream &OS) const { } // Value::dump - allow easy printing of Values from the debugger. -void Value::dump() const { print(errs()); errs() << '\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'; -} +void Value::dump() const { print(dbgs()); dbgs() << '\n'; } // Type::dump - allow easy printing of Types from the debugger. -void Type::dump() const { dump(0); } +void Type::dump() const { print(dbgs()); } // Module::dump() - Allow printing of Modules from the debugger. -void Module::dump() const { print(errs(), 0); } +void Module::dump() const { print(dbgs(), 0); }