X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FCppBackend%2FCPPBackend.cpp;h=3e69098edcc37c7f23db7f40469c715e7ecc8802;hb=98017a015bb862afce4f90d432eded4e28fe1d26;hp=394ea2bfea0280eb26bdcbf97d3f68521a19c79b;hpb=5b7cc334c8803284df7cf3aaee378b78f775b6ef;p=oota-llvm.git diff --git a/lib/Target/CppBackend/CPPBackend.cpp b/lib/Target/CppBackend/CPPBackend.cpp index 394ea2bfea0..3e69098edcc 100644 --- a/lib/Target/CppBackend/CPPBackend.cpp +++ b/lib/Target/CppBackend/CPPBackend.cpp @@ -13,28 +13,29 @@ //===----------------------------------------------------------------------===// #include "CPPTargetMachine.h" -#include "llvm/CallingConv.h" -#include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" -#include "llvm/InlineAsm.h" -#include "llvm/Instruction.h" -#include "llvm/Instructions.h" -#include "llvm/Module.h" -#include "llvm/Pass.h" -#include "llvm/PassManager.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/Config/config.h" +#include "llvm/IR/CallingConv.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/InlineAsm.h" +#include "llvm/IR/Instruction.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/Module.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCSubtargetInfo.h" -#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/Pass.h" +#include "llvm/PassManager.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FormattedStream.h" #include "llvm/Support/TargetRegistry.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/Config/config.h" #include -#include +#include #include +#include using namespace llvm; static cl::opt @@ -129,6 +130,7 @@ namespace { private: void printLinkageType(GlobalValue::LinkageTypes LT); void printVisibilityType(GlobalValue::VisibilityTypes VisTypes); + void printThreadLocalMode(GlobalVariable::ThreadLocalMode TLM); void printCallingConv(CallingConv::ID cc); void printEscapedString(const std::string& str); void printCFP(const ConstantFP* CFP); @@ -139,7 +141,7 @@ namespace { std::string getCppName(const Value* val); inline void printCppName(const Value* val); - void printAttributes(const AttrListPtr &PAL, const std::string &name); + void printAttributes(const AttributeSet &PAL, const std::string &name); void printType(Type* Ty); void printTypes(const Module* M); @@ -189,13 +191,24 @@ static std::string getTypePrefix(Type *Ty) { case Type::VectorTyID: return "packed_"; default: return "other_"; } - return "unknown_"; } void CppWriter::error(const std::string& msg) { report_fatal_error(msg); } +static inline std::string ftostr(const APFloat& V) { + std::string Buf; + if (&V.getSemantics() == &APFloat::IEEEdouble) { + raw_string_ostream(Buf) << V.convertToDouble(); + return Buf; + } else if (&V.getSemantics() == &APFloat::IEEEsingle) { + raw_string_ostream(Buf) << (double)V.convertToFloat(); + return Buf; + } + return ""; // error +} + // 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. @@ -272,14 +285,14 @@ void CppWriter::printLinkageType(GlobalValue::LinkageTypes LT) { Out << "GlobalValue::LinkerPrivateLinkage"; break; case GlobalValue::LinkerPrivateWeakLinkage: Out << "GlobalValue::LinkerPrivateWeakLinkage"; break; - case GlobalValue::LinkerPrivateWeakDefAutoLinkage: - Out << "GlobalValue::LinkerPrivateWeakDefAutoLinkage"; break; case GlobalValue::AvailableExternallyLinkage: Out << "GlobalValue::AvailableExternallyLinkage "; break; case GlobalValue::LinkOnceAnyLinkage: Out << "GlobalValue::LinkOnceAnyLinkage "; break; case GlobalValue::LinkOnceODRLinkage: Out << "GlobalValue::LinkOnceODRLinkage "; break; + case GlobalValue::LinkOnceODRAutoHideLinkage: + Out << "GlobalValue::LinkOnceODRAutoHideLinkage"; break; case GlobalValue::WeakAnyLinkage: Out << "GlobalValue::WeakAnyLinkage"; break; case GlobalValue::WeakODRLinkage: @@ -301,7 +314,6 @@ void CppWriter::printLinkageType(GlobalValue::LinkageTypes LT) { void CppWriter::printVisibilityType(GlobalValue::VisibilityTypes VisType) { switch (VisType) { - default: llvm_unreachable("Unknown GVar visibility"); case GlobalValue::DefaultVisibility: Out << "GlobalValue::DefaultVisibility"; break; @@ -314,6 +326,26 @@ void CppWriter::printVisibilityType(GlobalValue::VisibilityTypes VisType) { } } +void CppWriter::printThreadLocalMode(GlobalVariable::ThreadLocalMode TLM) { + switch (TLM) { + case GlobalVariable::NotThreadLocal: + Out << "GlobalVariable::NotThreadLocal"; + break; + case GlobalVariable::GeneralDynamicTLSModel: + Out << "GlobalVariable::GeneralDynamicTLSModel"; + break; + case GlobalVariable::LocalDynamicTLSModel: + Out << "GlobalVariable::LocalDynamicTLSModel"; + break; + case GlobalVariable::InitialExecTLSModel: + Out << "GlobalVariable::InitialExecTLSModel"; + break; + case GlobalVariable::LocalExecTLSModel: + Out << "GlobalVariable::LocalExecTLSModel"; + break; + } +} + // printEscapedString - Print each character of the specified string, escaping // it if it is not printable or if it is an escape char. void CppWriter::printEscapedString(const std::string &Str) { @@ -432,23 +464,26 @@ void CppWriter::printCppName(const Value* val) { printEscapedString(getCppName(val)); } -void CppWriter::printAttributes(const AttrListPtr &PAL, +void CppWriter::printAttributes(const AttributeSet &PAL, const std::string &name) { - Out << "AttrListPtr " << name << "_PAL;"; + Out << "AttributeSet " << name << "_PAL;"; nl(Out); if (!PAL.isEmpty()) { Out << '{'; in(); nl(Out); - Out << "SmallVector Attrs;"; nl(Out); - Out << "AttributeWithIndex PAWI;"; nl(Out); + Out << "SmallVector Attrs;"; nl(Out); + Out << "AttributeSet PAS;"; in(); nl(Out); for (unsigned i = 0; i < PAL.getNumSlots(); ++i) { - 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; - + unsigned index = PAL.getSlotIndex(i); + AttrBuilder attrs(PAL.getSlotAttributes(i), index); + Out << "{"; in(); nl(Out); + Out << "AttrBuilder B;"; nl(Out); + +#define HANDLE_ATTR(X) \ + if (attrs.contains(Attribute::X)) { \ + Out << "B.addAttribute(Attribute::" #X ");"; nl(Out); \ + attrs.removeAttribute(Attribute::X); \ + } + HANDLE_ATTR(SExt); HANDLE_ATTR(ZExt); HANDLE_ATTR(NoReturn); @@ -465,6 +500,7 @@ void CppWriter::printAttributes(const AttrListPtr &PAL, HANDLE_ATTR(OptimizeForSize); HANDLE_ATTR(StackProtect); HANDLE_ATTR(StackProtectReq); + HANDLE_ATTR(StackProtectStrong); HANDLE_ATTR(NoCapture); HANDLE_ATTR(NoRedZone); HANDLE_ATTR(NoImplicitFloat); @@ -473,19 +509,26 @@ void CppWriter::printAttributes(const AttrListPtr &PAL, HANDLE_ATTR(ReturnsTwice); HANDLE_ATTR(UWTable); HANDLE_ATTR(NonLazyBind); + HANDLE_ATTR(MinSize); #undef HANDLE_ATTR - if (attrs & Attribute::StackAlignment) - Out << " | Attribute::constructStackAlignmentFromInt(" - << Attribute::getStackAlignmentFromAttrs(attrs) - << ")"; - attrs &= ~Attribute::StackAlignment; - assert(attrs == 0 && "Unhandled attribute!"); - Out << ";"; - nl(Out); - Out << "Attrs.push_back(PAWI);"; + + if (attrs.contains(Attribute::StackAlignment)) { + Out << "B.addStackAlignmentAttr(" << attrs.getStackAlignment()<<')'; + nl(Out); + attrs.removeAttribute(Attribute::StackAlignment); + } + + Out << "PAS = AttributeSet::get(mod->getContext(), "; + if (index == ~0U) + Out << "~0U,"; + else + Out << index << "U,"; + Out << " B);"; out(); nl(Out); + Out << "}"; out(); nl(Out); nl(Out); + Out << "Attrs.push_back(PAS);"; nl(Out); } - Out << name << "_PAL = AttrListPtr::get(Attrs.begin(), Attrs.end());"; + Out << name << "_PAL = AttributeSet::get(mod->getContext(), Attrs);"; nl(Out); out(); nl(Out); Out << '}'; nl(Out); @@ -678,11 +721,6 @@ void CppWriter::printConstant(const Constant *CV) { std::string constName(getCppName(CV)); std::string typeName(getCppName(CV->getType())); - 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 @@ -700,38 +738,17 @@ void CppWriter::printConstant(const Constant *CV) { printCFP(CFP); Out << ";"; } else if (const ConstantArray *CA = dyn_cast(CV)) { - if (CA->isString() && - CA->getType()->getElementType() == - Type::getInt8Ty(CA->getContext())) { - Out << "Constant* " << constName << - " = ConstantArray::get(mod->getContext(), \""; - std::string tmp = CA->getAsString(); - bool nullTerminate = false; - if (tmp[tmp.length()-1] == 0) { - tmp.erase(tmp.length()-1); - nullTerminate = true; - } - printEscapedString(tmp); - // Determine if we want null termination or not. - if (nullTerminate) - Out << "\", true"; // Indicate that the null terminator should be - // added. - else - Out << "\", false";// No null terminator - Out << ");"; - } else { - Out << "std::vector " << constName << "_elems;"; + Out << "std::vector " << constName << "_elems;"; + nl(Out); + unsigned N = CA->getNumOperands(); + for (unsigned i = 0; i < N; ++i) { + printConstant(CA->getOperand(i)); // recurse to print operands + Out << constName << "_elems.push_back(" + << getCppName(CA->getOperand(i)) << ");"; nl(Out); - unsigned N = CA->getNumOperands(); - for (unsigned i = 0; i < N; ++i) { - printConstant(CA->getOperand(i)); // recurse to print operands - Out << constName << "_elems.push_back(" - << getCppName(CA->getOperand(i)) << ");"; - nl(Out); - } - Out << "Constant* " << constName << " = ConstantArray::get(" - << typeName << ", " << constName << "_elems);"; } + Out << "Constant* " << constName << " = ConstantArray::get(" + << typeName << ", " << constName << "_elems);"; } else if (const ConstantStruct *CS = dyn_cast(CV)) { Out << "std::vector " << constName << "_fields;"; nl(Out); @@ -744,14 +761,14 @@ void CppWriter::printConstant(const Constant *CV) { } Out << "Constant* " << constName << " = ConstantStruct::get(" << typeName << ", " << constName << "_fields);"; - } else if (const ConstantVector *CP = dyn_cast(CV)) { + } else if (const ConstantVector *CVec = dyn_cast(CV)) { Out << "std::vector " << constName << "_elems;"; nl(Out); - unsigned N = CP->getNumOperands(); + unsigned N = CVec->getNumOperands(); for (unsigned i = 0; i < N; ++i) { - printConstant(CP->getOperand(i)); + printConstant(CVec->getOperand(i)); Out << constName << "_elems.push_back(" - << getCppName(CP->getOperand(i)) << ");"; + << getCppName(CVec->getOperand(i)) << ");"; nl(Out); } Out << "Constant* " << constName << " = ConstantVector::get(" @@ -759,6 +776,41 @@ void CppWriter::printConstant(const Constant *CV) { } else if (isa(CV)) { Out << "UndefValue* " << constName << " = UndefValue::get(" << typeName << ");"; + } else if (const ConstantDataSequential *CDS = + dyn_cast(CV)) { + if (CDS->isString()) { + Out << "Constant *" << constName << + " = ConstantDataArray::getString(mod->getContext(), \""; + StringRef Str = CDS->getAsString(); + bool nullTerminate = false; + if (Str.back() == 0) { + Str = Str.drop_back(); + nullTerminate = true; + } + printEscapedString(Str); + // Determine if we want null termination or not. + if (nullTerminate) + Out << "\", true);"; + else + Out << "\", false);";// No null terminator + } else { + // TODO: Could generate more efficient code generating CDS calls instead. + Out << "std::vector " << constName << "_elems;"; + nl(Out); + for (unsigned i = 0; i != CDS->getNumElements(); ++i) { + Constant *Elt = CDS->getElementAsConstant(i); + printConstant(Elt); + Out << constName << "_elems.push_back(" << getCppName(Elt) << ");"; + nl(Out); + } + Out << "Constant* " << constName; + + if (isa(CDS->getType())) + Out << " = ConstantArray::get("; + else + Out << " = ConstantVector::get("; + Out << typeName << ", " << constName << "_elems);"; + } } else if (const ConstantExpr *CE = dyn_cast(CV)) { if (CE->getOpcode() == Instruction::GetElementPtr) { Out << "std::vector " << constName << "_indices;"; @@ -976,7 +1028,9 @@ void CppWriter::printVariableHead(const GlobalVariable *GV) { } if (GV->isThreadLocal()) { printCppName(GV); - Out << "->setThreadLocal(true);"; + Out << "->setThreadLocalMode("; + printThreadLocalMode(GV->getThreadLocalMode()); + Out << ");"; nl(Out); } if (is_inline) { @@ -1083,10 +1137,10 @@ void CppWriter::printInstruction(const Instruction *I, << getOpName(SI->getDefaultDest()) << ", " << SI->getNumCases() << ", " << bbname << ");"; nl(Out); - unsigned NumCases = SI->getNumCases(); - for (unsigned i = 1; i < NumCases; ++i) { - const ConstantInt* CaseVal = SI->getCaseValue(i); - const BasicBlock* BB = SI->getSuccessor(i); + for (SwitchInst::ConstCaseIt i = SI->case_begin(), e = SI->case_end(); + i != e; ++i) { + const IntegersSubset CaseVal = i.getCaseValueEx(); + const BasicBlock *BB = i.getCaseSuccessor(); Out << iName << "->addCase(" << getOpName(CaseVal) << ", " << getOpName(BB) << ");"; @@ -1135,11 +1189,6 @@ void CppWriter::printInstruction(const Instruction *I, nl(Out); break; } - case Instruction::Unwind: { - Out << "new UnwindInst(" - << bbname << ");"; - break; - } case Instruction::Unreachable: { Out << "new UnreachableInst(" << "mod->getContext(), " @@ -1354,7 +1403,7 @@ void CppWriter::printInstruction(const Instruction *I, case Instruction::PtrToInt: Out << "PtrToIntInst"; break; case Instruction::IntToPtr: Out << "IntToPtrInst"; break; case Instruction::BitCast: Out << "BitCastInst"; break; - default: assert(0 && "Unreachable"); break; + default: llvm_unreachable("Unreachable"); } Out << "(" << opNames[0] << ", " << getCppName(cst->getType()) << ", \""; @@ -1849,23 +1898,24 @@ void CppWriter::printModuleBody() { void CppWriter::printProgram(const std::string& fname, const std::string& mName) { - 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"; - 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"; + 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 << "using namespace llvm;\n\n"; Out << "Module* " << fname << "();\n\n"; @@ -1902,14 +1952,6 @@ void CppWriter::printModule(const std::string& fname, } nl(Out); - // Loop over the dependent libraries and emit them. - Module::lib_iterator LI = TheModule->lib_begin(); - Module::lib_iterator LE = TheModule->lib_end(); - while (LI != LE) { - Out << "mod->addLibrary(\"" << *LI << "\");"; - nl(Out); - ++LI; - } printModuleBody(); nl(Out) << "return mod;"; nl(Out,-1) << "}"; @@ -2049,8 +2091,6 @@ bool CppWriter::runOnModule(Module &M) { fname = "makeLLVMType"; printType(fname,tgtname); break; - default: - error("Invalid generation option"); } return false; @@ -2065,8 +2105,9 @@ char CppWriter::ID = 0; bool CPPTargetMachine::addPassesToEmitFile(PassManagerBase &PM, formatted_raw_ostream &o, CodeGenFileType FileType, - CodeGenOpt::Level OptLevel, - bool DisableVerify) { + bool DisableVerify, + AnalysisID StartAfter, + AnalysisID StopAfter) { if (FileType != TargetMachine::CGFT_AssemblyFile) return true; PM.add(new CppWriter(o)); return false;