X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;ds=sidebyside;f=lib%2FVMCore%2FAsmWriter.cpp;h=008c1daee192b91d53d246ec4eb81d146289872b;hb=80a75bfae980df96f969f1c05b0c4a80ce975240;hp=181f8e68c6166252b861e21902922cf6812c5aae;hpb=ac618e6a9d0e63ac7c71231393c557feaf787a85;p=oota-llvm.git diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp index 181f8e68c61..008c1daee19 100644 --- a/lib/VMCore/AsmWriter.cpp +++ b/lib/VMCore/AsmWriter.cpp @@ -20,11 +20,12 @@ #include "llvm/CallingConv.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" +#include "llvm/ParameterAttributes.h" #include "llvm/InlineAsm.h" #include "llvm/Instruction.h" #include "llvm/Instructions.h" #include "llvm/Module.h" -#include "llvm/SymbolTable.h" +#include "llvm/ValueSymbolTable.h" #include "llvm/TypeSymbolTable.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/STLExtras.h" @@ -32,6 +33,7 @@ #include "llvm/Support/MathExtras.h" #include "llvm/Support/Streams.h" #include +#include using namespace llvm; namespace llvm { @@ -48,17 +50,7 @@ class SlotMachine { public: /// @brief A mapping of Values to slot numbers - typedef std::map ValueMap; - - /// @brief A plane with next slot number and ValueMap - struct ValuePlane { - unsigned next_slot; ///< The next slot number to use - ValueMap map; ///< The map of Value* -> unsigned - ValuePlane() { next_slot = 0; } ///< Make sure we start at 0 - }; - - /// @brief The map of planes by Type - typedef std::map TypedPlanes; + typedef std::map ValueMap; /// @} /// @name Constructors @@ -131,10 +123,12 @@ public: bool FunctionProcessed; /// @brief The TypePlanes map for the module level data - TypedPlanes mMap; + ValueMap mMap; + unsigned mNext; /// @brief The TypePlanes map for the function level data - TypedPlanes fMap; + ValueMap fMap; + unsigned fNext; /// @} @@ -142,8 +136,10 @@ public: } // end namespace llvm +char PrintModulePass::ID = 0; static RegisterPass X("printm", "Print module to stderr"); +char PrintFunctionPass::ID = 0; static RegisterPass Y("print","Print function to stderr"); @@ -173,37 +169,71 @@ static SlotMachine *createSlotMachine(const Value *V) { return new SlotMachine(BB->getParent()); } else if (const GlobalVariable *GV = dyn_cast(V)){ return new SlotMachine(GV->getParent()); + } else if (const GlobalAlias *GA = dyn_cast(V)){ + return new SlotMachine(GA->getParent()); } else if (const Function *Func = dyn_cast(V)) { return new SlotMachine(Func); } return 0; } -// getLLVMName - Turn the specified string 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). -static std::string getLLVMName(const std::string &Name, - bool prefixName = true) { - assert(!Name.empty() && "Cannot get empty name!"); - - // First character cannot start with a number... - if (Name[0] >= '0' && Name[0] <= '9') - return "\"" + Name + "\""; - - // Scan to see if we have any characters that are not on the "white list" +/// NameNeedsQuotes - Return true if the specified llvm name should be wrapped +/// with ""'s. +static std::string QuoteNameIfNeeded(const std::string &Name) { + std::string result; + bool needsQuotes = Name[0] >= '0' && Name[0] <= '9'; + // Scan the name to see if it needs quotes and to replace funky chars with + // their octal equivalent. for (unsigned i = 0, e = Name.size(); i != e; ++i) { char C = Name[i]; assert(C != '"' && "Illegal character in LLVM value name!"); - if ((C < 'a' || C > 'z') && (C < 'A' || C > 'Z') && (C < '0' || C > '9') && - C != '-' && C != '.' && C != '_') - return "\"" + Name + "\""; + if (isalnum(C) || C == '-' || C == '.' || C == '_') + result += C; + else if (C == '\\') { + needsQuotes = true; + result += "\\\\"; + } else if (isprint(C)) { + needsQuotes = true; + result += C; + } else { + needsQuotes = true; + result += "\\"; + char hex1 = (C >> 4) & 0x0F; + if (hex1 < 10) + result += hex1 + '0'; + else + result += hex1 - 10 + 'A'; + char hex2 = C & 0x0F; + if (hex2 < 10) + result += hex2 + '0'; + else + result += hex2 - 10 + 'A'; + } + } + if (needsQuotes) { + result.insert(0,"\""); + result += '"'; } + return result; +} - // If we get here, then the identifier is legal to use as a "VarID". - if (prefixName) - return "%"+Name; - else - return Name; +enum PrefixType { + GlobalPrefix, + LabelPrefix, + LocalPrefix +}; + +/// getLLVMName - Turn the specified string 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). +static std::string getLLVMName(const std::string &Name, PrefixType Prefix) { + assert(!Name.empty() && "Cannot get empty name!"); + switch (Prefix) { + default: assert(0 && "Bad prefix!"); + case GlobalPrefix: return '@' + QuoteNameIfNeeded(Name); + case LabelPrefix: return QuoteNameIfNeeded(Name); + case LocalPrefix: return '%' + QuoteNameIfNeeded(Name); + } } @@ -222,8 +252,9 @@ static void fillTypeNameTable(const Module *M, const Type *Ty = cast(TI->second); if (!isa(Ty) || !cast(Ty)->getElementType()->isPrimitiveType() || + !cast(Ty)->getElementType()->isInteger() || isa(cast(Ty)->getElementType())) - TypeNames.insert(std::make_pair(Ty, getLLVMName(TI->first))); + TypeNames.insert(std::make_pair(Ty, getLLVMName(TI->first, LocalPrefix))); } } @@ -233,7 +264,7 @@ static void calcTypeName(const Type *Ty, std::vector &TypeStack, std::map &TypeNames, std::string & Result){ - if (Ty->isPrimitiveType() && !isa(Ty)) { + if (Ty->isInteger() || (Ty->isPrimitiveType() && !isa(Ty))) { Result += Ty->getDescription(); // Base case return; } @@ -265,31 +296,26 @@ static void calcTypeName(const Type *Ty, TypeStack.push_back(Ty); // Recursive case: Add us to the stack.. switch (Ty->getTypeID()) { + case Type::IntegerTyID: { + unsigned BitWidth = cast(Ty)->getBitWidth(); + Result += "i" + utostr(BitWidth); + break; + } case Type::FunctionTyID: { const FunctionType *FTy = cast(Ty); calcTypeName(FTy->getReturnType(), TypeStack, TypeNames, Result); Result += " ("; - unsigned Idx = 1; for (FunctionType::param_iterator I = FTy->param_begin(), - E = FTy->param_end(); I != E; ++I) { + E = FTy->param_end(); I != E; ++I) { if (I != FTy->param_begin()) Result += ", "; calcTypeName(*I, TypeStack, TypeNames, Result); - if (FTy->getParamAttrs(Idx)) { - Result += + " "; - Result += FunctionType::getParamAttrsText(FTy->getParamAttrs(Idx)); - } - Idx++; } if (FTy->isVarArg()) { if (FTy->getNumParams()) Result += ", "; Result += "..."; } Result += ")"; - if (FTy->getParamAttrs(0)) { - Result += " "; - Result += FunctionType::getParamAttrsText(FTy->getParamAttrs(0)); - } break; } case Type::StructTyID: { @@ -320,8 +346,8 @@ static void calcTypeName(const Type *Ty, Result += "]"; break; } - case Type::PackedTyID: { - const PackedType *PTy = cast(Ty); + case Type::VectorTyID: { + const VectorType *PTy = cast(Ty); Result += "<" + utostr(PTy->getNumElements()) + " x "; calcTypeName(PTy->getElementType(), TypeStack, TypeNames, Result); Result += ">"; @@ -347,7 +373,7 @@ static std::ostream &printTypeInt(std::ostream &Out, const Type *Ty, // Primitive types always print out their description, regardless of whether // they have been named or not. // - if (Ty->isPrimitiveType() && !isa(Ty)) + if (Ty->isInteger() || (Ty->isPrimitiveType() && !isa(Ty))) return Out << Ty->getDescription(); // Check to see if the type is named. @@ -438,37 +464,74 @@ static void WriteConstantInt(std::ostream &Out, const Constant *CV, SlotMachine *Machine) { const int IndentSize = 4; static std::string Indent = "\n"; - if (const ConstantBool *CB = dyn_cast(CV)) { - Out << (CB->getValue() ? "true" : "false"); - } else if (const ConstantInt *CI = dyn_cast(CV)) { - Out << CI->getSExtValue(); + if (const ConstantInt *CI = dyn_cast(CV)) { + if (CI->getType() == Type::Int1Ty) + Out << (CI->getZExtValue() ? "true" : "false"); + else + Out << CI->getValue().toStringSigned(10); } else if (const ConstantFP *CFP = dyn_cast(CV)) { - // 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. - // - std::string StrVal = ftostr(CFP->getValue()); - - // 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()) == CFP->getValue()) { - Out << StrVal; - return; + if (&CFP->getValueAPF().getSemantics() == &APFloat::IEEEdouble || + &CFP->getValueAPF().getSemantics() == &APFloat::IEEEsingle) { + // 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 isDouble = &CFP->getValueAPF().getSemantics()==&APFloat::IEEEdouble; + double Val = (isDouble) ? CFP->getValueAPF().convertToDouble() : + CFP->getValueAPF().convertToFloat(); + std::string StrVal = ftostr(CFP->getValueAPF()); + + // 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; + return; + } } - - // Otherwise we could not reparse it to exactly the same value, so we must - // output the string in hexadecimal format! - assert(sizeof(double) == sizeof(uint64_t) && - "assuming that double is 64 bits!"); - Out << "0x" << utohexstr(DoubleToBits(CFP->getValue())); - + // Otherwise we could not reparse it to exactly the same value, so we must + // output the string in hexadecimal format! + assert(sizeof(double) == sizeof(uint64_t) && + "assuming that double is 64 bits!"); + Out << "0x" << utohexstr(DoubleToBits(Val)); + } else { + // Some form of long double. These appear as a magic letter identifying + // the type, then a fixed number of hex digits. + Out << "0x"; + if (&CFP->getValueAPF().getSemantics() == &APFloat::x87DoubleExtended) + Out << 'K'; + else if (&CFP->getValueAPF().getSemantics() == &APFloat::IEEEquad) + Out << 'L'; + else if (&CFP->getValueAPF().getSemantics() == &APFloat::PPCDoubleDouble) + Out << 'M'; + else + assert(0 && "Unsupported floating point type"); + // api needed to prevent premature destruction + APInt api = CFP->getValueAPF().convertToAPInt(); + const uint64_t* p = api.getRawData(); + uint64_t word = *p; + int shiftcount=60; + int width = api.getBitWidth(); + for (int j=0; j>shiftcount) & 15; + if (nibble < 10) + Out << (unsigned char)(nibble + '0'); + else + Out << (unsigned char)(nibble - 10 + 'A'); + if (shiftcount == 0) { + word = *(++p); + shiftcount = 64; + if (width-j-4 < 64) + shiftcount = width-j-4; + } + } + } } else if (isa(CV)) { Out << "zeroinitializer"; } else if (const ConstantArray *CA = dyn_cast(CV)) { @@ -525,7 +588,7 @@ static void WriteConstantInt(std::ostream &Out, const Constant *CV, Out << " }"; if (CS->getType()->isPacked()) Out << '>'; - } else if (const ConstantPacked *CP = dyn_cast(CV)) { + } else if (const ConstantVector *CP = dyn_cast(CV)) { const Type *ETy = CP->getType()->getElementType(); assert(CP->getNumOperands() > 0 && "Number of operands for a PackedConst must be > 0"); @@ -580,7 +643,8 @@ static void WriteAsOperandInternal(std::ostream &Out, const Value *V, SlotMachine *Machine) { Out << ' '; if (V->hasName()) - Out << getLLVMName(V->getName()); + Out << getLLVMName(V->getName(), + isa(V) ? GlobalPrefix : LocalPrefix); else { const Constant *CV = dyn_cast(V); if (CV && !isa(CV)) { @@ -595,26 +659,31 @@ static void WriteAsOperandInternal(std::ostream &Out, const Value *V, PrintEscapedString(IA->getConstraintString(), Out); Out << '"'; } else { + char Prefix = '%'; int Slot; if (Machine) { - if (const GlobalValue *GV = dyn_cast(V)) + if (const GlobalValue *GV = dyn_cast(V)) { Slot = Machine->getGlobalSlot(GV); - else + Prefix = '@'; + } else { Slot = Machine->getLocalSlot(V); + } } else { Machine = createSlotMachine(V); if (Machine) { - if (const GlobalValue *GV = dyn_cast(V)) + if (const GlobalValue *GV = dyn_cast(V)) { Slot = Machine->getGlobalSlot(GV); - else + Prefix = '@'; + } else { Slot = Machine->getLocalSlot(V); + } } else { Slot = -1; } delete Machine; } if (Slot != -1) - Out << '%' << Slot; + Out << Prefix << Slot; else Out << ""; } @@ -660,26 +729,26 @@ public: fillTypeNameTable(M, TypeNames); } - inline void write(const Module *M) { printModule(M); } - inline void write(const GlobalVariable *G) { printGlobal(G); } - inline void write(const Function *F) { printFunction(F); } - inline void write(const BasicBlock *BB) { printBasicBlock(BB); } + inline void write(const Module *M) { printModule(M); } + inline void write(const GlobalVariable *G) { printGlobal(G); } + inline void write(const GlobalAlias *G) { printAlias(G); } + inline void write(const Function *F) { printFunction(F); } + inline void write(const BasicBlock *BB) { printBasicBlock(BB); } inline void write(const Instruction *I) { printInstruction(*I); } - inline void write(const Constant *CPV) { printConstant(CPV); } - inline void write(const Type *Ty) { printType(Ty); } + inline void write(const Type *Ty) { printType(Ty); } void writeOperand(const Value *Op, bool PrintType); + void writeParamOperand(const Value *Operand, uint16_t Attrs); const Module* getModule() { return TheModule; } private: void printModule(const Module *M); void printTypeSymbolTable(const TypeSymbolTable &ST); - void printValueSymbolTable(const SymbolTable &ST); - void printConstant(const Constant *CPV); void printGlobal(const GlobalVariable *GV); + void printAlias(const GlobalAlias *GV); void printFunction(const Function *F); - void printArgument(const Argument *FA, FunctionType::ParameterAttributes A); + void printArgument(const Argument *FA, uint16_t ParamAttrs); void printBasicBlock(const BasicBlock *BB); void printInstruction(const Instruction &I); @@ -705,27 +774,22 @@ private: /// without considering any symbolic types that we may have equal to it. /// std::ostream &AssemblyWriter::printTypeAtLeastOneLevel(const Type *Ty) { - if (const FunctionType *FTy = dyn_cast(Ty)) { + if (const IntegerType *ITy = dyn_cast(Ty)) + Out << "i" << utostr(ITy->getBitWidth()); + else if (const FunctionType *FTy = dyn_cast(Ty)) { printType(FTy->getReturnType()); Out << " ("; - unsigned Idx = 1; for (FunctionType::param_iterator I = FTy->param_begin(), E = FTy->param_end(); I != E; ++I) { if (I != FTy->param_begin()) Out << ", "; printType(*I); - if (FTy->getParamAttrs(Idx)) { - Out << " " << FunctionType::getParamAttrsText(FTy->getParamAttrs(Idx)); - } - Idx++; } if (FTy->isVarArg()) { if (FTy->getNumParams()) Out << ", "; Out << "..."; } Out << ')'; - if (FTy->getParamAttrs(0)) - Out << ' ' << FunctionType::getParamAttrsText(FTy->getParamAttrs(0)); } else if (const StructType *STy = dyn_cast(Ty)) { if (STy->isPacked()) Out << '<'; @@ -744,7 +808,7 @@ std::ostream &AssemblyWriter::printTypeAtLeastOneLevel(const Type *Ty) { } else if (const ArrayType *ATy = dyn_cast(Ty)) { Out << '[' << ATy->getNumElements() << " x "; printType(ATy->getElementType()) << ']'; - } else if (const PackedType *PTy = dyn_cast(Ty)) { + } else if (const VectorType *PTy = dyn_cast(Ty)) { Out << '<' << PTy->getNumElements() << " x "; printType(PTy->getElementType()) << '>'; } @@ -768,6 +832,20 @@ void AssemblyWriter::writeOperand(const Value *Operand, bool PrintType) { } } +void AssemblyWriter::writeParamOperand(const Value *Operand, uint16_t Attrs) { + if (Operand == 0) { + Out << ""; + } else { + Out << ' '; + // Print the type + printType(Operand->getType()); + // Print parameter attributes list + if (Attrs != ParamAttr::None) + Out << ' ' << ParamAttrsList::getParamAttrsText(Attrs); + // Print the operand + WriteAsOperandInternal(Out, Operand, TypeNames, &Machine); + } +} void AssemblyWriter::printModule(const Module *M) { if (!M->getModuleIdentifier().empty() && @@ -778,17 +856,6 @@ void AssemblyWriter::printModule(const Module *M) { if (!M->getDataLayout().empty()) Out << "target datalayout = \"" << M->getDataLayout() << "\"\n"; - - switch (M->getEndianness()) { - case Module::LittleEndian: Out << "target endian = little\n"; break; - case Module::BigEndian: Out << "target endian = big\n"; break; - case Module::AnyEndianness: break; - } - switch (M->getPointerSize()) { - case Module::Pointer32: Out << "target pointersize = 32\n"; break; - case Module::Pointer64: Out << "target pointersize = 64\n"; break; - case Module::AnyPointerSize: break; - } if (!M->getTargetTriple().empty()) Out << "target triple = \"" << M->getTargetTriple() << "\"\n"; @@ -828,13 +895,16 @@ void AssemblyWriter::printModule(const Module *M) { // Loop over the symbol table, emitting all named constants. printTypeSymbolTable(M->getTypeSymbolTable()); - printValueSymbolTable(M->getValueSymbolTable()); for (Module::const_global_iterator I = M->global_begin(), E = M->global_end(); I != E; ++I) printGlobal(I); - - Out << "\nimplementation ; Functions:\n"; + + // Output all aliases. + if (!M->alias_empty()) Out << "\n"; + for (Module::const_alias_iterator I = M->alias_begin(), E = M->alias_end(); + I != E; ++I) + printAlias(I); // Output all of the functions. for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I) @@ -842,15 +912,14 @@ void AssemblyWriter::printModule(const Module *M) { } void AssemblyWriter::printGlobal(const GlobalVariable *GV) { - if (GV->hasName()) Out << getLLVMName(GV->getName()) << " = "; + if (GV->hasName()) Out << getLLVMName(GV->getName(), GlobalPrefix) << " = "; if (!GV->hasInitializer()) switch (GV->getLinkage()) { case GlobalValue::DLLImportLinkage: Out << "dllimport "; break; case GlobalValue::ExternalWeakLinkage: Out << "extern_weak "; break; default: Out << "external "; break; - } - else + } else { switch (GV->getLinkage()) { case GlobalValue::InternalLinkage: Out << "internal "; break; case GlobalValue::LinkOnceLinkage: Out << "linkonce "; break; @@ -864,7 +933,15 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) { cerr << "GhostLinkage not allowed in AsmWriter!\n"; abort(); } + switch (GV->getVisibility()) { + default: assert(0 && "Invalid visibility style!"); + case GlobalValue::DefaultVisibility: break; + case GlobalValue::HiddenVisibility: Out << "hidden "; break; + case GlobalValue::ProtectedVisibility: Out << "protected "; break; + } + } + if (GV->isThreadLocal()) Out << "thread_local "; Out << (GV->isConstant() ? "constant " : "global "); printType(GV->getType()->getElementType()); @@ -873,21 +950,66 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) { assert(C && "GlobalVar initializer isn't constant?"); writeOperand(GV->getInitializer(), false); } - + if (GV->hasSection()) Out << ", section \"" << GV->getSection() << '"'; if (GV->getAlignment()) Out << ", align " << GV->getAlignment(); - + printInfoComment(*GV); Out << "\n"; } +void AssemblyWriter::printAlias(const GlobalAlias *GA) { + Out << getLLVMName(GA->getName(), GlobalPrefix) << " = "; + switch (GA->getVisibility()) { + default: assert(0 && "Invalid visibility style!"); + case GlobalValue::DefaultVisibility: break; + case GlobalValue::HiddenVisibility: Out << "hidden "; break; + case GlobalValue::ProtectedVisibility: Out << "protected "; break; + } + + Out << "alias "; + + switch (GA->getLinkage()) { + case GlobalValue::WeakLinkage: Out << "weak "; break; + case GlobalValue::InternalLinkage: Out << "internal "; break; + case GlobalValue::ExternalLinkage: break; + default: + assert(0 && "Invalid alias linkage"); + } + + const Constant *Aliasee = GA->getAliasee(); + + if (const GlobalVariable *GV = dyn_cast(Aliasee)) { + printType(GV->getType()); + Out << " " << getLLVMName(GV->getName(), GlobalPrefix); + } else if (const Function *F = dyn_cast(Aliasee)) { + printType(F->getFunctionType()); + Out << "* "; + + if (!F->getName().empty()) + Out << getLLVMName(F->getName(), GlobalPrefix); + else + Out << "@\"\""; + } else { + const ConstantExpr *CE = 0; + if ((CE = dyn_cast(Aliasee)) && + (CE->getOpcode() == Instruction::BitCast)) { + writeOperand(CE, false); + } else + assert(0 && "Unsupported aliasee"); + } + + printInfoComment(*GA); + Out << "\n"; +} + void AssemblyWriter::printTypeSymbolTable(const TypeSymbolTable &ST) { // Print the types. for (TypeSymbolTable::const_iterator TI = ST.begin(), TE = ST.end(); TI != TE; ++TI) { - Out << "\t" << getLLVMName(TI->first) << " = type "; + Out << "\t" << getLLVMName(TI->first, LocalPrefix) << " = type "; // Make sure we print out at least one level of the type structure, so // that we do not get %FILE = type %FILE @@ -896,81 +1018,42 @@ void AssemblyWriter::printTypeSymbolTable(const TypeSymbolTable &ST) { } } -// printSymbolTable - Run through symbol table looking for constants -// and types. Emit their declarations. -void AssemblyWriter::printValueSymbolTable(const SymbolTable &ST) { - - // Print the constants, in type plane order. - for (SymbolTable::plane_const_iterator PI = ST.plane_begin(); - PI != ST.plane_end(); ++PI) { - SymbolTable::value_const_iterator VI = ST.value_begin(PI->first); - SymbolTable::value_const_iterator VE = ST.value_end(PI->first); - - for (; VI != VE; ++VI) { - const Value* V = VI->second; - const Constant *CPV = dyn_cast(V) ; - if (CPV && !isa(V)) { - printConstant(CPV); - } - } - } -} - - -/// printConstant - Print out a constant pool entry... -/// -void AssemblyWriter::printConstant(const Constant *CPV) { - // Don't print out unnamed constants, they will be inlined - if (!CPV->hasName()) return; - - // Print out name... - Out << "\t" << getLLVMName(CPV->getName()) << " ="; - - // Write the value out now. - writeOperand(CPV, true); - - printInfoComment(*CPV); - Out << "\n"; -} - /// printFunction - Print all aspects of a function. /// void AssemblyWriter::printFunction(const Function *F) { // Print out the return type and name... Out << "\n"; - // Ensure that no local symbols conflict with global symbols. - const_cast(F)->renameLocalSymbols(); - if (AnnotationWriter) AnnotationWriter->emitFunctionAnnot(F, Out); - if (F->isExternal()) - switch (F->getLinkage()) { - case GlobalValue::DLLImportLinkage: Out << "declare dllimport "; break; - case GlobalValue::ExternalWeakLinkage: Out << "declare extern_weak "; break; - default: Out << "declare "; - } - else { + if (F->isDeclaration()) + Out << "declare "; + else Out << "define "; - switch (F->getLinkage()) { - case GlobalValue::InternalLinkage: Out << "internal "; break; - case GlobalValue::LinkOnceLinkage: Out << "linkonce "; break; - case GlobalValue::WeakLinkage: Out << "weak "; break; - case GlobalValue::AppendingLinkage: Out << "appending "; break; - case GlobalValue::DLLImportLinkage: Out << "dllimport "; break; - case GlobalValue::DLLExportLinkage: Out << "dllexport "; break; - case GlobalValue::ExternalWeakLinkage: Out << "extern_weak "; break; - case GlobalValue::ExternalLinkage: break; - case GlobalValue::GhostLinkage: - cerr << "GhostLinkage not allowed in AsmWriter!\n"; - abort(); - } + + switch (F->getLinkage()) { + case GlobalValue::InternalLinkage: Out << "internal "; break; + case GlobalValue::LinkOnceLinkage: Out << "linkonce "; break; + case GlobalValue::WeakLinkage: Out << "weak "; break; + case GlobalValue::AppendingLinkage: Out << "appending "; break; + case GlobalValue::DLLImportLinkage: Out << "dllimport "; break; + case GlobalValue::DLLExportLinkage: Out << "dllexport "; break; + case GlobalValue::ExternalWeakLinkage: Out << "extern_weak "; break; + case GlobalValue::ExternalLinkage: break; + case GlobalValue::GhostLinkage: + cerr << "GhostLinkage not allowed in AsmWriter!\n"; + abort(); + } + switch (F->getVisibility()) { + default: assert(0 && "Invalid visibility style!"); + case GlobalValue::DefaultVisibility: break; + case GlobalValue::HiddenVisibility: Out << "hidden "; break; + case GlobalValue::ProtectedVisibility: Out << "protected "; break; } // Print the calling convention. switch (F->getCallingConv()) { case CallingConv::C: break; // default - case CallingConv::CSRet: Out << "csretcc "; break; case CallingConv::Fast: Out << "fastcc "; break; case CallingConv::Cold: Out << "coldcc "; break; case CallingConv::X86_StdCall: Out << "x86_stdcallcc "; break; @@ -979,23 +1062,42 @@ void AssemblyWriter::printFunction(const Function *F) { } const FunctionType *FT = F->getFunctionType(); + const ParamAttrsList *Attrs = F->getParamAttrs(); printType(F->getReturnType()) << ' '; if (!F->getName().empty()) - Out << getLLVMName(F->getName()); + Out << getLLVMName(F->getName(), GlobalPrefix); else - Out << "\"\""; + Out << "@\"\""; Out << '('; Machine.incorporateFunction(F); // Loop over the arguments, printing them... unsigned Idx = 1; - for (Function::const_arg_iterator I = F->arg_begin(), E = F->arg_end(); - I != E; ++I) { - // Insert commas as we go... the first arg doesn't get a comma - if (I != F->arg_begin()) Out << ", "; - printArgument(I, FT->getParamAttrs(Idx)); - Idx++; + if (!F->isDeclaration()) { + // If this isn't a declaration, print the argument names as well. + for (Function::const_arg_iterator I = F->arg_begin(), E = F->arg_end(); + I != E; ++I) { + // Insert commas as we go... the first arg doesn't get a comma + if (I != F->arg_begin()) Out << ", "; + printArgument(I, (Attrs ? Attrs->getParamAttrs(Idx) + : uint16_t(ParamAttr::None))); + Idx++; + } + } else { + // Otherwise, print the types from the function type. + for (unsigned i = 0, e = FT->getNumParams(); i != e; ++i) { + // Insert commas as we go... the first arg doesn't get a comma + if (i) Out << ", "; + + // Output type... + printType(FT->getParamType(i)); + + unsigned ArgAttrs = ParamAttr::None; + if (Attrs) ArgAttrs = Attrs->getParamAttrs(i+1); + if (ArgAttrs != ParamAttr::None) + Out << ' ' << ParamAttrsList::getParamAttrsText(ArgAttrs); + } } // Finish printing arguments... @@ -1004,14 +1106,16 @@ void AssemblyWriter::printFunction(const Function *F) { Out << "..."; // Output varargs portion of signature! } Out << ')'; - if (FT->getParamAttrs(0)) - Out << ' ' << FunctionType::getParamAttrsText(FT->getParamAttrs(0)); + if (Attrs && Attrs->getParamAttrs(0) != ParamAttr::None) + Out << ' ' << Attrs->getParamAttrsTextByIndex(0); if (F->hasSection()) Out << " section \"" << F->getSection() << '"'; if (F->getAlignment()) Out << " align " << F->getAlignment(); + if (F->hasCollector()) + Out << " gc \"" << F->getCollector() << '"'; - if (F->isExternal()) { + if (F->isDeclaration()) { Out << "\n"; } else { Out << " {"; @@ -1029,24 +1133,24 @@ void AssemblyWriter::printFunction(const Function *F) { /// printArgument - This member is called for every argument that is passed into /// the function. Simply print it out /// -void AssemblyWriter::printArgument(const Argument *Arg, - FunctionType::ParameterAttributes attrs) { +void AssemblyWriter::printArgument(const Argument *Arg, uint16_t Attrs) { // Output type... printType(Arg->getType()); - if (attrs != FunctionType::NoAttributeSet) - Out << ' ' << FunctionType::getParamAttrsText(attrs); + // Output parameter attributes list + if (Attrs != ParamAttr::None) + Out << ' ' << ParamAttrsList::getParamAttrsText(Attrs); // Output name, if available... if (Arg->hasName()) - Out << ' ' << getLLVMName(Arg->getName()); + Out << ' ' << getLLVMName(Arg->getName(), LocalPrefix); } /// printBasicBlock - This member is called for each basic block in a method. /// void AssemblyWriter::printBasicBlock(const BasicBlock *BB) { if (BB->hasName()) { // Print out the label if it exists... - Out << "\n" << getLLVMName(BB->getName(), false) << ':'; + Out << "\n" << getLLVMName(BB->getName(), LabelPrefix) << ':'; } else if (!BB->use_empty()) { // Don't print block # of no uses... Out << "\n;