summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorNate Begeman <natebegeman@mac.com>2009-02-04 19:47:21 +0000
committerNate Begeman <natebegeman@mac.com>2009-02-04 19:47:21 +0000
commitd24479730a8790d82c4859dc477bc2416d7a6bda (patch)
tree7e0310ae5edc0f659e09b9d67efe437da9d4e6f9 /utils
parente5ab34e05d701da042619bf540046efc3c7bc41f (diff)
downloadllvm-d24479730a8790d82c4859dc477bc2416d7a6bda.tar.gz
llvm-d24479730a8790d82c4859dc477bc2416d7a6bda.tar.bz2
llvm-d24479730a8790d82c4859dc477bc2416d7a6bda.tar.xz
New feature: add support for target intrinsics being defined in the
target directories themselves. This also means that VMCore no longer needs to know about every target's list of intrinsics. Future work will include converting the PowerPC target to this interface as an example implementation. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@63765 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rw-r--r--utils/TableGen/CodeGenDAGPatterns.cpp3
-rw-r--r--utils/TableGen/CodeGenDAGPatterns.h12
-rw-r--r--utils/TableGen/CodeGenIntrinsics.h3
-rw-r--r--utils/TableGen/CodeGenTarget.cpp10
-rw-r--r--utils/TableGen/IntrinsicEmitter.cpp64
-rw-r--r--utils/TableGen/IntrinsicEmitter.h5
-rw-r--r--utils/TableGen/TableGen.cpp6
7 files changed, 79 insertions, 24 deletions
diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp
index f3bdb4fab3..6e7dd1eae0 100644
--- a/utils/TableGen/CodeGenDAGPatterns.cpp
+++ b/utils/TableGen/CodeGenDAGPatterns.cpp
@@ -1303,7 +1303,8 @@ void TreePattern::dump() const { print(*cerr.stream()); }
// FIXME: REMOVE OSTREAM ARGUMENT
CodeGenDAGPatterns::CodeGenDAGPatterns(RecordKeeper &R) : Records(R) {
- Intrinsics = LoadIntrinsics(Records);
+ Intrinsics = LoadIntrinsics(Records, false);
+ TgtIntrinsics = LoadIntrinsics(Records, true);
ParseNodeInfo();
ParseNodeTransforms();
ParseComplexPatterns();
diff --git a/utils/TableGen/CodeGenDAGPatterns.h b/utils/TableGen/CodeGenDAGPatterns.h
index d44bfc9337..0bd316511e 100644
--- a/utils/TableGen/CodeGenDAGPatterns.h
+++ b/utils/TableGen/CodeGenDAGPatterns.h
@@ -465,6 +465,7 @@ class CodeGenDAGPatterns {
RecordKeeper &Records;
CodeGenTarget Target;
std::vector<CodeGenIntrinsic> Intrinsics;
+ std::vector<CodeGenIntrinsic> TgtIntrinsics;
std::map<Record*, SDNodeInfo> SDNodes;
std::map<Record*, std::pair<Record*, std::string> > SDNodeXForms;
@@ -515,18 +516,25 @@ public:
const CodeGenIntrinsic &getIntrinsic(Record *R) const {
for (unsigned i = 0, e = Intrinsics.size(); i != e; ++i)
if (Intrinsics[i].TheDef == R) return Intrinsics[i];
+ for (unsigned i = 0, e = TgtIntrinsics.size(); i != e; ++i)
+ if (TgtIntrinsics[i].TheDef == R) return TgtIntrinsics[i];
assert(0 && "Unknown intrinsic!");
abort();
}
const CodeGenIntrinsic &getIntrinsicInfo(unsigned IID) const {
- assert(IID-1 < Intrinsics.size() && "Bad intrinsic ID!");
- return Intrinsics[IID-1];
+ if (IID-1 < Intrinsics.size())
+ return Intrinsics[IID-1];
+ if (IID-Intrinsics.size()-1 < TgtIntrinsics.size())
+ return TgtIntrinsics[IID-Intrinsics.size()-1];
+ assert(0 && "Bad intrinsic ID!");
}
unsigned getIntrinsicID(Record *R) const {
for (unsigned i = 0, e = Intrinsics.size(); i != e; ++i)
if (Intrinsics[i].TheDef == R) return i;
+ for (unsigned i = 0, e = TgtIntrinsics.size(); i != e; ++i)
+ if (TgtIntrinsics[i].TheDef == R) return i + Intrinsics.size();
assert(0 && "Unknown intrinsic!");
abort();
}
diff --git a/utils/TableGen/CodeGenIntrinsics.h b/utils/TableGen/CodeGenIntrinsics.h
index dd99e319d6..fea868b8c0 100644
--- a/utils/TableGen/CodeGenIntrinsics.h
+++ b/utils/TableGen/CodeGenIntrinsics.h
@@ -80,7 +80,8 @@ namespace llvm {
/// LoadIntrinsics - Read all of the intrinsics defined in the specified
/// .td file.
- std::vector<CodeGenIntrinsic> LoadIntrinsics(const RecordKeeper &RC);
+ std::vector<CodeGenIntrinsic> LoadIntrinsics(const RecordKeeper &RC,
+ bool TargetOnly);
}
#endif
diff --git a/utils/TableGen/CodeGenTarget.cpp b/utils/TableGen/CodeGenTarget.cpp
index 274cc78c35..9ef64d66b5 100644
--- a/utils/TableGen/CodeGenTarget.cpp
+++ b/utils/TableGen/CodeGenTarget.cpp
@@ -426,13 +426,17 @@ ComplexPattern::ComplexPattern(Record *R) {
// CodeGenIntrinsic Implementation
//===----------------------------------------------------------------------===//
-std::vector<CodeGenIntrinsic> llvm::LoadIntrinsics(const RecordKeeper &RC) {
+std::vector<CodeGenIntrinsic> llvm::LoadIntrinsics(const RecordKeeper &RC,
+ bool TargetOnly) {
std::vector<Record*> I = RC.getAllDerivedDefinitions("Intrinsic");
std::vector<CodeGenIntrinsic> Result;
- for (unsigned i = 0, e = I.size(); i != e; ++i)
- Result.push_back(CodeGenIntrinsic(I[i]));
+ for (unsigned i = 0, e = I.size(); i != e; ++i) {
+ bool isTarget = I[i]->getValueAsBit("isTarget");
+ if (isTarget == TargetOnly)
+ Result.push_back(CodeGenIntrinsic(I[i]));
+ }
return Result;
}
diff --git a/utils/TableGen/IntrinsicEmitter.cpp b/utils/TableGen/IntrinsicEmitter.cpp
index eda55e1430..53081ffb65 100644
--- a/utils/TableGen/IntrinsicEmitter.cpp
+++ b/utils/TableGen/IntrinsicEmitter.cpp
@@ -25,7 +25,10 @@ using namespace llvm;
void IntrinsicEmitter::run(std::ostream &OS) {
EmitSourceFileHeader("Intrinsic Function Source Fragment", OS);
- std::vector<CodeGenIntrinsic> Ints = LoadIntrinsics(Records);
+ std::vector<CodeGenIntrinsic> Ints = LoadIntrinsics(Records, TargetOnly);
+
+ if (TargetOnly && !Ints.empty())
+ TargetPrefix = Ints[0].TargetPrefix;
// Emit the enum information.
EmitEnumInfo(Ints, OS);
@@ -91,12 +94,12 @@ EmitFnNameRecognizer(const std::vector<CodeGenIntrinsic> &Ints,
if (Ints[I->second].isOverloaded)
OS << " if (Len > " << I->first.size()
<< " && !memcmp(Name, \"" << I->first << ".\", "
- << (I->first.size() + 1) << ")) return Intrinsic::"
+ << (I->first.size() + 1) << ")) return " << TargetPrefix << "Intrinsic::"
<< Ints[I->second].EnumName << ";\n";
else
OS << " if (Len == " << I->first.size()
<< " && !memcmp(Name, \"" << I->first << "\", "
- << I->first.size() << ")) return Intrinsic::"
+ << I->first.size() << ")) return " << TargetPrefix << "Intrinsic::"
<< Ints[I->second].EnumName << ";\n";
}
OS << " }\n";
@@ -351,11 +354,13 @@ void IntrinsicEmitter::EmitGenerator(const std::vector<CodeGenIntrinsic> &Ints,
Ints[i].IS.ParamTypeDefs)].push_back(i);
// Loop through the array, emitting one generator for each batch.
+ std::string IntrinsicStr = TargetPrefix + "Intrinsic::";
+
for (MapTy::iterator I = UniqueArgInfos.begin(),
E = UniqueArgInfos.end(); I != E; ++I) {
for (unsigned i = 0, e = I->second.size(); i != e; ++i)
- OS << " case Intrinsic::" << Ints[I->second[i]].EnumName << ":\t\t// "
- << Ints[I->second[i]].Name << "\n";
+ OS << " case " << IntrinsicStr << Ints[I->second[i]].EnumName
+ << ":\t\t// " << Ints[I->second[i]].Name << "\n";
const RecPair &ArgTypes = I->first;
const std::vector<Record*> &RetTys = ArgTypes.first;
@@ -392,7 +397,11 @@ void IntrinsicEmitter::
EmitAttributes(const std::vector<CodeGenIntrinsic> &Ints, std::ostream &OS) {
OS << "// Add parameter attributes that are not common to all intrinsics.\n";
OS << "#ifdef GET_INTRINSIC_ATTRIBUTES\n";
- OS << "AttrListPtr Intrinsic::getAttributes(ID id) {";
+ if (TargetOnly)
+ OS << "static AttrListPtr getAttributes(" << TargetPrefix
+ << "Intrinsic::ID id) {";
+ else
+ OS << "AttrListPtr Intrinsic::getAttributes(ID id) {";
OS << " // No intrinsic can throw exceptions.\n";
OS << " Attributes Attr = Attribute::NoUnwind;\n";
OS << " switch (id) {\n";
@@ -404,7 +413,8 @@ EmitAttributes(const std::vector<CodeGenIntrinsic> &Ints, std::ostream &OS) {
switch (Ints[i].ModRef) {
default: break;
case CodeGenIntrinsic::NoMem:
- OS << " case Intrinsic::" << Ints[i].EnumName << ":\n";
+ OS << " case " << TargetPrefix << "Intrinsic::" << Ints[i].EnumName
+ << ":\n";
break;
}
}
@@ -415,7 +425,8 @@ EmitAttributes(const std::vector<CodeGenIntrinsic> &Ints, std::ostream &OS) {
default: break;
case CodeGenIntrinsic::ReadArgMem:
case CodeGenIntrinsic::ReadMem:
- OS << " case Intrinsic::" << Ints[i].EnumName << ":\n";
+ OS << " case " << TargetPrefix << "Intrinsic::" << Ints[i].EnumName
+ << ":\n";
break;
}
}
@@ -431,7 +442,8 @@ EmitAttributes(const std::vector<CodeGenIntrinsic> &Ints, std::ostream &OS) {
for (unsigned i = 0, e = Ints.size(); i != e; ++i) {
if (Ints[i].ArgumentAttributes.empty()) continue;
- OS << " case Intrinsic::" << Ints[i].EnumName << ":\n";
+ OS << " case " << TargetPrefix << "Intrinsic::" << Ints[i].EnumName
+ << ":\n";
std::vector<std::pair<unsigned, CodeGenIntrinsic::ArgAttribute> > ArgAttrs =
Ints[i].ArgumentAttributes;
@@ -495,7 +507,7 @@ EmitGCCBuiltinList(const std::vector<CodeGenIntrinsic> &Ints, std::ostream &OS){
typedef std::map<std::string, std::string>::const_iterator StrMapIterator;
static void EmitBuiltinComparisons(StrMapIterator Start, StrMapIterator End,
unsigned CharStart, unsigned Indent,
- std::ostream &OS) {
+ std::string TargetPrefix, std::ostream &OS) {
if (Start == End) return; // empty range.
// Determine what, if anything, is the same about all these strings.
@@ -522,7 +534,8 @@ static void EmitBuiltinComparisons(StrMapIterator Start, StrMapIterator End,
OS << CommonString.size() - CharStart << "))\n";
++Indent;
}
- OS << std::string(Indent*2, ' ') << "IntrinsicID = Intrinsic::";
+ OS << std::string(Indent*2, ' ') << "IntrinsicID = " << TargetPrefix
+ << "Intrinsic::";
OS << Start->second << ";\n";
return;
}
@@ -535,7 +548,8 @@ static void EmitBuiltinComparisons(StrMapIterator Start, StrMapIterator End,
OS << ", \"" << (CommonString.c_str()+CharStart) << "\", ";
OS << CommonString.size()-CharStart << ")) {\n";
- EmitBuiltinComparisons(Start, End, CommonString.size(), Indent+1, OS);
+ EmitBuiltinComparisons(Start, End, CommonString.size(), Indent+1,
+ TargetPrefix, OS);
OS << std::string(Indent*2, ' ') << "}\n";
return;
}
@@ -556,7 +570,7 @@ static void EmitBuiltinComparisons(StrMapIterator Start, StrMapIterator End,
for (++NextChar; NextChar != End && NextChar->first[CharStart] == ThisChar;
++NextChar)
/*empty*/;
- EmitBuiltinComparisons(I, NextChar, CharStart+1, Indent+1, OS);
+ EmitBuiltinComparisons(I, NextChar, CharStart+1, Indent+1, TargetPrefix,OS);
OS << std::string(Indent*2, ' ') << " break;\n";
I = NextChar;
}
@@ -566,6 +580,7 @@ static void EmitBuiltinComparisons(StrMapIterator Start, StrMapIterator End,
/// EmitTargetBuiltins - All of the builtins in the specified map are for the
/// same target, and we already checked it.
static void EmitTargetBuiltins(const std::map<std::string, std::string> &BIM,
+ const std::string &TargetPrefix,
std::ostream &OS) {
// Rearrange the builtins by length.
std::vector<std::map<std::string, std::string> > BuiltinsByLen;
@@ -584,7 +599,7 @@ static void EmitTargetBuiltins(const std::map<std::string, std::string> &BIM,
if (BuiltinsByLen[i].empty()) continue;
OS << " case " << i << ":\n";
EmitBuiltinComparisons(BuiltinsByLen[i].begin(), BuiltinsByLen[i].end(),
- 0, 3, OS);
+ 0, 3, TargetPrefix, OS);
OS << " break;\n";
}
OS << " }\n";
@@ -613,7 +628,22 @@ EmitIntrinsicToGCCBuiltinMap(const std::vector<CodeGenIntrinsic> &Ints,
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";
- OS << " IntrinsicID = Intrinsic::not_intrinsic;\n";
+
+ if (TargetOnly) {
+ OS << "static " << TargetPrefix << "Intrinsic::ID "
+ << "getIntrinsicForGCCBuiltin(const char "
+ << "*TargetPrefix, const char *BuiltinName) {\n";
+ OS << " " << TargetPrefix << "Intrinsic::ID IntrinsicID = ";
+ } else {
+ OS << "Intrinsic::ID Intrinsic::getIntrinsicForGCCBuiltin(const char "
+ << "*TargetPrefix, const char *BuiltinName) {\n";
+ OS << " Intrinsic::ID IntrinsicID = ";
+ }
+
+ if (TargetOnly)
+ OS << "(" << TargetPrefix<< "Intrinsic::ID)";
+
+ OS << "Intrinsic::not_intrinsic;\n";
// Note: this could emit significantly better code if we cared.
for (BIMTy::iterator I = BuiltinMap.begin(), E = BuiltinMap.end();I != E;++I){
@@ -625,8 +655,10 @@ EmitIntrinsicToGCCBuiltinMap(const std::vector<CodeGenIntrinsic> &Ints,
OS << "{\n";
// Emit the comparisons for this target prefix.
- EmitTargetBuiltins(I->second, OS);
+ EmitTargetBuiltins(I->second, TargetPrefix, OS);
OS << " }\n";
}
+ OS << " return IntrinsicID;\n";
+ OS << "}\n";
OS << "#endif\n\n";
}
diff --git a/utils/TableGen/IntrinsicEmitter.h b/utils/TableGen/IntrinsicEmitter.h
index 357369263b..0f3f0e72b6 100644
--- a/utils/TableGen/IntrinsicEmitter.h
+++ b/utils/TableGen/IntrinsicEmitter.h
@@ -20,9 +20,12 @@
namespace llvm {
class IntrinsicEmitter : public TableGenBackend {
RecordKeeper &Records;
+ bool TargetOnly;
+ std::string TargetPrefix;
public:
- IntrinsicEmitter(RecordKeeper &R) : Records(R) {}
+ IntrinsicEmitter(RecordKeeper &R, bool T = false)
+ : Records(R), TargetOnly(T) {}
void run(std::ostream &OS);
diff --git a/utils/TableGen/TableGen.cpp b/utils/TableGen/TableGen.cpp
index c6692f805b..98a188ed83 100644
--- a/utils/TableGen/TableGen.cpp
+++ b/utils/TableGen/TableGen.cpp
@@ -49,6 +49,7 @@ enum ActionType {
GenFastISel,
GenSubtarget,
GenIntrinsic,
+ GenTgtIntrinsic,
GenLLVMCConf,
PrintEnums
};
@@ -82,6 +83,8 @@ namespace {
"Generate subtarget enumerations"),
clEnumValN(GenIntrinsic, "gen-intrinsic",
"Generate intrinsic information"),
+ clEnumValN(GenTgtIntrinsic, "gen-tgt-intrinsic",
+ "Generate target intrinsic information"),
clEnumValN(GenLLVMCConf, "gen-llvmc",
"Generate LLVMC configuration library"),
clEnumValN(PrintEnums, "print-enums",
@@ -190,6 +193,9 @@ int main(int argc, char **argv) {
case GenIntrinsic:
IntrinsicEmitter(Records).run(*Out);
break;
+ case GenTgtIntrinsic:
+ IntrinsicEmitter(Records, true).run(*Out);
+ break;
case GenLLVMCConf:
LLVMCConfigurationEmitter(Records).run(*Out);
break;