diff options
author | dim <dim@FreeBSD.org> | 2014-03-21 17:53:59 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2014-03-21 17:53:59 +0000 |
commit | 9cedb8bb69b89b0f0c529937247a6a80cabdbaec (patch) | |
tree | c978f0e9ec1ab92dc8123783f30b08a7fd1e2a39 /contrib/llvm/utils/TableGen/IntrinsicEmitter.cpp | |
parent | 03fdc2934eb61c44c049a02b02aa974cfdd8a0eb (diff) | |
download | FreeBSD-src-9cedb8bb69b89b0f0c529937247a6a80cabdbaec.zip FreeBSD-src-9cedb8bb69b89b0f0c529937247a6a80cabdbaec.tar.gz |
MFC 261991:
Upgrade our copy of llvm/clang to 3.4 release. This version supports
all of the features in the current working draft of the upcoming C++
standard, provisionally named C++1y.
The code generator's performance is greatly increased, and the loop
auto-vectorizer is now enabled at -Os and -O2 in addition to -O3. The
PowerPC backend has made several major improvements to code generation
quality and compile time, and the X86, SPARC, ARM32, Aarch64 and SystemZ
backends have all seen major feature work.
Release notes for llvm and clang can be found here:
<http://llvm.org/releases/3.4/docs/ReleaseNotes.html>
<http://llvm.org/releases/3.4/tools/clang/docs/ReleaseNotes.html>
MFC 262121 (by emaste):
Update lldb for clang/llvm 3.4 import
This commit largely restores the lldb source to the upstream r196259
snapshot with the addition of threaded inferior support and a few bug
fixes.
Specific upstream lldb revisions restored include:
SVN git
181387 779e6ac
181703 7bef4e2
182099 b31044e
182650 f2dcf35
182683 0d91b80
183862 15c1774
183929 99447a6
184177 0b2934b
184948 4dc3761
184954 007e7bc
186990 eebd175
Sponsored by: DARPA, AFRL
MFC 262186 (by emaste):
Fix mismerge in r262121
A break statement was lost in the merge. The error had no functional
impact, but restore it to reduce the diff against upstream.
MFC 262303:
Pull in r197521 from upstream clang trunk (by rdivacky):
Use the integrated assembler by default on FreeBSD/ppc and ppc64.
Requested by: jhibbits
MFC 262611:
Pull in r196874 from upstream llvm trunk:
Fix a crash that occurs when PWD is invalid.
MCJIT needs to be able to run in hostile environments, even when PWD
is invalid. There's no need to crash MCJIT in this case.
The obvious fix is to simply leave MCContext's CompilationDir empty
when PWD can't be determined. This way, MCJIT clients,
and other clients that link with LLVM don't need a valid working directory.
If we do want to guarantee valid CompilationDir, that should be done
only for clients of getCompilationDir(). This is as simple as checking
for an empty string.
The only current use of getCompilationDir is EmitGenDwarfInfo, which
won't conceivably run with an invalid working dir. However, in the
purely hypothetically and untestable case that this happens, the
AT_comp_dir will be omitted from the compilation_unit DIE.
This should help fix assertions occurring with ports-mgmt/tinderbox,
when it is using jails, and sometimes invalidates clang's current
working directory.
Reported by: decke
MFC 262809:
Pull in r203007 from upstream clang trunk:
Don't produce an alias between destructors with different calling conventions.
Fixes pr19007.
(Please note that is an LLVM PR identifier, not a FreeBSD one.)
This should fix Firefox and/or libxul crashes (due to problems with
regparm/stdcall calling conventions) on i386.
Reported by: multiple users on freebsd-current
PR: bin/187103
MFC 263048:
Repair recognition of "CC" as an alias for the C++ compiler, since it
was silently broken by upstream for a Windows-specific use-case.
Apparently some versions of CMake still rely on this archaic feature...
Reported by: rakuco
MFC 263049:
Garbage collect the old way of adding the libstdc++ include directories
in clang's InitHeaderSearch.cpp. This has been superseded by David
Chisnall's commit in r255321.
Moreover, if libc++ is used, the libstdc++ include directories should
not be in the search path at all. These directories are now only used
if you pass -stdlib=libstdc++.
Diffstat (limited to 'contrib/llvm/utils/TableGen/IntrinsicEmitter.cpp')
-rw-r--r-- | contrib/llvm/utils/TableGen/IntrinsicEmitter.cpp | 178 |
1 files changed, 114 insertions, 64 deletions
diff --git a/contrib/llvm/utils/TableGen/IntrinsicEmitter.cpp b/contrib/llvm/utils/TableGen/IntrinsicEmitter.cpp index df4d847..8f137f8 100644 --- a/contrib/llvm/utils/TableGen/IntrinsicEmitter.cpp +++ b/contrib/llvm/utils/TableGen/IntrinsicEmitter.cpp @@ -84,10 +84,10 @@ void IntrinsicEmitter::run(raw_ostream &OS) { // Emit the function name recognizer. EmitFnNameRecognizer(Ints, OS); - + // Emit the intrinsic declaration generator. EmitGenerator(Ints, OS); - + // Emit the intrinsic parameter attributes. EmitAttributes(Ints, OS); @@ -125,35 +125,53 @@ void IntrinsicEmitter::EmitEnumInfo(const std::vector<CodeGenIntrinsic> &Ints, for (unsigned i = 0, e = Ints.size(); i != e; ++i) { OS << " " << Ints[i].EnumName; OS << ((i != e-1) ? ", " : " "); - OS << std::string(40-Ints[i].EnumName.size(), ' ') + OS << std::string(40-Ints[i].EnumName.size(), ' ') << "// " << Ints[i].Name << "\n"; } OS << "#endif\n\n"; } +struct IntrinsicNameSorter { + IntrinsicNameSorter(const std::vector<CodeGenIntrinsic> &I) + : Ints(I) {} + + // Sort in reverse order of intrinsic name so "abc.def" appears after + // "abd.def.ghi" in the overridden name matcher + bool operator()(unsigned i, unsigned j) { + return Ints[i].Name > Ints[j].Name; + } + +private: + const std::vector<CodeGenIntrinsic> &Ints; +}; + void IntrinsicEmitter:: -EmitFnNameRecognizer(const std::vector<CodeGenIntrinsic> &Ints, +EmitFnNameRecognizer(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS) { // Build a 'first character of function name' -> intrinsic # mapping. std::map<char, std::vector<unsigned> > IntMapping; for (unsigned i = 0, e = Ints.size(); i != e; ++i) IntMapping[Ints[i].Name[5]].push_back(i); - + OS << "// Function name -> enum value recognizer code.\n"; OS << "#ifdef GET_FUNCTION_RECOGNIZER\n"; OS << " StringRef NameR(Name+6, Len-6); // Skip over 'llvm.'\n"; OS << " switch (Name[5]) { // Dispatch on first letter.\n"; OS << " default: break;\n"; + IntrinsicNameSorter Sorter(Ints); // Emit the intrinsic matching stuff by first letter. for (std::map<char, std::vector<unsigned> >::iterator I = IntMapping.begin(), E = IntMapping.end(); I != E; ++I) { OS << " case '" << I->first << "':\n"; std::vector<unsigned> &IntList = I->second; + // Sort intrinsics in reverse order of their names + std::sort(IntList.begin(), IntList.end(), Sorter); + // Emit all the overloaded intrinsics first, build a table of the // non-overloaded ones. std::vector<StringMatcher::StringPair> MatchTable; - + for (unsigned i = 0, e = IntList.size(); i != e; ++i) { unsigned IntNo = IntList[i]; std::string Result = "return " + TargetPrefix + "Intrinsic::" + @@ -170,18 +188,18 @@ EmitFnNameRecognizer(const std::vector<CodeGenIntrinsic> &Ints, OS << " if (NameR.startswith(\"" << TheStr << "\")) " << Result << '\n'; } - + // Emit the matcher logic for the fixed length strings. StringMatcher("NameR", MatchTable, OS).Emit(1); OS << " break; // end of '" << I->first << "' case.\n"; } - + OS << " }\n"; OS << "#endif\n\n"; } void IntrinsicEmitter:: -EmitIntrinsicToNameTable(const std::vector<CodeGenIntrinsic> &Ints, +EmitIntrinsicToNameTable(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS) { OS << "// Intrinsic ID to name table\n"; OS << "#ifdef GET_INTRINSIC_NAME_TABLE\n"; @@ -192,7 +210,7 @@ EmitIntrinsicToNameTable(const std::vector<CodeGenIntrinsic> &Ints, } void IntrinsicEmitter:: -EmitIntrinsicToOverloadTable(const std::vector<CodeGenIntrinsic> &Ints, +EmitIntrinsicToOverloadTable(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS) { OS << "// Intrinsic ID to overload bitset\n"; OS << "#ifdef GET_INTRINSIC_OVERLOAD_TABLE\n"; @@ -242,7 +260,9 @@ enum IIT_Info { IIT_STRUCT5 = 22, IIT_EXTEND_VEC_ARG = 23, IIT_TRUNC_VEC_ARG = 24, - IIT_ANYPTR = 25 + IIT_ANYPTR = 25, + IIT_V1 = 26, + IIT_VARARG = 27 }; @@ -259,7 +279,7 @@ static void EncodeFixedValueType(MVT::SimpleValueType VT, case 64: return Sig.push_back(IIT_I64); } } - + switch (VT) { default: PrintFatalError("unhandled MVT in intrinsic!"); case MVT::f16: return Sig.push_back(IIT_F16); @@ -269,16 +289,18 @@ static void EncodeFixedValueType(MVT::SimpleValueType VT, case MVT::x86mmx: return Sig.push_back(IIT_MMX); // MVT::OtherVT is used to mean the empty struct type here. case MVT::Other: return Sig.push_back(IIT_EMPTYSTRUCT); + // MVT::isVoid is used to represent varargs here. + case MVT::isVoid: return Sig.push_back(IIT_VARARG); } } #ifdef _MSC_VER #pragma optimize("",off) // MSVC 2010 optimizer can't deal with this function. -#endif +#endif static void EncodeFixedType(Record *R, std::vector<unsigned char> &ArgCodes, std::vector<unsigned char> &Sig) { - + if (R->isSubClassOf("LLVMMatchType")) { unsigned Number = R->getValueAsInt("Number"); assert(Number < ArgCodes.size() && "Invalid matching number!"); @@ -290,7 +312,7 @@ static void EncodeFixedType(Record *R, std::vector<unsigned char> &ArgCodes, Sig.push_back(IIT_ARG); return Sig.push_back((Number << 2) | ArgCodes[Number]); } - + MVT::SimpleValueType VT = getValueType(R->getValueAsDef("VT")); unsigned Tmp = 0; @@ -301,17 +323,17 @@ static void EncodeFixedType(Record *R, std::vector<unsigned char> &ArgCodes, case MVT::fAny: ++Tmp; // FALL THROUGH. case MVT::iAny: { // If this is an "any" valuetype, then the type is the type of the next - // type in the list specified to getIntrinsic(). + // type in the list specified to getIntrinsic(). Sig.push_back(IIT_ARG); - + // Figure out what arg # this is consuming, and remember what kind it was. unsigned ArgNo = ArgCodes.size(); ArgCodes.push_back(Tmp); - + // Encode what sort of argument it must be in the low 2 bits of the ArgNo. return Sig.push_back((ArgNo << 2) | Tmp); } - + case MVT::iPTR: { unsigned AddrSpace = 0; if (R->isSubClassOf("LLVMQualPointerType")) { @@ -327,18 +349,19 @@ static void EncodeFixedType(Record *R, std::vector<unsigned char> &ArgCodes, return EncodeFixedType(R->getValueAsDef("ElTy"), ArgCodes, Sig); } } - + if (EVT(VT).isVector()) { EVT VVT = VT; switch (VVT.getVectorNumElements()) { default: PrintFatalError("unhandled vector type width in intrinsic!"); + case 1: Sig.push_back(IIT_V1); break; case 2: Sig.push_back(IIT_V2); break; case 4: Sig.push_back(IIT_V4); break; case 8: Sig.push_back(IIT_V8); break; case 16: Sig.push_back(IIT_V16); break; case 32: Sig.push_back(IIT_V32); break; } - + return EncodeFixedValueType(VVT.getVectorElementType(). getSimpleVT().SimpleTy, Sig); } @@ -355,7 +378,7 @@ static void EncodeFixedType(Record *R, std::vector<unsigned char> &ArgCodes, static void ComputeFixedEncoding(const CodeGenIntrinsic &Int, std::vector<unsigned char> &TypeSig) { std::vector<unsigned char> ArgCodes; - + if (Int.IS.RetVTs.empty()) TypeSig.push_back(IIT_Done); else if (Int.IS.RetVTs.size() == 1 && @@ -370,11 +393,11 @@ static void ComputeFixedEncoding(const CodeGenIntrinsic &Int, case 5: TypeSig.push_back(IIT_STRUCT5); break; default: assert(0 && "Unhandled case in struct"); } - + for (unsigned i = 0, e = Int.IS.RetVTs.size(); i != e; ++i) EncodeFixedType(Int.IS.RetTypeDefs[i], ArgCodes, TypeSig); } - + for (unsigned i = 0, e = Int.IS.ParamTypeDefs.size(); i != e; ++i) EncodeFixedType(Int.IS.ParamTypeDefs[i], ArgCodes, TypeSig); } @@ -383,16 +406,16 @@ static void printIITEntry(raw_ostream &OS, unsigned char X) { OS << (unsigned)X; } -void IntrinsicEmitter::EmitGenerator(const std::vector<CodeGenIntrinsic> &Ints, +void IntrinsicEmitter::EmitGenerator(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS) { // If we can compute a 32-bit fixed encoding for this intrinsic, do so and // capture it in this vector, otherwise store a ~0U. std::vector<unsigned> FixedEncodings; - + SequenceToOffsetTable<std::vector<unsigned char> > LongEncodingTable; - + std::vector<unsigned char> TypeSig; - + // Compute the unique argument type info. for (unsigned i = 0, e = Ints.size(); i != e; ++i) { // Get the signature for the intrinsic. @@ -412,7 +435,7 @@ void IntrinsicEmitter::EmitGenerator(const std::vector<CodeGenIntrinsic> &Ints, } Result = (Result << 4) | TypeSig[e-i-1]; } - + // If this could be encoded into a 31-bit word, return it. if (!Failed && (Result >> 31) == 0) { FixedEncodings.push_back(Result); @@ -423,45 +446,45 @@ void IntrinsicEmitter::EmitGenerator(const std::vector<CodeGenIntrinsic> &Ints, // Otherwise, we're going to unique the sequence into the // LongEncodingTable, and use its offset in the 32-bit table instead. LongEncodingTable.add(TypeSig); - + // This is a placehold that we'll replace after the table is laid out. FixedEncodings.push_back(~0U); } - + LongEncodingTable.layout(); - + OS << "// Global intrinsic function declaration type table.\n"; OS << "#ifdef GET_INTRINSIC_GENERATOR_GLOBAL\n"; OS << "static const unsigned IIT_Table[] = {\n "; - + for (unsigned i = 0, e = FixedEncodings.size(); i != e; ++i) { if ((i & 7) == 7) OS << "\n "; - + // If the entry fit in the table, just emit it. if (FixedEncodings[i] != ~0U) { OS << "0x" << utohexstr(FixedEncodings[i]) << ", "; continue; } - + TypeSig.clear(); ComputeFixedEncoding(Ints[i], TypeSig); - + // Otherwise, emit the offset into the long encoding table. We emit it this // way so that it is easier to read the offset in the .def file. OS << "(1U<<31) | " << LongEncodingTable.get(TypeSig) << ", "; } - + OS << "0\n};\n\n"; - + // Emit the shared table of register lists. OS << "static const unsigned char IIT_LongEncodingTable[] = {\n"; if (!LongEncodingTable.empty()) LongEncodingTable.emit(OS, printIITEntry); OS << " 255\n};\n\n"; - + OS << "#endif\n\n"; // End of GET_INTRINSIC_GENERATOR_GLOBAL } @@ -549,7 +572,6 @@ EmitAttributes(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS) { OS << " AttributeSet AS[" << maxArgAttrs+1 << "];\n"; OS << " unsigned NumAttrs = 0;\n"; OS << " if (id != 0) {\n"; - OS << " SmallVector<Attribute::AttrKind, 8> AttrVec;\n"; OS << " switch(IntrinsicsToAttributesMap[id - "; if (TargetOnly) OS << "Intrinsic::num_intrinsics"; @@ -559,7 +581,7 @@ EmitAttributes(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS) { OS << " default: llvm_unreachable(\"Invalid attribute number\");\n"; for (UniqAttrMapTy::const_iterator I = UniqAttributes.begin(), E = UniqAttributes.end(); I != E; ++I) { - OS << " case " << I->second << ":\n"; + OS << " case " << I->second << ": {\n"; const CodeGenIntrinsic &intrinsic = *(I->first); @@ -572,54 +594,82 @@ EmitAttributes(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS) { while (ai != ae) { unsigned argNo = intrinsic.ArgumentAttributes[ai].first; - OS << " AttrVec.clear();\n"; + OS << " const Attribute::AttrKind AttrParam" << argNo + 1 <<"[]= {"; + bool addComma = false; do { switch (intrinsic.ArgumentAttributes[ai].second) { case CodeGenIntrinsic::NoCapture: - OS << " AttrVec.push_back(Attribute::NoCapture);\n"; + if (addComma) + OS << ","; + OS << "Attribute::NoCapture"; + addComma = true; + break; + case CodeGenIntrinsic::ReadOnly: + if (addComma) + OS << ","; + OS << "Attribute::ReadOnly"; + addComma = true; + break; + case CodeGenIntrinsic::ReadNone: + if (addComma) + OS << ","; + OS << "Attributes::ReadNone"; + addComma = true; break; } ++ai; } while (ai != ae && intrinsic.ArgumentAttributes[ai].first == argNo); - + OS << "};\n"; OS << " AS[" << numAttrs++ << "] = AttributeSet::get(C, " - << argNo+1 << ", AttrVec);\n"; + << argNo+1 << ", AttrParam" << argNo +1 << ");\n"; } } ModRefKind modRef = getModRefKind(intrinsic); if (!intrinsic.canThrow || modRef || intrinsic.isNoReturn) { - OS << " AttrVec.clear();\n"; - - if (!intrinsic.canThrow) - OS << " AttrVec.push_back(Attribute::NoUnwind);\n"; - if (intrinsic.isNoReturn) - OS << " AttrVec.push_back(Attribute::NoReturn);\n"; + OS << " const Attribute::AttrKind Atts[] = {"; + bool addComma = false; + if (!intrinsic.canThrow) { + OS << "Attribute::NoUnwind"; + addComma = true; + } + if (intrinsic.isNoReturn) { + if (addComma) + OS << ","; + OS << "Attribute::NoReturn"; + addComma = true; + } switch (modRef) { case MRK_none: break; case MRK_readonly: - OS << " AttrVec.push_back(Attribute::ReadOnly);\n"; + if (addComma) + OS << ","; + OS << "Attribute::ReadOnly"; break; case MRK_readnone: - OS << " AttrVec.push_back(Attribute::ReadNone);\n"; + if (addComma) + OS << ","; + OS << "Attribute::ReadNone"; break; } + OS << "};\n"; OS << " AS[" << numAttrs++ << "] = AttributeSet::get(C, " - << "AttributeSet::FunctionIndex, AttrVec);\n"; + << "AttributeSet::FunctionIndex, Atts);\n"; } if (numAttrs) { OS << " NumAttrs = " << numAttrs << ";\n"; OS << " break;\n"; + OS << " }\n"; } else { OS << " return AttributeSet();\n"; } } - + OS << " }\n"; OS << " }\n"; OS << " return AttributeSet::get(C, ArrayRef<AttributeSet>(AS, " @@ -668,9 +718,9 @@ EmitModRefBehavior(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS){ static void EmitTargetBuiltins(const std::map<std::string, std::string> &BIM, const std::string &TargetPrefix, raw_ostream &OS) { - + std::vector<StringMatcher::StringPair> Results; - + for (std::map<std::string, std::string>::const_iterator I = BIM.begin(), E = BIM.end(); I != E; ++I) { std::string ResultCode = @@ -681,9 +731,9 @@ static void EmitTargetBuiltins(const std::map<std::string, std::string> &BIM, StringMatcher("BuiltinName", Results, OS).Emit(); } - + void IntrinsicEmitter:: -EmitIntrinsicToGCCBuiltinMap(const std::vector<CodeGenIntrinsic> &Ints, +EmitIntrinsicToGCCBuiltinMap(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS) { typedef std::map<std::string, std::map<std::string, std::string> > BIMTy; BIMTy BuiltinMap; @@ -691,20 +741,20 @@ EmitIntrinsicToGCCBuiltinMap(const std::vector<CodeGenIntrinsic> &Ints, if (!Ints[i].GCCBuiltinName.empty()) { // Get the map for this target prefix. std::map<std::string, std::string> &BIM =BuiltinMap[Ints[i].TargetPrefix]; - + if (!BIM.insert(std::make_pair(Ints[i].GCCBuiltinName, Ints[i].EnumName)).second) PrintFatalError("Intrinsic '" + Ints[i].TheDef->getName() + "': duplicate GCC builtin name!"); } } - + OS << "// Get the LLVM intrinsic that corresponds to a GCC builtin.\n"; OS << "// This is used by the C front-end. The GCC builtin name is passed\n"; OS << "// in as BuiltinName, and a target prefix (e.g. 'ppc') is passed\n"; OS << "// in as TargetPrefix. The result is assigned to 'IntrinsicID'.\n"; OS << "#ifdef GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN\n"; - + if (TargetOnly) { OS << "static " << TargetPrefix << "Intrinsic::ID " << "getIntrinsicForGCCBuiltin(const char " @@ -713,10 +763,10 @@ EmitIntrinsicToGCCBuiltinMap(const std::vector<CodeGenIntrinsic> &Ints, OS << "Intrinsic::ID Intrinsic::getIntrinsicForGCCBuiltin(const char " << "*TargetPrefixStr, const char *BuiltinNameStr) {\n"; } - + OS << " StringRef BuiltinName(BuiltinNameStr);\n"; OS << " StringRef TargetPrefix(TargetPrefixStr);\n\n"; - + // Note: this could emit significantly better code if we cared. for (BIMTy::iterator I = BuiltinMap.begin(), E = BuiltinMap.end();I != E;++I){ OS << " "; |