X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FCppBackend%2FCPPBackend.cpp;h=107c6ccb47dddcc876b882429b8d2fbb8d5da4a0;hb=3d3abe0852d5f499bed7ab014519dd582a0a795d;hp=7f5f5e189e83d64e383427cbaca52047085dcff0;hpb=10c6d12a9fd4dab411091f64db4db69670b88850;p=oota-llvm.git diff --git a/lib/Target/CppBackend/CPPBackend.cpp b/lib/Target/CppBackend/CPPBackend.cpp index 7f5f5e189e8..107c6ccb47d 100644 --- a/lib/Target/CppBackend/CPPBackend.cpp +++ b/lib/Target/CppBackend/CPPBackend.cpp @@ -29,7 +29,7 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FormattedStream.h" -#include "llvm/Target/TargetRegistry.h" +#include "llvm/Support/TargetRegistry.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Config/config.h" #include @@ -154,7 +154,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(); }; @@ -189,7 +189,6 @@ static std::string getTypePrefix(Type *Ty) { case Type::VectorTyID: return "packed_"; default: return "other_"; } - return "unknown_"; } void CppWriter::error(const std::string& msg) { @@ -301,7 +300,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; @@ -443,7 +441,7 @@ void CppWriter::printAttributes(const AttrListPtr &PAL, 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 "; + Out << "PAWI.Index = " << index << "U; PAWI.Attrs = Attribute::None "; #define HANDLE_ATTR(X) \ if (attrs & Attribute::X) \ Out << " | Attribute::" #X; \ @@ -470,6 +468,9 @@ void CppWriter::printAttributes(const AttrListPtr &PAL, HANDLE_ATTR(NoImplicitFloat); HANDLE_ATTR(Naked); HANDLE_ATTR(InlineHint); + HANDLE_ATTR(ReturnsTwice); + HANDLE_ATTR(UWTable); + HANDLE_ATTR(NonLazyBind); #undef HANDLE_ATTR if (attrs & Attribute::StackAlignment) Out << " | Attribute::constructStackAlignmentFromInt(" @@ -530,12 +531,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); } @@ -553,16 +562,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: { @@ -661,11 +676,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 @@ -683,38 +693,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); @@ -727,14 +716,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(" @@ -742,6 +731,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 +1000,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); @@ -999,6 +1023,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) { @@ -1041,14 +1086,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 ConstantInt* CaseVal = i.getCaseValue(); + const BasicBlock *BB = i.getCaseSuccessor(); Out << iName << "->addCase(" - << opNames[i] << ", " - << opNames[i+1] << ");"; + << getOpName(CaseVal) << ", " + << getOpName(BB) << ");"; nl(Out); } break; @@ -1064,6 +1112,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;"; @@ -1078,8 +1131,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("; @@ -1090,11 +1142,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(), " @@ -1213,15 +1260,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: { @@ -1291,7 +1356,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()) << ", \""; @@ -1401,7 +1466,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; @@ -1418,11 +1483,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); @@ -1528,13 +1647,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=*/"; @@ -1571,10 +1689,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);"; @@ -1602,7 +1718,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); } } @@ -1933,8 +2051,6 @@ bool CppWriter::runOnModule(Module &M) { fname = "makeLLVMType"; printType(fname,tgtname); break; - default: - error("Invalid generation option"); } return false; @@ -1949,7 +2065,6 @@ char CppWriter::ID = 0; bool CPPTargetMachine::addPassesToEmitFile(PassManagerBase &PM, formatted_raw_ostream &o, CodeGenFileType FileType, - CodeGenOpt::Level OptLevel, bool DisableVerify) { if (FileType != TargetMachine::CGFT_AssemblyFile) return true; PM.add(new CppWriter(o));