#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Config/config.h"
#include <algorithm>
#include <iostream>
#include <set>
GenModule,
GenContents,
GenFunction,
+ GenInline,
GenVariable,
GenType
};
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
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; }
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 );
// 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());
!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
name = std::string("func_");
} else if (const Constant* C = dyn_cast<Constant>(val)) {
name = std::string("const_") + getTypePrefix(C->getType());
+ } else if (const Argument* Arg = dyn_cast<Argument>(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());
}
Out << "ConstantPointerNull* " << constName
<< " = ConstanPointerNull::get(" << typeName << ");";
} else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) {
- Out << "ConstantFP* " << constName << " = ConstantFP::get(" << typeName
- << ", ";
+ Out << "ConstantFP* " << constName << " = ";
printCFP(CFP);
- Out << ");";
+ Out << ";";
} else if (const ConstantArray *CA = dyn_cast<ConstantArray>(CV)) {
if (CA->isString() && CA->getType()->getElementType() == Type::SByteTy) {
Out << "Constant* " << constName << " = ConstantArray::get(\"";
}
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());
printCppName(GV);
Out << "->setAlignment(" << utostr(GV->getAlignment()) << ");\n";
};
+ if (is_inline)
+ Out << "}\n";
}
void
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
Out << "\n// Function Declarations\n";
for (std::vector<GlobalValue*>::iterator I = gvs.begin(), E = gvs.end();
I != E; ++I) {
- if (Function* F = dyn_cast<Function>(*I))
- printFunctionHead(F);
+ if (Function* Fun = dyn_cast<Function>(*I)) {
+ if (!is_inline || Fun != F)
+ printFunctionHead(Fun);
+ }
}
// Print the global variable declarations for any variables encountered
Out << "\n// Constant Definitions\n";
for (std::vector<Constant*>::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
}
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());
printCppName(F);
Out << "->setAlignment(" << F->getAlignment() << ");\n";
}
+ if (is_inline) {
+ Out << "}\n";
+ }
}
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
}
}
+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";
Out << "#include <llvm/BasicBlock.h>\n";
Out << "#include <llvm/Instructions.h>\n";
Out << "#include <llvm/InlineAsm.h>\n";
+ Out << "#include <llvm/Support/MathExtras.h>\n";
Out << "#include <llvm/Pass.h>\n";
Out << "#include <llvm/PassManager.h>\n";
Out << "#include <llvm/Analysis/Verifier.h>\n";
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";