aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2013-11-21 18:15:26 -0800
committerAlon Zakai <alonzakai@gmail.com>2013-11-21 18:15:26 -0800
commitb7e3f2ec069cb331749db389636f735551e37bdb (patch)
tree220767c0d61ba81c3d54a78456898e78c74f4d94
parent902015756b37260b51e6da6a7c9ae67e96a55b52 (diff)
merge in CppBackend work
-rw-r--r--lib/Target/CppBackend/CMakeLists.txt1
-rw-r--r--lib/Target/CppBackend/CPPBackend.cpp1010
-rw-r--r--lib/Target/CppBackend/Relooper.cpp1287
-rw-r--r--lib/Target/CppBackend/Relooper.h251
-rw-r--r--lib/Target/CppBackend/TargetInfo/CppBackendTargetInfo.cpp4
5 files changed, 2098 insertions, 455 deletions
diff --git a/lib/Target/CppBackend/CMakeLists.txt b/lib/Target/CppBackend/CMakeLists.txt
index 515e1dd7e3..7e138b2695 100644
--- a/lib/Target/CppBackend/CMakeLists.txt
+++ b/lib/Target/CppBackend/CMakeLists.txt
@@ -1,5 +1,6 @@
add_llvm_target(CppBackendCodeGen
CPPBackend.cpp
+ Relooper.cpp
)
add_subdirectory(TargetInfo)
diff --git a/lib/Target/CppBackend/CPPBackend.cpp b/lib/Target/CppBackend/CPPBackend.cpp
index 3e69098edc..299db973f8 100644
--- a/lib/Target/CppBackend/CPPBackend.cpp
+++ b/lib/Target/CppBackend/CPPBackend.cpp
@@ -38,6 +38,10 @@
#include <set>
using namespace llvm;
+#define dump(x, ...) fprintf(stderr, x, __VA_ARGS__)
+
+#include <Relooper.h>
+
static cl::opt<std::string>
FuncName("cppfname", cl::desc("Specify the name of the generated function"),
cl::value_desc("function name"));
@@ -85,7 +89,10 @@ namespace {
typedef std::set<std::string> NameSet;
typedef std::set<Type*> TypeSet;
typedef std::set<const Value*> ValueSet;
+ typedef std::map<std::string, Type::TypeID> VarMap;
typedef std::map<const Value*,std::string> ForwardRefMap;
+ typedef std::vector<unsigned char> HeapData;
+ typedef std::pair<unsigned, unsigned> Address;
/// CppWriter - This class is the main chunk of code that converts an LLVM
/// module to a C++ translation unit.
@@ -98,14 +105,20 @@ namespace {
NameSet UsedNames;
TypeSet DefinedTypes;
ValueSet DefinedValues;
+ VarMap UsedVars;
ForwardRefMap ForwardRefs;
bool is_inline;
unsigned indent_level;
+ HeapData GlobalData8;
+ HeapData GlobalData32;
+ HeapData GlobalData64;
+ std::map<std::string, Address> GlobalAddresses;
public:
static char ID;
explicit CppWriter(formatted_raw_ostream &o) :
- ModulePass(ID), Out(o), uniqueNum(0), is_inline(false), indent_level(0){}
+ ModulePass(ID), Out(o), uniqueNum(0), is_inline(false), indent_level(0){
+ }
virtual const char *getPassName() const { return "C++ backend"; }
@@ -134,7 +147,28 @@ namespace {
void printCallingConv(CallingConv::ID cc);
void printEscapedString(const std::string& str);
void printCFP(const ConstantFP* CFP);
-
+ void printCommaSeparated(const HeapData v);
+
+ void allocateConstant(const Constant* CV);
+ unsigned getGlobalAddress(const std::string &s) {
+ Address a = GlobalAddresses[s];
+ switch (a.second) {
+ case 64:
+ return a.first + 8;
+ case 32:
+ return a.first + 8 + GlobalData64.size();
+ case 8:
+ return a.first + 8 + GlobalData64.size() + GlobalData32.size();
+ default:
+ assert(false);
+ }
+ }
+ std::string getPtrLoad(const Value* Ptr);
+ std::string getPtrUse(const Value* Ptr);
+ std::string getPtr(const Value* Ptr);
+ std::string getConstant(const Constant*);
+ std::string getValueAsStr(const Value*);
+ std::string getValueAsParenStr(const Value*);
std::string getCppName(Type* val);
inline void printCppName(Type* val);
@@ -145,6 +179,10 @@ namespace {
void printType(Type* Ty);
void printTypes(const Module* M);
+ std::string getAssign(const StringRef &, const Type *);
+ std::string getCast(const StringRef &, const Type *);
+ std::string getParenCast(const StringRef &, const Type *);
+
void printConstant(const Constant *CPV);
void printConstants(const Module* M);
@@ -155,10 +193,14 @@ namespace {
void printFunctionUses(const Function *F);
void printFunctionHead(const Function *F);
void printFunctionBody(const Function *F);
- void printInstruction(const Instruction *I, const std::string& bbname);
+ std::string generateInstruction(const Instruction *I);
std::string getOpName(const Value*);
void printModuleBody();
+
+ unsigned stackAlign(unsigned x) {
+ return x + (x%4 != 0 ? 4 - x%4 : 0);
+ }
};
} // end anonymous namespace.
@@ -171,8 +213,8 @@ formatted_raw_ostream &CppWriter::nl(formatted_raw_ostream &Out, int delta) {
}
static inline void sanitize(std::string &str) {
- for (size_t i = 0; i < str.length(); ++i)
- if (!isalnum(str[i]) && str[i] != '_')
+ for (size_t i = 1; i < str.length(); ++i)
+ if (!isalnum(str[i]) && str[i] != '_' && str[i] != '$')
str[i] = '_';
}
@@ -217,8 +259,6 @@ void CppWriter::printCFP(const ConstantFP *CFP) {
APFloat APF = APFloat(CFP->getValueAPF()); // copy
if (CFP->getType() == Type::getFloatTy(CFP->getContext()))
APF.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven, &ignored);
- Out << "ConstantFP::get(mod->getContext(), ";
- Out << "APFloat(";
#if HAVE_PRINTF_A
char Buffer[100];
sprintf(Buffer, "%A", APF.convertToDouble());
@@ -257,11 +297,9 @@ void CppWriter::printCFP(const ConstantFP *CFP) {
<< utohexstr((uint32_t)CFP->getValueAPF().
bitcastToAPInt().getZExtValue())
<< "U) /* " << StrVal << " */";
- Out << ")";
#if HAVE_PRINTF_A
}
#endif
- Out << ")";
}
void CppWriter::printCallingConv(CallingConv::ID cc){
@@ -423,40 +461,46 @@ std::string CppWriter::getCppName(const Value* val) {
std::string name;
ValueMap::iterator I = ValueNames.find(val);
if (I != ValueNames.end() && I->first == val)
- return I->second;
-
- if (const GlobalVariable* GV = dyn_cast<GlobalVariable>(val)) {
- name = std::string("gvar_") +
- getTypePrefix(GV->getType()->getElementType());
- } else if (isa<Function>(val)) {
- 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;
+ return I->second;
+
+ if (val->hasName()) {
+ if (dyn_cast<Function>(val)) {
+ name = std::string("_") + val->getName().str();
} else {
- name = getTypePrefix(val->getType());
+ name = std::string("$") + val->getName().str();
}
+ sanitize(name);
} else {
- name = getTypePrefix(val->getType());
- }
- if (val->hasName())
- name += val->getName();
- else
+ if (const GlobalVariable* GV = dyn_cast<GlobalVariable>(val)) {
+ name = std::string("gvar_") +
+ getTypePrefix(GV->getType()->getElementType());
+ } else if (isa<Function>(val)) {
+ 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());
+ }
name += utostr(uniqueNum++);
- sanitize(name);
- NameSet::iterator NI = UsedNames.find(name);
- if (NI != UsedNames.end())
- name += std::string("_") + utostr(uniqueNum++);
- UsedNames.insert(name);
+ sanitize(name);
+ NameSet::iterator NI = UsedNames.find(name);
+ if (NI != UsedNames.end())
+ name += std::string("_") + utostr(uniqueNum++);
+ UsedNames.insert(name);
+ }
return ValueNames[val] = name;
}
@@ -710,6 +754,29 @@ void CppWriter::printTypes(const Module* M) {
}
+std::string CppWriter::getAssign(const StringRef &s, const Type *t) {
+ UsedVars[s] = t->getTypeID();
+ return (s + " = ").str();
+}
+
+std::string CppWriter::getCast(const StringRef &s, const Type *t) {
+ switch (t->getTypeID()) {
+ default:
+ assert(false && "Unsupported type");
+ case Type::FloatTyID:
+ // TODO return ("Math_fround(" + s + ")").str();
+ case Type::DoubleTyID:
+ return ("+" + s).str();
+ case Type::IntegerTyID:
+ case Type::PointerTyID:
+ return (s + "|0").str();
+ }
+}
+
+std::string CppWriter::getParenCast(const StringRef &s, const Type *t) {
+ return getCast(("(" + s + ")").str(), t);
+}
+
// printConstant - Print out a constant pool entry...
void CppWriter::printConstant(const Constant *CV) {
// First, if the constant is actually a GlobalValue (variable or function)
@@ -721,20 +788,16 @@ void CppWriter::printConstant(const Constant *CV) {
std::string constName(getCppName(CV));
std::string typeName(getCppName(CV->getType()));
+ //Out << "var " << constName << " = ";
+
if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
std::string constValue = CI->getValue().toString(10, true);
- Out << "ConstantInt* " << constName
- << " = ConstantInt::get(mod->getContext(), APInt("
- << cast<IntegerType>(CI->getType())->getBitWidth()
- << ", StringRef(\"" << constValue << "\"), 10));";
+ Out << constValue << ";";
} else if (isa<ConstantAggregateZero>(CV)) {
- Out << "ConstantAggregateZero* " << constName
- << " = ConstantAggregateZero::get(" << typeName << ");";
+ Out << "ConstantAggregateZero::get(" << typeName << ");";
} else if (isa<ConstantPointerNull>(CV)) {
- Out << "ConstantPointerNull* " << constName
- << " = ConstantPointerNull::get(" << typeName << ");";
+ Out << "ConstantPointerNull::get(" << typeName << ");";
} else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) {
- Out << "ConstantFP* " << constName << " = ";
printCFP(CFP);
Out << ";";
} else if (const ConstantArray *CA = dyn_cast<ConstantArray>(CV)) {
@@ -779,20 +842,13 @@ void CppWriter::printConstant(const Constant *CV) {
} else if (const ConstantDataSequential *CDS =
dyn_cast<ConstantDataSequential>(CV)) {
if (CDS->isString()) {
- Out << "Constant *" << constName <<
- " = ConstantDataArray::getString(mod->getContext(), \"";
+ Out << "allocate([";
StringRef Str = CDS->getAsString();
- bool nullTerminate = false;
- if (Str.back() == 0) {
- Str = Str.drop_back();
- nullTerminate = true;
+ for (unsigned int i = 0; i < Str.size(); i++) {
+ Out << (unsigned int)(Str.data()[i]);
+ if (i < Str.size()-1) Out << ",";
}
- printEscapedString(Str);
- // Determine if we want null termination or not.
- if (nullTerminate)
- Out << "\", true);";
- else
- Out << "\", false);";// No null terminator
+ Out << "], 'i8', ALLOC_STATIC);";
} else {
// TODO: Could generate more efficient code generating CDS calls instead.
Out << "std::vector<Constant*> " << constName << "_elems;";
@@ -813,19 +869,12 @@ void CppWriter::printConstant(const Constant *CV) {
}
} else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV)) {
if (CE->getOpcode() == Instruction::GetElementPtr) {
- Out << "std::vector<Constant*> " << constName << "_indices;";
- nl(Out);
- printConstant(CE->getOperand(0));
- for (unsigned i = 1; i < CE->getNumOperands(); ++i ) {
- printConstant(CE->getOperand(i));
- Out << constName << "_indices.push_back("
- << getCppName(CE->getOperand(i)) << ");";
- nl(Out);
+ Out << "allocate([";
+ for (unsigned i = 0; i < CE->getNumOperands(); ++i ) {
+ Out << getCppName(CE->getOperand(i));
+ if (i < CE->getNumOperands()-1) Out << ",";
}
- Out << "Constant* " << constName
- << " = ConstantExpr::getGetElementPtr("
- << getCppName(CE->getOperand(0)) << ", "
- << constName << "_indices);";
+ Out << "], 'i32', ALLOC_STATIC);";
} else if (CE->isCast()) {
printConstant(CE->getOperand(0));
Out << "Constant* " << constName << " = ConstantExpr::getCast(";
@@ -936,8 +985,11 @@ void CppWriter::printConstants(const Module* M) {
// Traverse all the global variables looking for constant initializers
for (Module::const_global_iterator I = TheModule->global_begin(),
E = TheModule->global_end(); I != E; ++I)
- if (I->hasInitializer())
- printConstant(I->getInitializer());
+ if (I->hasInitializer()) {
+ const Constant *CV = I->getInitializer();
+ allocateConstant(CV);
+ GlobalAddresses[I->getName().str()] = GlobalAddresses[getCppName(CV)];
+ }
// Traverse the LLVM functions looking for constants
for (Module::const_iterator FI = TheModule->begin(), FE = TheModule->end();
@@ -949,7 +1001,7 @@ void CppWriter::printConstants(const Module* M) {
++I) {
for (unsigned i = 0; i < I->getNumOperands(); ++i) {
if (Constant* C = dyn_cast<Constant>(I->getOperand(i))) {
- printConstant(C);
+ allocateConstant(C);
}
}
}
@@ -958,91 +1010,19 @@ void CppWriter::printConstants(const Module* M) {
}
void CppWriter::printVariableUses(const GlobalVariable *GV) {
- nl(Out) << "// Type Definitions";
- nl(Out);
- printType(GV->getType());
- if (GV->hasInitializer()) {
- const Constant *Init = GV->getInitializer();
- printType(Init->getType());
- if (const Function *F = dyn_cast<Function>(Init)) {
- nl(Out)<< "/ Function Declarations"; nl(Out);
- printFunctionHead(F);
- } else if (const GlobalVariable* gv = dyn_cast<GlobalVariable>(Init)) {
- nl(Out) << "// Global Variable Declarations"; nl(Out);
- printVariableHead(gv);
-
- nl(Out) << "// Global Variable Definitions"; nl(Out);
- printVariableBody(gv);
- } else {
- nl(Out) << "// Constant Definitions"; nl(Out);
- printConstant(Init);
- }
- }
}
void CppWriter::printVariableHead(const GlobalVariable *GV) {
- nl(Out) << "GlobalVariable* " << getCppName(GV);
- if (is_inline) {
- Out << " = mod->getGlobalVariable(mod->getContext(), ";
- printEscapedString(GV->getName());
- Out << ", " << getCppName(GV->getType()->getElementType()) << ",true)";
- nl(Out) << "if (!" << getCppName(GV) << ") {";
- in(); nl(Out) << getCppName(GV);
- }
- Out << " = new GlobalVariable(/*Module=*/*mod, ";
- nl(Out) << "/*Type=*/";
- printCppName(GV->getType()->getElementType());
- Out << ",";
- nl(Out) << "/*isConstant=*/" << (GV->isConstant()?"true":"false");
- Out << ",";
- nl(Out) << "/*Linkage=*/";
- printLinkageType(GV->getLinkage());
- Out << ",";
- nl(Out) << "/*Initializer=*/0, ";
- if (GV->hasInitializer()) {
- Out << "// has initializer, specified below";
- }
- nl(Out) << "/*Name=*/\"";
- printEscapedString(GV->getName());
- Out << "\");";
- nl(Out);
-
- if (GV->hasSection()) {
- printCppName(GV);
- Out << "->setSection(\"";
- printEscapedString(GV->getSection());
- Out << "\");";
- nl(Out);
- }
- if (GV->getAlignment()) {
- printCppName(GV);
- Out << "->setAlignment(" << utostr(GV->getAlignment()) << ");";
- nl(Out);
- }
- if (GV->getVisibility() != GlobalValue::DefaultVisibility) {
- printCppName(GV);
- Out << "->setVisibility(";
- printVisibilityType(GV->getVisibility());
- Out << ");";
- nl(Out);
- }
- if (GV->isThreadLocal()) {
- printCppName(GV);
- Out << "->setThreadLocalMode(";
- printThreadLocalMode(GV->getThreadLocalMode());
- Out << ");";
- nl(Out);
- }
- if (is_inline) {
- out(); Out << "}"; nl(Out);
- }
+ Out << "var ";
+ printCppName(GV);
+ Out << ";\n";
}
void CppWriter::printVariableBody(const GlobalVariable *GV) {
if (GV->hasInitializer()) {
printCppName(GV);
- Out << "->setInitializer(";
- Out << getCppName(GV->getInitializer()) << ");";
+ Out << " = ";
+ Out << getCppName(GV->getInitializer()) << ";";
nl(Out);
}
}
@@ -1091,9 +1071,98 @@ static StringRef ConvertAtomicSynchScope(SynchronizationScope SynchScope) {
llvm_unreachable("Unknown synch scope");
}
-// printInstruction - This member is called for each Instruction in a function.
-void CppWriter::printInstruction(const Instruction *I,
- const std::string& bbname) {
+std::string CppWriter::getPtrLoad(const Value* Ptr) {
+ Type *t = cast<PointerType>(Ptr->getType())->getElementType();
+ return getCast(getPtrUse(Ptr), t);
+}
+
+std::string CppWriter::getPtrUse(const Value* Ptr) {
+ Type *t = cast<PointerType>(Ptr->getType())->getElementType();
+ if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Ptr)) {
+ std::string text = "";
+ unsigned Addr = getGlobalAddress(GV->getName().str());
+ switch (t->getTypeID()) {
+ default:
+ assert(false && "Unsupported type");
+ case Type::DoubleTyID:
+ return "HEAPF64[" + utostr(Addr >> 3) + "]";
+ case Type::FloatTyID:
+ return "HEAPF32[" + utostr(Addr >> 2) + "]";
+ case Type::IntegerTyID:
+ return "HEAP32[" + utostr(Addr >> 2) + "]";
+ }
+ } else {
+ switch (t->getTypeID()) {
+ default:
+ assert(false && "Unsupported type");
+ case Type::DoubleTyID:
+ return "HEAPF64[" + getOpName(Ptr) + ">>3]";
+ case Type::FloatTyID:
+ return "HEAPF32[" + getOpName(Ptr) + ">>2]";
+ case Type::IntegerTyID:
+ case Type::PointerTyID:
+ return "HEAP32[" + getOpName(Ptr) + ">>2]";
+ }
+ }
+}
+
+std::string CppWriter::getPtr(const Value* Ptr) {
+ Type *t = cast<PointerType>(Ptr->getType())->getElementType();
+ if (const Constant *CV = dyn_cast<Constant>(Ptr)) {
+ std::string text = "";
+ unsigned Addr = getGlobalAddress(CV->getName().str());
+ switch (t->getTypeID()) {
+ default:
+ assert(false && "Unsupported type");
+ case Type::DoubleTyID:
+ return utostr(Addr >> 3);
+ case Type::FloatTyID:
+ return utostr(Addr >> 2);
+ case Type::ArrayTyID:
+ case Type::StructTyID:
+ case Type::PointerTyID:
+ case Type::VectorTyID:
+ case Type::IntegerTyID:
+ return utostr(Addr >> 2);
+ }
+ } else {
+ return getOpName(Ptr) + "|0";
+ }
+}
+
+std::string CppWriter::getConstant(const Constant* CV) {
+ if (/* const PointerType *Ptr = */ dyn_cast<PointerType>(CV->getType())) {
+ return getPtr(CV);
+ } else {
+ if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) {
+ std::string S = ftostr(CFP->getValueAPF());
+ S = '+' + S;
+// if (S.find('.') == S.npos) { TODO: do this when necessary, but it is necessary even for 0.0001
+ return S;
+ } else if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
+ return CI->getValue().toString(10, true);
+ } else {
+ assert(false);
+ }
+ }
+}
+
+std::string CppWriter::getValueAsStr(const Value* V) {
+ if (const Constant *CV = dyn_cast<Constant>(V)) {
+ return getConstant(CV);
+ } else {
+ return getCast(getCppName(V), V->getType());
+ }
+}
+
+std::string CppWriter::getValueAsParenStr(const Value* V) {
+ return "(" + getValueAsStr(V) + ")";
+}
+
+// generateInstruction - This member is called for each Instruction in a function.
+std::string CppWriter::generateInstruction(const Instruction *I) {
+ std::string text = "NYI: " + std::string(I->getOpcodeName());
+ std::string bbname = "NO_BBNAME";
std::string iName(getCppName(I));
// Before we emit this instruction, we need to take care of generating any
@@ -1110,24 +1179,18 @@ void CppWriter::printInstruction(const Instruction *I,
case Instruction::Ret: {
const ReturnInst* ret = cast<ReturnInst>(I);
- Out << "ReturnInst::Create(mod->getContext(), "
- << (ret->getReturnValue() ? opNames[0] + ", " : "") << bbname << ");";
+ Value *RV = ret->getReturnValue();
+ text = "STACKTOP = sp;";
+ text += "return";
+ if (RV == NULL) {
+ text += ";";
+ } else {
+ text += " " + getValueAsStr(RV) + ";";
+ }
break;
}
case Instruction::Br: {
- const BranchInst* br = cast<BranchInst>(I);
- Out << "BranchInst::Create(" ;
- if (br->getNumOperands() == 3) {
- Out << opNames[2] << ", "
- << opNames[1] << ", "
- << opNames[0] << ", ";
-
- } else if (br->getNumOperands() == 1) {
- Out << opNames[0] << ", ";
- } else {
- error("Branch with 2 operands?");
- }
- Out << bbname << ");";
+ text = "";
break;
}
case Instruction::Switch: {
@@ -1213,14 +1276,15 @@ void CppWriter::printInstruction(const Instruction *I,
case Instruction::Shl:
case Instruction::LShr:
case Instruction::AShr:{
- Out << "BinaryOperator* " << iName << " = BinaryOperator::Create(";
+ //Out << "BinaryOperator* " << iName << " = BinaryOperator::Create(";
+ text = getAssign(iName, Type::getInt32Ty(I->getContext()));
switch (I->getOpcode()) {
- case Instruction::Add: Out << "Instruction::Add"; break;
+ case Instruction::Add: text += getParenCast(getValueAsParenStr(I->getOperand(0)) + " + " + getValueAsParenStr(I->getOperand(1)), Type::getInt32Ty(I->getContext())) + ";"; break;
case Instruction::FAdd: Out << "Instruction::FAdd"; break;
- case Instruction::Sub: Out << "Instruction::Sub"; break;
+ case Instruction::Sub: text += getParenCast(getValueAsParenStr(I->getOperand(0)) + " - " + getValueAsParenStr(I->getOperand(1)), Type::getInt32Ty(I->getContext())) + ";"; break;
case Instruction::FSub: Out << "Instruction::FSub"; break;
case Instruction::Mul: Out << "Instruction::Mul"; break;
- case Instruction::FMul: Out << "Instruction::FMul"; break;
+ case Instruction::FMul: text += getParenCast(getValueAsStr(I->getOperand(0)) + " * " + getValueAsStr(I->getOperand(1)), I->getType()) + ";"; break;
case Instruction::UDiv:Out << "Instruction::UDiv"; break;
case Instruction::SDiv:Out << "Instruction::SDiv"; break;
case Instruction::FDiv:Out << "Instruction::FDiv"; break;
@@ -1235,9 +1299,9 @@ void CppWriter::printInstruction(const Instruction *I,
case Instruction::AShr:Out << "Instruction::AShr"; break;
default: Out << "Instruction::BadOpCode"; break;
}
- Out << ", " << opNames[0] << ", " << opNames[1] << ", \"";
- printEscapedString(I->getName());
- Out << "\", " << bbname << ");";
+ //Out << ", " << opNames[0] << ", " << opNames[1] << ", \"";
+ //printEscapedString(I->getName());
+ //Out << "\", " << bbname << ");";
break;
}
case Instruction::FCmp: {
@@ -1267,96 +1331,59 @@ void CppWriter::printInstruction(const Instruction *I,
break;
}
case Instruction::ICmp: {
- Out << "ICmpInst* " << iName << " = new ICmpInst(*" << bbname << ", ";
+ text = getAssign(iName, Type::getInt32Ty(I->getContext())) + "(" + getValueAsStr(I->getOperand(0)) + ")";
switch (cast<ICmpInst>(I)->getPredicate()) {
- case ICmpInst::ICMP_EQ: Out << "ICmpInst::ICMP_EQ"; break;
- case ICmpInst::ICMP_NE: Out << "ICmpInst::ICMP_NE"; break;
- case ICmpInst::ICMP_ULE: Out << "ICmpInst::ICMP_ULE"; break;
- case ICmpInst::ICMP_SLE: Out << "ICmpInst::ICMP_SLE"; break;
- case ICmpInst::ICMP_UGE: Out << "ICmpInst::ICMP_UGE"; break;
- case ICmpInst::ICMP_SGE: Out << "ICmpInst::ICMP_SGE"; break;
- case ICmpInst::ICMP_ULT: Out << "ICmpInst::ICMP_ULT"; break;
- case ICmpInst::ICMP_SLT: Out << "ICmpInst::ICMP_SLT"; break;
- case ICmpInst::ICMP_UGT: Out << "ICmpInst::ICMP_UGT"; break;
- case ICmpInst::ICMP_SGT: Out << "ICmpInst::ICMP_SGT"; break;
- default: Out << "ICmpInst::BAD_ICMP_PREDICATE"; break;
+ case ICmpInst::ICMP_EQ: text += "=="; break;
+ case ICmpInst::ICMP_NE: text += "!="; break;
+ // TODO: handle signed and unsigned
+ case ICmpInst::ICMP_ULE: text += "<="; break;
+ case ICmpInst::ICMP_SLE: text += "<="; break;
+ case ICmpInst::ICMP_UGE: text += ">="; break;
+ case ICmpInst::ICMP_SGE: text += ">="; break;
+ case ICmpInst::ICMP_ULT: text += "<"; break;
+ case ICmpInst::ICMP_SLT: text += "<"; break;
+ case ICmpInst::ICMP_UGT: text += ">"; break;
+ case ICmpInst::ICMP_SGT: text += ">"; break;
+ default: text += "ICmpInst::BAD_ICMP_PREDICATE"; break;
}
- Out << ", " << opNames[0] << ", " << opNames[1] << ", \"";
- printEscapedString(I->getName());
- Out << "\");";
+ text += "(" + getValueAsStr(I->getOperand(1)) + ")";
break;
}
case Instruction::Alloca: {
const AllocaInst* allocaI = cast<AllocaInst>(I);
- Out << "AllocaInst* " << iName << " = new AllocaInst("
- << getCppName(allocaI->getAllocatedType()) << ", ";
- if (allocaI->isArrayAllocation())
- Out << opNames[0] << ", ";
- Out << "\"";
- printEscapedString(allocaI->getName());
- Out << "\", " << bbname << ");";
- if (allocaI->getAlignment())
- nl(Out) << iName << "->setAlignment("
- << allocaI->getAlignment() << ");";
+ Type *t = allocaI->getAllocatedType();
+ unsigned size;
+ if (ArrayType *AT = dyn_cast<ArrayType>(t)) {
+ size = AT->getElementType()->getScalarSizeInBits()/8 * AT->getNumElements();
+ } else {
+ size = t->getScalarSizeInBits()/8;
+ }
+ text = getAssign(iName, Type::getInt32Ty(I->getContext())) + "STACKTOP; STACKTOP = STACKTOP + " + Twine(stackAlign(size)).str() + "|0;";
break;
}
case Instruction::Load: {
- const LoadInst* load = cast<LoadInst>(I);
- Out << "LoadInst* " << iName << " = new LoadInst("
- << opNames[0] << ", \"";
- printEscapedString(load->getName());
- Out << "\", " << (load->isVolatile() ? "true" : "false" )
- << ", " << bbname << ");";
- if (load->getAlignment())
- nl(Out) << iName << "->setAlignment("
- << load->getAlignment() << ");";
- if (load->isAtomic()) {
- StringRef Ordering = ConvertAtomicOrdering(load->getOrdering());
- StringRef CrossThread = ConvertAtomicSynchScope(load->getSynchScope());
- nl(Out) << iName << "->setAtomic("
- << Ordering << ", " << CrossThread << ");";
- }
+ const LoadInst *LI = cast<LoadInst>(I);
+ const Value *Ptr = LI->getPointerOperand();
+ Type *t = cast<PointerType>(Ptr->getType())->getElementType();
+ text = getAssign(iName, t) + getPtrLoad(Ptr) + ";";
break;
}
case Instruction::Store: {
- const StoreInst* store = cast<StoreInst>(I);
- Out << "StoreInst* " << iName << " = new StoreInst("
- << opNames[0] << ", "
- << opNames[1] << ", "
- << (store->isVolatile() ? "true" : "false")
- << ", " << bbname << ");";
- if (store->getAlignment())
- nl(Out) << iName << "->setAlignment("
- << store->getAlignment() << ");";
- if (store->isAtomic()) {
- StringRef Ordering = ConvertAtomicOrdering(store->getOrdering());
- StringRef CrossThread = ConvertAtomicSynchScope(store->getSynchScope());
- nl(Out) << iName << "->setAtomic("
- << Ordering << ", " << CrossThread << ");";
+ const StoreInst *SI = cast<StoreInst>(I);
+ const Value *P = SI->getPointerOperand();
+ const Value *V = SI->getValueOperand();
+ std::string VS = getValueAsStr(V);
+ if (V->getType()->isDoubleTy() && SI->getAlignment() == 4) {
+ // only 4-byte aligned, copy carefully
+ std::string PS = getOpName(P);
+ text = "HEAPF64[tempDoublePtr>>3]=" + VS + ";HEAPF32[" + PS + ">>2]=HEAPF32[tempDoublePtr>>2];HEAPF32[" + PS + "+4>>2]=HEAPF32[tempDoublePtr+4>>2];";
+ } else {
+ text = getPtrUse(P) + " = " + VS + ";";
}
break;
}
case Instruction::GetElementPtr: {
- const GetElementPtrInst* gep = cast<GetElementPtrInst>(I);
- if (gep->getNumOperands() <= 2) {
- Out << "GetElementPtrInst* " << iName << " = GetElementPtrInst::Create("
- << opNames[0];
- if (gep->getNumOperands() == 2)
- Out << ", " << opNames[1];
- } else {
- Out << "std::vector<Value*> " << iName << "_indices;";
- nl(Out);
- for (unsigned i = 1; i < gep->getNumOperands(); ++i ) {
- Out << iName << "_indices.push_back("
- << opNames[i] << ");";
- nl(Out);
- }
- Out << "Instruction* " << iName << " = GetElementPtrInst::Create("
- << opNames[0] << ", " << iName << "_indices";
- }
- Out << ", \"";
- printEscapedString(gep->getName());
- Out << "\", " << bbname << ");";
+ assert(false && "Unhandled instruction");
break;
}
case Instruction::PHI: {
@@ -1376,6 +1403,18 @@ void CppWriter::printInstruction(const Instruction *I,
}
break;
}
+ case Instruction::PtrToInt:
+ text = getAssign(iName, Type::getInt32Ty(I->getContext()));
+ if (const Constant *CV = dyn_cast<Constant>(I->getOperand(0))) {
+ text += utostr(getGlobalAddress(CV->getName().str()));
+ } else {
+ text += getCast(opNames[0], Type::getInt32Ty(I->getContext()));
+ }
+ text += ";";
+ break;
+ case Instruction::IntToPtr:
+ text = getAssign(iName, Type::getInt32Ty(I->getContext())) + opNames[0] + ";";
+ break;
case Instruction::Trunc:
case Instruction::ZExt:
case Instruction::SExt:
@@ -1385,71 +1424,45 @@ void CppWriter::printInstruction(const Instruction *I,
case Instruction::FPToSI:
case Instruction::UIToFP:
case Instruction::SIToFP:
- case Instruction::PtrToInt:
- case Instruction::IntToPtr:
case Instruction::BitCast: {
- const CastInst* cst = cast<CastInst>(I);
- Out << "CastInst* " << iName << " = new ";
switch (I->getOpcode()) {
case Instruction::Trunc: Out << "TruncInst"; break;
case Instruction::ZExt: Out << "ZExtInst"; break;
case Instruction::SExt: Out << "SExtInst"; break;
case Instruction::FPTrunc: Out << "FPTruncInst"; break;
- case Instruction::FPExt: Out << "FPExtInst"; break;
+ case Instruction::FPExt: text = getAssign(iName, Type::getFloatTy(I->getContext())) + opNames[0] + ";"; break;
case Instruction::FPToUI: Out << "FPToUIInst"; break;
case Instruction::FPToSI: Out << "FPToSIInst"; break;
case Instruction::UIToFP: Out << "UIToFPInst"; break;
- case Instruction::SIToFP: Out << "SIToFPInst"; break;
case Instruction::PtrToInt: Out << "PtrToIntInst"; break;
case Instruction::IntToPtr: Out << "IntToPtrInst"; break;
- case Instruction::BitCast: Out << "BitCastInst"; break;
+ case Instruction::SIToFP:
+ case Instruction::BitCast: text = getAssign(iName, I->getOperand(0)->getType()) + getValueAsStr(I->getOperand(0)) + ";"; break;
default: llvm_unreachable("Unreachable");
}
- Out << "(" << opNames[0] << ", "
- << getCppName(cst->getType()) << ", \"";
- printEscapedString(cst->getName());
- Out << "\", " << bbname << ");";
break;
}
case Instruction::Call: {
const CallInst* call = cast<CallInst>(I);
- if (const InlineAsm* ila = dyn_cast<InlineAsm>(call->getCalledValue())) {
- Out << "InlineAsm* " << getCppName(ila) << " = InlineAsm::get("
- << getCppName(ila->getFunctionType()) << ", \""
- << ila->getAsmString() << "\", \""
- << ila->getConstraintString() << "\","
- << (ila->hasSideEffects() ? "true" : "false") << ");";
- nl(Out);
- }
- if (call->getNumArgOperands() > 1) {
- Out << "std::vector<Value*> " << iName << "_params;";
- nl(Out);
- for (unsigned i = 0; i < call->getNumArgOperands(); ++i) {
- Out << iName << "_params.push_back(" << opNames[i] << ");";
- nl(Out);
+ const int numArgs = call->getNumArgOperands();
+ Type *RT = call->getCalledFunction()->getReturnType();
+ text = opNames[numArgs] + "(";
+ for (int i = 0; i < numArgs; i++) {
+ Value *Arg = call->getArgOperand(i);
+ Type *t = dyn_cast<PointerType>(Arg->getType());
+ const GlobalVariable *GV;
+ if (t && (GV = dyn_cast<GlobalVariable>(Arg))) {
+ text += utostr(getGlobalAddress(GV->getName().str()));
+ } else {
+ text += getValueAsStr(call->getArgOperand(i));
}
- Out << "CallInst* " << iName << " = CallInst::Create("
- << opNames[call->getNumArgOperands()] << ", "
- << iName << "_params, \"";
- } else if (call->getNumArgOperands() == 1) {
- Out << "CallInst* " << iName << " = CallInst::Create("
- << opNames[call->getNumArgOperands()] << ", " << opNames[0] << ", \"";
- } else {
- Out << "CallInst* " << iName << " = CallInst::Create("
- << opNames[call->getNumArgOperands()] << ", \"";
+ if (i < numArgs - 1) text += ", ";
}
- printEscapedString(call->getName());
- Out << "\", " << bbname << ");";
- nl(Out) << iName << "->setCallingConv(";
- printCallingConv(call->getCallingConv());
- Out << ");";
- nl(Out) << iName << "->setTailCall("
- << (call->isTailCall() ? "true" : "false");
- Out << ");";
- nl(Out);
- printAttributes(call->getAttributes(), iName);
- Out << iName << "->setAttributes(" << iName << "_PAL);";
- nl(Out);
+ text += ")";
+ if (!RT->isVoidTy()) {
+ text = getAssign(iName, RT) + getCast(text, RT);
+ }
+ text += ";";
break;
}
case Instruction::Select: {
@@ -1591,8 +1604,8 @@ void CppWriter::printInstruction(const Instruction *I,
}
}
DefinedValues.insert(I);
- nl(Out);
delete [] opNames;
+ return text;
}
// Print out the types, constants and declarations needed by one function
@@ -1654,42 +1667,6 @@ void CppWriter::printFunctionUses(const Function* F) {
}
}
- // Print the function declarations for any functions encountered
- nl(Out) << "// Function Declarations"; nl(Out);
- for (SmallPtrSet<GlobalValue*,64>::iterator I = gvs.begin(), E = gvs.end();
- I != E; ++I) {
- if (Function* Fun = dyn_cast<Function>(*I)) {
- if (!is_inline || Fun != F)
- printFunctionHead(Fun);
- }
- }
-
- // Print the global variable declarations for any variables encountered
- nl(Out) << "// Global Variable Declarations"; nl(Out);
- for (SmallPtrSet<GlobalValue*,64>::iterator I = gvs.begin(), E = gvs.end();
- I != E; ++I) {
- if (GlobalVariable* F = dyn_cast<GlobalVariable>(*I))
- printVariableHead(F)