From f977e7bc834449a3658862862a2206b066b01af5 Mon Sep 17 00:00:00 2001 From: Reid Spencer Date: Thu, 1 Jun 2006 23:43:47 +0000 Subject: Teach CppWriter how to emit an inline (partial) function. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@28645 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm2cpp/CppWriter.cpp | 182 +++++++++++++++++++++++++++++++------------ 1 file changed, 132 insertions(+), 50 deletions(-) (limited to 'tools/llvm2cpp') diff --git a/tools/llvm2cpp/CppWriter.cpp b/tools/llvm2cpp/CppWriter.cpp index c7f3b7cc69..c7cbe40d60 100644 --- a/tools/llvm2cpp/CppWriter.cpp +++ b/tools/llvm2cpp/CppWriter.cpp @@ -25,6 +25,7 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Config/config.h" #include #include #include @@ -40,6 +41,7 @@ enum WhatToGenerate { GenModule, GenContents, GenFunction, + GenInline, GenVariable, GenType }; @@ -52,6 +54,7 @@ static cl::opt GenerationType(cl::Optional, clEnumValN(GenModule, "gen-module", "Generate a module definition"), clEnumValN(GenContents,"gen-contents", "Generate contents of a module"), clEnumValN(GenFunction,"gen-function", "Generate a function definition"), + clEnumValN(GenInline, "gen-inline", "Generate an inline function"), clEnumValN(GenVariable,"gen-variable", "Generate a variable definition"), clEnumValN(GenType, "gen-type", "Generate a type definition"), clEnumValEnd @@ -84,11 +87,12 @@ class CppWriter { TypeSet DefinedTypes; ValueSet DefinedValues; ForwardRefMap ForwardRefs; + bool is_inline; public: inline CppWriter(std::ostream &o, const Module *M, const char* pn="llvm2cpp") : progname(pn), Out(o), TheModule(M), uniqueNum(0), TypeNames(), - ValueNames(), UnresolvedTypes(), TypeStack() { } + ValueNames(), UnresolvedTypes(), TypeStack(), is_inline(false) { } const Module* getModule() { return TheModule; } @@ -96,6 +100,7 @@ public: void printModule(const std::string& fname, const std::string& modName ); void printContents(const std::string& fname, const std::string& modName ); void printFunction(const std::string& fname, const std::string& funcName ); + void printInline(const std::string& fname, const std::string& funcName ); void printVariable(const std::string& fname, const std::string& varName ); void printType(const std::string& fname, const std::string& typeName ); @@ -195,6 +200,11 @@ CppWriter::error(const std::string& msg) { // result so that we don't lose precision. void CppWriter::printCFP(const ConstantFP *CFP) { + Out << "ConstantFP::get("; + if (CFP->getType() == Type::DoubleTy) + Out << "Type::DoubleTy, "; + else + Out << "Type::FloatTy, "; #if HAVE_PRINTF_A char Buffer[100]; sprintf(Buffer, "%A", CFP->getValue()); @@ -202,32 +212,37 @@ CppWriter::printCFP(const ConstantFP *CFP) { !strncmp(Buffer, "-0x", 3) || !strncmp(Buffer, "+0x", 3)) && (atof(Buffer) == CFP->getValue())) - Out << Buffer; + if (CFP->getType() == Type::DoubleTy) + Out << "BitsToDouble(" << Buffer << ")"; + else + Out << "BitsToFloat(" << Buffer << ")"; else { -#else - std::string StrVal = ftostr(CFP->getValue()); - - while (StrVal[0] == ' ') - StrVal.erase(StrVal.begin()); - - // Check to make sure that the stringized number is not some string like "Inf" - // or NaN. 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'))) && - (atof(StrVal.c_str()) == CFP->getValue())) - Out << StrVal; - else if (CFP->getType() == Type::DoubleTy) { - Out << "0x" << std::hex << DoubleToBits(CFP->getValue()) << std::dec - << "ULL /* " << StrVal << " */"; - } else { - Out << "0x" << std::hex << FloatToBits(CFP->getValue()) << std::dec - << "U /* " << StrVal << " */"; - } #endif + std::string StrVal = ftostr(CFP->getValue()); + + while (StrVal[0] == ' ') + StrVal.erase(StrVal.begin()); + + // Check to make sure that the stringized number is not some string like + // "Inf" or NaN. 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'))) && + (atof(StrVal.c_str()) == CFP->getValue())) + if (CFP->getType() == Type::DoubleTy) + Out << StrVal; + else + Out << StrVal; + else if (CFP->getType() == Type::DoubleTy) + Out << "BitsToDouble(0x" << std::hex << DoubleToBits(CFP->getValue()) + << std::dec << "ULL) /* " << StrVal << " */"; + else + Out << "BitsToFloat(0x" << std::hex << FloatToBits(CFP->getValue()) + << std::dec << "U) /* " << StrVal << " */"; #if HAVE_PRINTF_A } #endif + Out << ")"; } void @@ -353,6 +368,19 @@ CppWriter::getCppName(const Value* val) { name = std::string("func_"); } else if (const Constant* C = dyn_cast(val)) { name = std::string("const_") + getTypePrefix(C->getType()); + } else if (const Argument* Arg = dyn_cast(val)) { + if (is_inline) { + unsigned argNum = std::distance(Arg->getParent()->arg_begin(), + Function::const_arg_iterator(Arg)) + 1; + name = std::string("arg_") + utostr(argNum); + NameSet::iterator NI = UsedNames.find(name); + if (NI != UsedNames.end()) + name += std::string("_") + utostr(uniqueNum++); + UsedNames.insert(name); + return ValueNames[val] = name; + } else { + name = getTypePrefix(val->getType()); + } } else { name = getTypePrefix(val->getType()); } @@ -629,10 +657,9 @@ void CppWriter::printConstant(const Constant *CV) { Out << "ConstantPointerNull* " << constName << " = ConstanPointerNull::get(" << typeName << ");"; } else if (const ConstantFP *CFP = dyn_cast(CV)) { - Out << "ConstantFP* " << constName << " = ConstantFP::get(" << typeName - << ", "; + Out << "ConstantFP* " << constName << " = "; printCFP(CFP); - Out << ");"; + Out << ";"; } else if (const ConstantArray *CA = dyn_cast(CV)) { if (CA->isString() && CA->getType()->getElementType() == Type::SByteTy) { Out << "Constant* " << constName << " = ConstantArray::get(\""; @@ -788,9 +815,13 @@ void CppWriter::printVariableUses(const GlobalVariable *GV) { } void CppWriter::printVariableHead(const GlobalVariable *GV) { - Out << "\n"; - Out << "GlobalVariable* "; - printCppName(GV); + Out << "\nGlobalVariable* " << getCppName(GV); + if (is_inline) { + Out << " = mod->getGlobalVariable("; + printEscapedString(GV->getName()); + Out << ", " << getCppName(GV->getType()->getElementType()) << ",true)\n"; + Out << "if (!" << getCppName(GV) << ") {\n " << getCppName(GV); + } Out << " = new GlobalVariable(\n"; Out << " /*Type=*/"; printCppName(GV->getType()->getElementType()); @@ -816,6 +847,8 @@ void CppWriter::printVariableHead(const GlobalVariable *GV) { printCppName(GV); Out << "->setAlignment(" << utostr(GV->getAlignment()) << ");\n"; }; + if (is_inline) + Out << "}\n"; } void @@ -1168,16 +1201,18 @@ CppWriter::printInstruction(const Instruction *I, const std::string& bbname) { void CppWriter::printFunctionUses(const Function* F) { Out << "\n// Type Definitions\n"; - // Print the function's return type - printType(F->getReturnType()); + if (!is_inline) { + // Print the function's return type + printType(F->getReturnType()); - // Print the function's function type - printType(F->getFunctionType()); + // Print the function's function type + printType(F->getFunctionType()); - // Print the types of each of the function's arguments - for(Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end(); - AI != AE; ++AI) { - printType(AI->getType()); + // Print the types of each of the function's arguments + for(Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end(); + AI != AE; ++AI) { + printType(AI->getType()); + } } // Print type definitions for every type referenced by an instruction and @@ -1206,8 +1241,10 @@ void CppWriter::printFunctionUses(const Function* F) { Out << "\n// Function Declarations\n"; for (std::vector::iterator I = gvs.begin(), E = gvs.end(); I != E; ++I) { - if (Function* F = dyn_cast(*I)) - printFunctionHead(F); + if (Function* Fun = dyn_cast(*I)) { + if (!is_inline || Fun != F) + printFunctionHead(Fun); + } } // Print the global variable declarations for any variables encountered @@ -1222,7 +1259,7 @@ void CppWriter::printFunctionUses(const Function* F) { Out << "\n// Constant Definitions\n"; for (std::vector::iterator I = consts.begin(), E = consts.end(); I != E; ++I) { - printConstant(F); + printConstant(*I); } // Process the global variables definitions now that all the constants have @@ -1237,7 +1274,15 @@ void CppWriter::printFunctionUses(const Function* F) { } void CppWriter::printFunctionHead(const Function* F) { - Out << "\nFunction* " << getCppName(F) << " = new Function(\n" + Out << "\nFunction* " << getCppName(F); + if (is_inline) { + Out << " = mod->getFunction(\""; + printEscapedString(F->getName()); + Out << "\", " << getCppName(F->getFunctionType()) << ");\n"; + Out << "if (!" << getCppName(F) << ") {\n"; + Out << getCppName(F); + } + Out<< " = new Function(\n" << " /*Type=*/" << getCppName(F->getFunctionType()) << ",\n" << " /*Linkage=*/"; printLinkageType(F->getLinkage()); @@ -1257,6 +1302,9 @@ void CppWriter::printFunctionHead(const Function* F) { printCppName(F); Out << "->setAlignment(" << F->getAlignment() << ");\n"; } + if (is_inline) { + Out << "}\n"; + } } void CppWriter::printFunctionBody(const Function *F) { @@ -1269,16 +1317,18 @@ void CppWriter::printFunctionBody(const Function *F) { DefinedValues.clear(); // Create all the argument values - if (!F->arg_empty()) { - Out << " Function::arg_iterator args = " << getCppName(F) - << "->arg_begin();\n"; - } - for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end(); - AI != AE; ++AI) { - Out << " Value* " << getCppName(AI) << " = args++;\n"; - if (AI->hasName()) - Out << " " << getCppName(AI) << "->setName(\"" << AI->getName() - << "\");\n"; + if (!is_inline) { + if (!F->arg_empty()) { + Out << " Function::arg_iterator args = " << getCppName(F) + << "->arg_begin();\n"; + } + for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end(); + AI != AE; ++AI) { + Out << " Value* " << getCppName(AI) << " = args++;\n"; + if (AI->hasName()) + Out << " " << getCppName(AI) << "->setName(\"" << AI->getName() + << "\");\n"; + } } // Create all the basic blocks @@ -1317,6 +1367,32 @@ void CppWriter::printFunctionBody(const Function *F) { } } +void CppWriter::printInline(const std::string& fname, const std::string& func) { + const Function* F = TheModule->getNamedFunction(func); + if (!F) { + error(std::string("Function '") + func + "' not found in input module"); + return; + } + if (F->isExternal()) { + error(std::string("Function '") + func + "' is external!"); + return; + } + Out << "\nBasicBlock* " << fname << "(Module* mod, Function *" + << getCppName(F); + unsigned arg_count = 1; + for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end(); + AI != AE; ++AI) { + Out << ", Value* arg_" << arg_count; + } + Out << ") {\n"; + is_inline = true; + printFunctionUses(F); + printFunctionBody(F); + is_inline = false; + Out << "return " << getCppName(F->begin()) << ";\n"; + Out << "}\n"; +} + void CppWriter::printModuleBody() { // Print out all the type definitions Out << "\n// Type Definitions\n"; @@ -1378,6 +1454,7 @@ void CppWriter::printProgram( Out << "#include \n"; Out << "#include \n"; Out << "#include \n"; + Out << "#include \n"; Out << "#include \n"; Out << "#include \n"; Out << "#include \n"; @@ -1551,6 +1628,11 @@ void WriteModuleToCppFile(Module* mod, std::ostream& o) { fname = "makeLLVMFunction"; W.printFunction(fname,tgtname); break; + case GenInline: + if (fname.empty()) + fname = "makeLLVMInline"; + W.printInline(fname,tgtname); + break; case GenVariable: if (fname.empty()) fname = "makeLLVMVariable"; -- cgit v1.2.3