X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FCppBackend%2FCPPBackend.cpp;h=162e9fd12c3987d5920bdd94a69db330d5b64a2d;hb=c25e7581b9b8088910da31702d4ca21c4734c6d7;hp=fc5be98828031c7896185c1cfd34e68c2c29b545;hpb=70053c340e41a1a7086ecef218395489b3c8cbc6;p=oota-llvm.git diff --git a/lib/Target/CppBackend/CPPBackend.cpp b/lib/Target/CppBackend/CPPBackend.cpp index fc5be988280..162e9fd12c3 100644 --- a/lib/Target/CppBackend/CPPBackend.cpp +++ b/lib/Target/CppBackend/CPPBackend.cpp @@ -28,7 +28,9 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Streams.h" +#include "llvm/Support/raw_ostream.h" #include "llvm/Config/config.h" #include #include @@ -70,8 +72,19 @@ static cl::opt NameToGenerate("cppfor", cl::Optional, cl::desc("Specify the name of the thing to generate"), cl::init("!bad!")); +/// CppBackendTargetMachineModule - Note that this is used on hosts +/// that cannot link in a library unless there are references into the +/// library. In particular, it seems that it is not possible to get +/// things to work on Win32 without this. Though it is unused, do not +/// remove it. +extern "C" int CppBackendTargetMachineModule; +int CppBackendTargetMachineModule = 0; + // Register the target. -static RegisterTarget X("cpp", " C++ backend"); +static RegisterTarget X("cpp", "C++ backend"); + +// Force static initialization. +extern "C" void LLVMInitializeCppBackendTarget() { } namespace { typedef std::vector TypeList; @@ -85,8 +98,7 @@ namespace { /// CppWriter - This class is the main chunk of code that converts an LLVM /// module to a C++ translation unit. class CppWriter : public ModulePass { - const char* progname; - std::ostream &Out; + raw_ostream &Out; const Module *TheModule; uint64_t uniqueNum; TypeMap TypeNames; @@ -101,8 +113,8 @@ namespace { public: static char ID; - explicit CppWriter(std::ostream &o) : - ModulePass((intptr_t)&ID), Out(o), uniqueNum(0), is_inline(false) {} + explicit CppWriter(raw_ostream &o) : + ModulePass(&ID), Out(o), uniqueNum(0), is_inline(false) {} virtual const char *getPassName() const { return "C++ backend"; } @@ -132,7 +144,7 @@ namespace { std::string getCppName(const Value* val); inline void printCppName(const Value* val); - void printParamAttrs(const PAListPtr &PAL, const std::string &name); + void printAttributes(const AttrListPtr &PAL, const std::string &name); bool printTypeInternal(const Type* Ty); inline void printType(const Type* Ty); void printTypes(const Module* M); @@ -154,7 +166,7 @@ namespace { }; static unsigned indent_level = 0; - inline std::ostream& nl(std::ostream& Out, int delta = 0) { + inline raw_ostream& nl(raw_ostream& Out, int delta = 0) { Out << "\n"; if (delta >= 0 || indent_level >= unsigned(-delta)) indent_level += delta; @@ -209,17 +221,17 @@ namespace { } void CppWriter::error(const std::string& msg) { - cerr << progname << ": " << msg << "\n"; - exit(2); + llvm_report_error(msg); } // printCFP - Print a floating point constant .. very carefully :) // This makes sure that conversion to/from floating yields the same binary // result so that we don't lose precision. void CppWriter::printCFP(const ConstantFP *CFP) { + bool ignored; APFloat APF = APFloat(CFP->getValueAPF()); // copy if (CFP->getType() == Type::FloatTy) - APF.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven); + APF.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven, &ignored); Out << "ConstantFP::get("; Out << "APFloat("; #if HAVE_PRINTF_A @@ -252,13 +264,14 @@ namespace { else Out << StrVal << "f"; } else if (CFP->getType() == Type::DoubleTy) - Out << "BitsToDouble(0x" << std::hex - << CFP->getValueAPF().convertToAPInt().getZExtValue() - << std::dec << "ULL) /* " << StrVal << " */"; + Out << "BitsToDouble(0x" + << utohexstr(CFP->getValueAPF().bitcastToAPInt().getZExtValue()) + << "ULL) /* " << StrVal << " */"; else - Out << "BitsToFloat(0x" << std::hex - << (uint32_t)CFP->getValueAPF().convertToAPInt().getZExtValue() - << std::dec << "U) /* " << StrVal << " */"; + Out << "BitsToFloat(0x" + << utohexstr((uint32_t)CFP->getValueAPF(). + bitcastToAPInt().getZExtValue()) + << "U) /* " << StrVal << " */"; Out << ")"; #if HAVE_PRINTF_A } @@ -281,10 +294,18 @@ namespace { switch (LT) { case GlobalValue::InternalLinkage: Out << "GlobalValue::InternalLinkage"; break; - case GlobalValue::LinkOnceLinkage: - Out << "GlobalValue::LinkOnceLinkage "; break; - case GlobalValue::WeakLinkage: - Out << "GlobalValue::WeakLinkage"; break; + case GlobalValue::PrivateLinkage: + Out << "GlobalValue::PrivateLinkage"; break; + case GlobalValue::AvailableExternallyLinkage: + Out << "GlobalValue::AvailableExternallyLinkage "; break; + case GlobalValue::LinkOnceAnyLinkage: + Out << "GlobalValue::LinkOnceAnyLinkage "; break; + case GlobalValue::LinkOnceODRLinkage: + Out << "GlobalValue::LinkOnceODRLinkage "; break; + case GlobalValue::WeakAnyLinkage: + Out << "GlobalValue::WeakAnyLinkage"; break; + case GlobalValue::WeakODRLinkage: + Out << "GlobalValue::WeakODRLinkage"; break; case GlobalValue::AppendingLinkage: Out << "GlobalValue::AppendingLinkage"; break; case GlobalValue::ExternalLinkage: @@ -304,7 +325,7 @@ namespace { void CppWriter::printVisibilityType(GlobalValue::VisibilityTypes VisType) { switch (VisType) { - default: assert(0 && "Unknown GVar visibility"); + default: LLVM_UNREACHABLE("Unknown GVar visibility"); case GlobalValue::DefaultVisibility: Out << "GlobalValue::DefaultVisibility"; break; @@ -341,9 +362,10 @@ namespace { unsigned BitWidth = cast(Ty)->getBitWidth(); return "IntegerType::get(" + utostr(BitWidth) + ")"; } - case Type::FloatTyID: return "Type::FloatTy"; - case Type::DoubleTyID: return "Type::DoubleTy"; - case Type::LabelTyID: return "Type::LabelTy"; + case Type::X86_FP80TyID: return "Type::X86_FP80Ty"; + case Type::FloatTyID: return "Type::FloatTy"; + case Type::DoubleTyID: return "Type::DoubleTy"; + case Type::LabelTyID: return "Type::LabelTy"; default: error("Invalid primitive type"); break; @@ -427,46 +449,48 @@ namespace { printEscapedString(getCppName(val)); } - void CppWriter::printParamAttrs(const PAListPtr &PAL, + void CppWriter::printAttributes(const AttrListPtr &PAL, const std::string &name) { - Out << "PAListPtr " << name << "_PAL;"; + Out << "AttrListPtr " << name << "_PAL;"; nl(Out); if (!PAL.isEmpty()) { Out << '{'; in(); nl(Out); - Out << "SmallVector Attrs;"; nl(Out); - Out << "ParamAttrsWithIndex PAWI;"; nl(Out); + Out << "SmallVector Attrs;"; nl(Out); + Out << "AttributeWithIndex PAWI;"; nl(Out); for (unsigned i = 0; i < PAL.getNumSlots(); ++i) { - uint16_t index = PAL.getSlot(i).Index; - ParameterAttributes attrs = PAL.getSlot(i).Attrs; - Out << "PAWI.Index = " << index << "; PAWI.Attrs = 0 "; - if (attrs & ParamAttr::SExt) - Out << " | ParamAttr::SExt"; - if (attrs & ParamAttr::ZExt) - Out << " | ParamAttr::ZExt"; - if (attrs & ParamAttr::StructRet) - Out << " | ParamAttr::StructRet"; - if (attrs & ParamAttr::InReg) - Out << " | ParamAttr::InReg"; - if (attrs & ParamAttr::NoReturn) - Out << " | ParamAttr::NoReturn"; - if (attrs & ParamAttr::NoUnwind) - Out << " | ParamAttr::NoUnwind"; - if (attrs & ParamAttr::ByVal) - Out << " | ParamAttr::ByVal"; - if (attrs & ParamAttr::NoAlias) - Out << " | ParamAttr::NoAlias"; - if (attrs & ParamAttr::Nest) - Out << " | ParamAttr::Nest"; - if (attrs & ParamAttr::ReadNone) - Out << " | ParamAttr::ReadNone"; - if (attrs & ParamAttr::ReadOnly) - Out << " | ParamAttr::ReadOnly"; + unsigned index = PAL.getSlot(i).Index; + Attributes attrs = PAL.getSlot(i).Attrs; + Out << "PAWI.Index = " << index << "U; PAWI.Attrs = 0 "; +#define HANDLE_ATTR(X) \ + if (attrs & Attribute::X) \ + Out << " | Attribute::" #X; \ + attrs &= ~Attribute::X; + + HANDLE_ATTR(SExt); + HANDLE_ATTR(ZExt); + HANDLE_ATTR(NoReturn); + HANDLE_ATTR(InReg); + HANDLE_ATTR(StructRet); + HANDLE_ATTR(NoUnwind); + HANDLE_ATTR(NoAlias); + HANDLE_ATTR(ByVal); + HANDLE_ATTR(Nest); + HANDLE_ATTR(ReadNone); + HANDLE_ATTR(ReadOnly); + HANDLE_ATTR(NoInline); + HANDLE_ATTR(AlwaysInline); + HANDLE_ATTR(OptimizeForSize); + HANDLE_ATTR(StackProtect); + HANDLE_ATTR(StackProtectReq); + HANDLE_ATTR(NoCapture); +#undef HANDLE_ATTR + assert(attrs == 0 && "Unhandled attribute!"); Out << ";"; nl(Out); Out << "Attrs.push_back(PAWI);"; nl(Out); } - Out << name << "_PAL = PAListPtr::get(Attrs.begin(), Attrs.end());"; + Out << name << "_PAL = AttrListPtr::get(Attrs.begin(), Attrs.end());"; nl(Out); out(); nl(Out); Out << '}'; nl(Out); @@ -721,16 +745,12 @@ namespace { std::string constName(getCppName(CV)); std::string typeName(getCppName(CV->getType())); - if (CV->isNullValue()) { - Out << "Constant* " << constName << " = Constant::getNullValue(" - << typeName << ");"; - nl(Out); - return; - } + if (isa(CV)) { // Skip variables and functions, we emit them elsewhere return; } + if (const ConstantInt *CI = dyn_cast(CV)) { std::string constValue = CI->getValue().toString(10, true); Out << "ConstantInt* " << constName << " = ConstantInt::get(APInt(" @@ -741,7 +761,7 @@ namespace { << " = ConstantAggregateZero::get(" << typeName << ");"; } else if (isa(CV)) { Out << "ConstantPointerNull* " << constName - << " = ConstanPointerNull::get(" << typeName << ");"; + << " = ConstantPointerNull::get(" << typeName << ");"; } else if (const ConstantFP *CFP = dyn_cast(CV)) { Out << "ConstantFP* " << constName << " = "; printCFP(CFP); @@ -824,7 +844,7 @@ namespace { printConstant(CE->getOperand(0)); Out << "Constant* " << constName << " = ConstantExpr::getCast("; switch (CE->getOpcode()) { - default: assert(0 && "Invalid cast opcode"); + default: LLVM_UNREACHABLE("Invalid cast opcode"); case Instruction::Trunc: Out << "Instruction::Trunc"; break; case Instruction::ZExt: Out << "Instruction::ZExt"; break; case Instruction::SExt: Out << "Instruction::SExt"; break; @@ -848,8 +868,11 @@ namespace { Out << "Constant* " << constName << " = ConstantExpr::"; switch (CE->getOpcode()) { case Instruction::Add: Out << "getAdd("; break; + case Instruction::FAdd: Out << "getFAdd("; break; case Instruction::Sub: Out << "getSub("; break; + case Instruction::FSub: Out << "getFSub("; break; case Instruction::Mul: Out << "getMul("; break; + case Instruction::FMul: Out << "getFMul("; break; case Instruction::UDiv: Out << "getUDiv("; break; case Instruction::SDiv: Out << "getSDiv("; break; case Instruction::FDiv: Out << "getFDiv("; break; @@ -978,7 +1001,7 @@ namespace { nl(Out) << "if (!" << getCppName(GV) << ") {"; in(); nl(Out) << getCppName(GV); } - Out << " = new GlobalVariable("; + Out << " = new GlobalVariable(/*Module=*/*mod"; nl(Out) << "/*Type=*/"; printCppName(GV->getType()->getElementType()); Out << ","; @@ -993,8 +1016,7 @@ namespace { } nl(Out) << "/*Name=*/\""; printEscapedString(GV->getName()); - Out << "\","; - nl(Out) << "mod);"; + Out << "\");"; nl(Out); if (GV->hasSection()) { @@ -1080,9 +1102,9 @@ namespace { const BranchInst* br = cast(I); Out << "BranchInst::Create(" ; if (br->getNumOperands() == 3 ) { - Out << opNames[0] << ", " + Out << opNames[2] << ", " << opNames[1] << ", " - << opNames[2] << ", "; + << opNames[0] << ", "; } else if (br->getNumOperands() == 1) { Out << opNames[0] << ", "; @@ -1126,8 +1148,8 @@ namespace { nl(Out) << iName << "->setCallingConv("; printCallingConv(inv->getCallingConv()); Out << ");"; - printParamAttrs(inv->getParamAttrs(), iName); - Out << iName << "->setParamAttrs(" << iName << "_PAL);"; + printAttributes(inv->getAttributes(), iName); + Out << iName << "->setAttributes(" << iName << "_PAL);"; nl(Out); break; } @@ -1142,8 +1164,11 @@ namespace { break; } case Instruction::Add: + case Instruction::FAdd: case Instruction::Sub: + case Instruction::FSub: case Instruction::Mul: + case Instruction::FMul: case Instruction::UDiv: case Instruction::SDiv: case Instruction::FDiv: @@ -1159,8 +1184,11 @@ namespace { Out << "BinaryOperator* " << iName << " = BinaryOperator::Create("; switch (I->getOpcode()) { case Instruction::Add: Out << "Instruction::Add"; break; + case Instruction::FAdd: Out << "Instruction::FAdd"; break; case Instruction::Sub: Out << "Instruction::Sub"; break; + case Instruction::FSub: Out << "Instruction::FSub"; break; case Instruction::Mul: Out << "Instruction::Mul"; break; + case Instruction::FMul: Out << "Instruction::FMul"; break; case Instruction::UDiv:Out << "Instruction::UDiv"; break; case Instruction::SDiv:Out << "Instruction::SDiv"; break; case Instruction::FDiv:Out << "Instruction::FDiv"; break; @@ -1270,7 +1298,7 @@ namespace { } case Instruction::Store: { const StoreInst* store = cast(I); - Out << "StoreInst* " << iName << " = new StoreInst(" + Out << " new StoreInst(" << opNames[0] << ", " << opNames[1] << ", " << (store->isVolatile() ? "true" : "false") @@ -1356,7 +1384,7 @@ namespace { } case Instruction::Call:{ const CallInst* call = cast(I); - if (InlineAsm* ila = dyn_cast(call->getOperand(0))) { + if (const InlineAsm* ila = dyn_cast(call->getCalledValue())) { Out << "InlineAsm* " << getCppName(ila) << " = InlineAsm::get(" << getCppName(ila->getFunctionType()) << ", \"" << ila->getAsmString() << "\", \"" @@ -1389,8 +1417,8 @@ namespace { nl(Out) << iName << "->setTailCall(" << (call->isTailCall() ? "true":"false"); Out << ");"; - printParamAttrs(call->getParamAttrs(), iName); - Out << iName << "->setParamAttrs(" << iName << "_PAL);"; + printAttributes(call->getAttributes(), iName); + Out << iName << "->setAttributes(" << iName << "_PAL);"; nl(Out); break; } @@ -1613,9 +1641,9 @@ namespace { Out << "}"; nl(Out); } - printParamAttrs(F->getParamAttrs(), getCppName(F)); + printAttributes(F->getAttributes(), getCppName(F)); printCppName(F); - Out << "->setParamAttrs(" << getCppName(F) << "_PAL);"; + Out << "->setAttributes(" << getCppName(F) << "_PAL);"; nl(Out); } @@ -1780,22 +1808,21 @@ namespace { Out << "#include \n"; Out << "#include \n"; Out << "#include \n"; + Out << "#include \n"; Out << "#include \n"; Out << "#include \n"; Out << "#include \n"; Out << "#include \n"; Out << "#include \n"; Out << "#include \n"; - Out << "#include \n\n"; Out << "using namespace llvm;\n\n"; Out << "Module* " << fname << "();\n\n"; Out << "int main(int argc, char**argv) {\n"; Out << " Module* Mod = " << fname << "();\n"; Out << " verifyModule(*Mod, PrintMessageAction);\n"; - Out << " std::cerr.flush();\n"; - Out << " std::cout.flush();\n"; + Out << " outs().flush();\n"; Out << " PassManager PM;\n"; - Out << " PM.add(new PrintModulePass(&llvm::cout));\n"; + Out << " PM.add(createPrintModulePass(&outs()));\n"; Out << " PM.run(*Mod);\n"; Out << " return 0;\n"; Out << "}\n\n"; @@ -1806,7 +1833,9 @@ namespace { const std::string& mName) { nl(Out) << "Module* " << fname << "() {"; nl(Out,1) << "// Module Construction"; - nl(Out) << "Module* mod = new Module(\"" << mName << "\");"; + nl(Out) << "Module* mod = new Module(\""; + printEscapedString(mName); + Out << "\");"; if (!TheModule->getTargetTriple().empty()) { nl(Out) << "mod->setDataLayout(\"" << TheModule->getDataLayout() << "\");"; } @@ -1839,7 +1868,9 @@ namespace { void CppWriter::printContents(const std::string& fname, const std::string& mName) { Out << "\nModule* " << fname << "(Module *mod) {\n"; - Out << "\nmod->setModuleIdentifier(\"" << mName << "\");\n"; + Out << "\nmod->setModuleIdentifier(\""; + printEscapedString(mName); + Out << "\");\n"; printModuleBody(); Out << "\nreturn mod;\n"; Out << "\n}\n"; @@ -1982,9 +2013,9 @@ char CppWriter::ID = 0; //===----------------------------------------------------------------------===// bool CPPTargetMachine::addPassesToEmitWholeFile(PassManager &PM, - std::ostream &o, + raw_ostream &o, CodeGenFileType FileType, - bool Fast) { + CodeGenOpt::Level OptLevel) { if (FileType != TargetMachine::AssemblyFile) return true; PM.add(new CppWriter(o)); return false;