X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FCppBackend%2FCPPBackend.cpp;h=0f9ba58295babc684b5834e433c16a9ddd823da2;hb=034b94b17006f51722886b0f2283fb6fb19aca1f;hp=85b07d1fa1b4de07aa110b628185667951e042a7;hpb=db125cfaf57cc83e7dd7453de2d509bc8efd0e5e;p=oota-llvm.git diff --git a/lib/Target/CppBackend/CPPBackend.cpp b/lib/Target/CppBackend/CPPBackend.cpp index 85b07d1fa1b..0f9ba58295b 100644 --- a/lib/Target/CppBackend/CPPBackend.cpp +++ b/lib/Target/CppBackend/CPPBackend.cpp @@ -13,28 +13,29 @@ //===----------------------------------------------------------------------===// #include "CPPTargetMachine.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/CallingConv.h" +#include "llvm/Config/config.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/MC/MCAsmInfo.h" #include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCSubtargetInfo.h" -#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/Module.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/Target/TargetRegistry.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/Config/config.h" +#include "llvm/Support/TargetRegistry.h" #include -#include +#include #include +#include using namespace llvm; static cl::opt @@ -77,16 +78,6 @@ extern "C" void LLVMInitializeCppBackendTarget() { RegisterTargetMachine X(TheCppBackendTarget); } -extern "C" void LLVMInitializeCppBackendMCAsmInfo() {} - -extern "C" void LLVMInitializeCppBackendMCInstrInfo() { - RegisterMCInstrInfo X(TheCppBackendTarget); -} - -extern "C" void LLVMInitializeCppBackendMCSubtargetInfo() { - RegisterMCSubtargetInfo X(TheCppBackendTarget); -} - namespace { typedef std::vector TypeList; typedef std::map TypeMap; @@ -139,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); @@ -149,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); @@ -164,7 +156,7 @@ namespace { void printFunctionHead(const Function *F); void printFunctionBody(const Function *F); void printInstruction(const Instruction *I, const std::string& bbname); - std::string getOpName(Value*); + std::string getOpName(const Value*); void printModuleBody(); }; @@ -199,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. @@ -282,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: @@ -311,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; @@ -324,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) { @@ -442,9 +464,9 @@ 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); @@ -452,13 +474,15 @@ void CppWriter::printAttributes(const AttrListPtr &PAL, Out << "AttributeWithIndex PAWI;"; 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; - + AttrBuilder attrs(PAL.getSlot(i).Attrs); + Out << "PAWI.Index = " << index << "U;\n"; + Out << " {\n AttrBuilder B;\n"; + +#define HANDLE_ATTR(X) \ + if (attrs.hasAttribute(Attribute::X)) \ + Out << " B.addAttribute(Attribute::" #X ");\n"; \ + attrs.removeAttribute(Attribute::X); + HANDLE_ATTR(SExt); HANDLE_ATTR(ZExt); HANDLE_ATTR(NoReturn); @@ -480,19 +504,21 @@ void CppWriter::printAttributes(const AttrListPtr &PAL, HANDLE_ATTR(NoImplicitFloat); HANDLE_ATTR(Naked); HANDLE_ATTR(InlineHint); + 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 << ";"; + if (attrs.hasAttribute(Attribute::StackAlignment)) + Out << " B.addStackAlignmentAttr(" << attrs.getStackAlignment() << ")\n"; + attrs.removeAttribute(Attribute::StackAlignment); + assert(!attrs.hasAttributes() && "Unhandled attribute!"); + Out << " PAWI.Attrs = Attribute::get(mod->getContext(), B);\n }"; nl(Out); Out << "Attrs.push_back(PAWI);"; 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); @@ -540,12 +566,20 @@ void CppWriter::printType(Type* Ty) { } case Type::StructTyID: { StructType* ST = cast(Ty); - if (!ST->isAnonymous()) { - Out << "StructType *" << typeName << " = "; - Out << "StructType::createNamed(mod->getContext(), \""; + if (!ST->isLiteral()) { + Out << "StructType *" << typeName << " = mod->getTypeByName(\""; + printEscapedString(ST->getName()); + Out << "\");"; + nl(Out); + Out << "if (!" << typeName << ") {"; + nl(Out); + Out << typeName << " = "; + Out << "StructType::create(mod->getContext(), \""; printEscapedString(ST->getName()); Out << "\");"; nl(Out); + Out << "}"; + nl(Out); // Indicate that this type is now defined. DefinedTypes.insert(Ty); } @@ -563,16 +597,22 @@ void CppWriter::printType(Type* Ty) { nl(Out); } - if (ST->isAnonymous()) { + if (ST->isLiteral()) { Out << "StructType *" << typeName << " = "; Out << "StructType::get(" << "mod->getContext(), "; } else { + Out << "if (" << typeName << "->isOpaque()) {"; + nl(Out); Out << typeName << "->setBody("; } Out << typeName << "_fields, /*isPacked=*/" << (ST->isPacked() ? "true" : "false") << ");"; nl(Out); + if (!ST->isLiteral()) { + Out << "}"; + nl(Out); + } break; } case Type::ArrayTyID: { @@ -671,11 +711,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 @@ -693,38 +728,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); @@ -737,14 +751,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(" @@ -752,6 +766,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;"; @@ -766,9 +815,7 @@ void CppWriter::printConstant(const Constant *CV) { Out << "Constant* " << constName << " = ConstantExpr::getGetElementPtr(" << getCppName(CE->getOperand(0)) << ", " - << "&" << constName << "_indices[0], " - << constName << "_indices.size()" - << ");"; + << constName << "_indices);"; } else if (CE->isCast()) { printConstant(CE->getOperand(0)); Out << "Constant* " << constName << " = ConstantExpr::getCast("; @@ -971,7 +1018,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) { @@ -988,7 +1037,7 @@ void CppWriter::printVariableBody(const GlobalVariable *GV) { } } -std::string CppWriter::getOpName(Value* V) { +std::string CppWriter::getOpName(const Value* V) { if (!isa(V) || DefinedValues.find(V) != DefinedValues.end()) return getCppName(V); @@ -1011,6 +1060,27 @@ std::string CppWriter::getOpName(Value* V) { return result; } +static StringRef ConvertAtomicOrdering(AtomicOrdering Ordering) { + switch (Ordering) { + case NotAtomic: return "NotAtomic"; + case Unordered: return "Unordered"; + case Monotonic: return "Monotonic"; + case Acquire: return "Acquire"; + case Release: return "Release"; + case AcquireRelease: return "AcquireRelease"; + case SequentiallyConsistent: return "SequentiallyConsistent"; + } + llvm_unreachable("Unknown ordering"); +} + +static StringRef ConvertAtomicSynchScope(SynchronizationScope SynchScope) { + switch (SynchScope) { + case SingleThread: return "SingleThread"; + case CrossThread: return "CrossThread"; + } + 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) { @@ -1053,14 +1123,17 @@ void CppWriter::printInstruction(const Instruction *I, case Instruction::Switch: { const SwitchInst *SI = cast(I); Out << "SwitchInst* " << iName << " = SwitchInst::Create(" - << opNames[0] << ", " - << opNames[1] << ", " + << getOpName(SI->getCondition()) << ", " + << getOpName(SI->getDefaultDest()) << ", " << SI->getNumCases() << ", " << bbname << ");"; nl(Out); - for (unsigned i = 2; i != SI->getNumOperands(); i += 2) { + 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(" - << opNames[i] << ", " - << opNames[i+1] << ");"; + << getOpName(CaseVal) << ", " + << getOpName(BB) << ");"; nl(Out); } break; @@ -1076,6 +1149,11 @@ void CppWriter::printInstruction(const Instruction *I, } break; } + case Instruction::Resume: { + Out << "ResumeInst::Create(mod->getContext(), " << opNames[0] + << ", " << bbname << ");"; + break; + } case Instruction::Invoke: { const InvokeInst* inv = cast(I); Out << "std::vector " << iName << "_params;"; @@ -1090,8 +1168,7 @@ void CppWriter::printInstruction(const Instruction *I, << getOpName(inv->getCalledFunction()) << ", " << getOpName(inv->getNormalDest()) << ", " << getOpName(inv->getUnwindDest()) << ", " - << iName << "_params.begin(), " - << iName << "_params.end(), \""; + << iName << "_params, \""; printEscapedString(inv->getName()); Out << "\", " << bbname << ");"; nl(Out) << iName << "->setCallingConv("; @@ -1102,11 +1179,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(), " @@ -1225,15 +1297,33 @@ void CppWriter::printInstruction(const Instruction *I, 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 << ");"; + } break; } case Instruction::Store: { const StoreInst* store = cast(I); - Out << " new StoreInst(" + 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 << ");"; + } break; } case Instruction::GetElementPtr: { @@ -1252,8 +1342,7 @@ void CppWriter::printInstruction(const Instruction *I, nl(Out); } Out << "Instruction* " << iName << " = GetElementPtrInst::Create(" - << opNames[0] << ", " << iName << "_indices.begin(), " - << iName << "_indices.end()"; + << opNames[0] << ", " << iName << "_indices"; } Out << ", \""; printEscapedString(gep->getName()); @@ -1304,7 +1393,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(!"Unreachable"); break; + default: llvm_unreachable("Unreachable"); } Out << "(" << opNames[0] << ", " << getCppName(cst->getType()) << ", \""; @@ -1331,8 +1420,7 @@ void CppWriter::printInstruction(const Instruction *I, } Out << "CallInst* " << iName << " = CallInst::Create(" << opNames[call->getNumArgOperands()] << ", " - << iName << "_params.begin(), " - << iName << "_params.end(), \""; + << iName << "_params, \""; } else if (call->getNumArgOperands() == 1) { Out << "CallInst* " << iName << " = CallInst::Create(" << opNames[call->getNumArgOperands()] << ", " << opNames[0] << ", \""; @@ -1415,7 +1503,7 @@ void CppWriter::printInstruction(const Instruction *I, Out << "ExtractValueInst* " << getCppName(evi) << " = ExtractValueInst::Create(" << opNames[0] << ", " - << iName << "_indices.begin(), " << iName << "_indices.end(), \""; + << iName << "_indices, \""; printEscapedString(evi->getName()); Out << "\", " << bbname << ");"; break; @@ -1432,11 +1520,65 @@ void CppWriter::printInstruction(const Instruction *I, Out << "InsertValueInst* " << getCppName(ivi) << " = InsertValueInst::Create(" << opNames[0] << ", " << opNames[1] << ", " - << iName << "_indices.begin(), " << iName << "_indices.end(), \""; + << iName << "_indices, \""; printEscapedString(ivi->getName()); Out << "\", " << bbname << ");"; break; } + case Instruction::Fence: { + const FenceInst *fi = cast(I); + StringRef Ordering = ConvertAtomicOrdering(fi->getOrdering()); + StringRef CrossThread = ConvertAtomicSynchScope(fi->getSynchScope()); + Out << "FenceInst* " << iName + << " = new FenceInst(mod->getContext(), " + << Ordering << ", " << CrossThread << ", " << bbname + << ");"; + break; + } + case Instruction::AtomicCmpXchg: { + const AtomicCmpXchgInst *cxi = cast(I); + StringRef Ordering = ConvertAtomicOrdering(cxi->getOrdering()); + StringRef CrossThread = ConvertAtomicSynchScope(cxi->getSynchScope()); + Out << "AtomicCmpXchgInst* " << iName + << " = new AtomicCmpXchgInst(" + << opNames[0] << ", " << opNames[1] << ", " << opNames[2] << ", " + << Ordering << ", " << CrossThread << ", " << bbname + << ");"; + nl(Out) << iName << "->setName(\""; + printEscapedString(cxi->getName()); + Out << "\");"; + break; + } + case Instruction::AtomicRMW: { + const AtomicRMWInst *rmwi = cast(I); + StringRef Ordering = ConvertAtomicOrdering(rmwi->getOrdering()); + StringRef CrossThread = ConvertAtomicSynchScope(rmwi->getSynchScope()); + StringRef Operation; + switch (rmwi->getOperation()) { + case AtomicRMWInst::Xchg: Operation = "AtomicRMWInst::Xchg"; break; + case AtomicRMWInst::Add: Operation = "AtomicRMWInst::Add"; break; + case AtomicRMWInst::Sub: Operation = "AtomicRMWInst::Sub"; break; + case AtomicRMWInst::And: Operation = "AtomicRMWInst::And"; break; + case AtomicRMWInst::Nand: Operation = "AtomicRMWInst::Nand"; break; + case AtomicRMWInst::Or: Operation = "AtomicRMWInst::Or"; break; + case AtomicRMWInst::Xor: Operation = "AtomicRMWInst::Xor"; break; + case AtomicRMWInst::Max: Operation = "AtomicRMWInst::Max"; break; + case AtomicRMWInst::Min: Operation = "AtomicRMWInst::Min"; break; + case AtomicRMWInst::UMax: Operation = "AtomicRMWInst::UMax"; break; + case AtomicRMWInst::UMin: Operation = "AtomicRMWInst::UMin"; break; + case AtomicRMWInst::BAD_BINOP: llvm_unreachable("Bad atomic operation"); + } + Out << "AtomicRMWInst* " << iName + << " = new AtomicRMWInst(" + << Operation << ", " + << opNames[0] << ", " << opNames[1] << ", " + << Ordering << ", " << CrossThread << ", " << bbname + << ");"; + nl(Out) << iName << "->setName(\""; + printEscapedString(rmwi->getName()); + Out << "\");"; + break; + } } DefinedValues.insert(I); nl(Out); @@ -1542,13 +1684,12 @@ void CppWriter::printFunctionUses(const Function* F) { void CppWriter::printFunctionHead(const Function* F) { nl(Out) << "Function* " << getCppName(F); - if (is_inline) { - Out << " = mod->getFunction(\""; - printEscapedString(F->getName()); - Out << "\", " << getCppName(F->getFunctionType()) << ");"; - nl(Out) << "if (!" << getCppName(F) << ") {"; - nl(Out) << getCppName(F); - } + Out << " = mod->getFunction(\""; + printEscapedString(F->getName()); + Out << "\");"; + nl(Out) << "if (!" << getCppName(F) << ") {"; + nl(Out) << getCppName(F); + Out<< " = Function::Create("; nl(Out,1) << "/*Type=*/" << getCppName(F->getFunctionType()) << ","; nl(Out) << "/*Linkage=*/"; @@ -1585,10 +1726,8 @@ void CppWriter::printFunctionHead(const Function* F) { Out << "->setGC(\"" << F->getGC() << "\");"; nl(Out); } - if (is_inline) { - Out << "}"; - nl(Out); - } + Out << "}"; + nl(Out); printAttributes(F->getAttributes(), getCppName(F)); printCppName(F); Out << "->setAttributes(" << getCppName(F) << "_PAL);"; @@ -1616,7 +1755,9 @@ void CppWriter::printFunctionBody(const Function *F) { Out << "Value* " << getCppName(AI) << " = args++;"; nl(Out); if (AI->hasName()) { - Out << getCppName(AI) << "->setName(\"" << AI->getName() << "\");"; + Out << getCppName(AI) << "->setName(\""; + printEscapedString(AI->getName()); + Out << "\");"; nl(Out); } } @@ -1800,14 +1941,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) << "}"; @@ -1947,8 +2080,6 @@ bool CppWriter::runOnModule(Module &M) { fname = "makeLLVMType"; printType(fname,tgtname); break; - default: - error("Invalid generation option"); } return false; @@ -1963,8 +2094,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;