}
}
-static void EmitTypeGenerate(std::ostream &OS, Record *ArgType,
+static void EmitTypeGenerate(std::ostream &OS, const Record *ArgType,
+ unsigned &ArgNo);
+
+static void EmitTypeGenerate(std::ostream &OS,
+ const std::vector<Record*> &ArgTypes,
+ unsigned &ArgNo) {
+ if (ArgTypes.size() == 1) {
+ EmitTypeGenerate(OS, ArgTypes.front(), ArgNo);
+ return;
+ }
+
+ OS << "StructType::get(";
+
+ for (std::vector<Record*>::const_iterator
+ I = ArgTypes.begin(), E = ArgTypes.end(); I != E; ++I) {
+ EmitTypeGenerate(OS, *I, ArgNo);
+ OS << ", ";
+ }
+
+ OS << " NULL)";
+}
+
+static void EmitTypeGenerate(std::ostream &OS, const Record *ArgType,
unsigned &ArgNo) {
MVT::SimpleValueType VT = getValueType(ArgType->getValueAsDef("VT"));
OS << "PointerType::getUnqual(";
EmitTypeGenerate(OS, ArgType->getValueAsDef("ElTy"), ArgNo);
OS << ")";
+ } else if (VT == MVT::iPTRAny) {
+ // Make sure the user has passed us an argument type to overload. If not,
+ // treat it as an ordinary (not overloaded) intrinsic.
+ OS << "(" << ArgNo << " < numTys) ? Tys[" << ArgNo
+ << "] : PointerType::getUnqual(";
+ EmitTypeGenerate(OS, ArgType->getValueAsDef("ElTy"), ArgNo);
+ OS << ")";
+ ++ArgNo;
} else if (VT == MVT::isVoid) {
if (ArgNo == 0)
OS << "Type::VoidTy";
/// RecordListComparator - Provide a determinstic comparator for lists of
/// records.
namespace {
+ typedef std::pair<std::vector<Record*>, std::vector<Record*> > RecPair;
struct RecordListComparator {
- bool operator()(const std::vector<Record*> &LHS,
- const std::vector<Record*> &RHS) const {
+ bool operator()(const RecPair &LHS,
+ const RecPair &RHS) const {
unsigned i = 0;
+ const std::vector<Record*> *LHSVec = &LHS.first;
+ const std::vector<Record*> *RHSVec = &RHS.first;
+ unsigned RHSSize = RHSVec->size();
+ unsigned LHSSize = LHSVec->size();
+
do {
- if (i == RHS.size()) return false; // RHS is shorter than LHS.
- if (LHS[i] != RHS[i])
- return LHS[i]->getName() < RHS[i]->getName();
- } while (++i != LHS.size());
-
- return i != RHS.size();
+ if (i == RHSSize) return false; // RHS is shorter than LHS.
+ if ((*LHSVec)[i] != (*RHSVec)[i])
+ return (*LHSVec)[i]->getName() < (*RHSVec)[i]->getName();
+ } while (++i != LHSSize);
+
+ if (i != RHSSize) return true;
+
+ i = 0;
+ LHSVec = &LHS.second;
+ RHSVec = &RHS.second;
+ RHSSize = RHSVec->size();
+ LHSSize = LHSVec->size();
+
+ for (i = 0; i != LHSSize; ++i) {
+ if (i == RHSSize) return false; // RHS is shorter than LHS.
+ if ((*LHSVec)[i] != (*RHSVec)[i])
+ return (*LHSVec)[i]->getName() < (*RHSVec)[i]->getName();
+ }
+
+ return i != RHSSize;
}
};
}
// This checking can emit a lot of very common code. To reduce the amount of
// code that we emit, batch up cases that have identical types. This avoids
// problems where GCC can run out of memory compiling Verifier.cpp.
- typedef std::map<std::vector<Record*>, std::vector<unsigned>,
- RecordListComparator> MapTy;
+ typedef std::map<RecPair, std::vector<unsigned>, RecordListComparator> MapTy;
MapTy UniqueArgInfos;
// Compute the unique argument type info.
for (unsigned i = 0, e = Ints.size(); i != e; ++i)
- UniqueArgInfos[Ints[i].ArgTypeDefs].push_back(i);
+ UniqueArgInfos[make_pair(Ints[i].IS.RetTypeDefs,
+ Ints[i].IS.ParamTypeDefs)].push_back(i);
// Loop through the array, emitting one comparison for each batch.
for (MapTy::iterator I = UniqueArgInfos.begin(),
E = UniqueArgInfos.end(); I != E; ++I) {
- for (unsigned i = 0, e = I->second.size(); 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";
- }
- const std::vector<Record*> &ArgTypes = I->first;
- OS << " VerifyIntrinsicPrototype(ID, IF, " << ArgTypes.size() << ", ";
- for (unsigned j = 0; j != ArgTypes.size(); ++j) {
- Record *ArgType = ArgTypes[j];
+ const RecPair &ArgTypes = I->first;
+ const std::vector<Record*> &RetTys = ArgTypes.first;
+ const std::vector<Record*> &ParamTys = ArgTypes.second;
+
+ OS << " VerifyIntrinsicPrototype(ID, IF, " << RetTys.size() << ", "
+ << ParamTys.size();
+
+ // Emit return types.
+ for (unsigned j = 0, je = RetTys.size(); j != je; ++j) {
+ Record *ArgType = RetTys[j];
+ OS << ", ";
+
if (ArgType->isSubClassOf("LLVMMatchType")) {
unsigned Number = ArgType->getValueAsInt("Number");
assert(Number < j && "Invalid matching number!");
} else {
MVT::SimpleValueType VT = getValueType(ArgType->getValueAsDef("VT"));
OS << getEnumName(VT);
- if (VT == MVT::isVoid && j != 0 && j != ArgTypes.size()-1)
+
+ if (VT == MVT::isVoid && j != 0 && j != je - 1)
+ throw "Var arg type not last argument";
+ }
+ }
+
+ // Emit the parameter types.
+ for (unsigned j = 0, je = ParamTys.size(); j != je; ++j) {
+ Record *ArgType = ParamTys[j];
+ OS << ", ";
+
+ if (ArgType->isSubClassOf("LLVMMatchType")) {
+ unsigned Number = ArgType->getValueAsInt("Number");
+ assert(Number < j + RetTys.size() && "Invalid matching number!");
+ OS << "~" << Number;
+ } else {
+ MVT::SimpleValueType VT = getValueType(ArgType->getValueAsDef("VT"));
+ OS << getEnumName(VT);
+
+ if (VT == MVT::isVoid && j != 0 && j != je - 1)
throw "Var arg type not last argument";
}
- if (j != ArgTypes.size()-1)
- OS << ", ";
}
OS << ");\n";
// Similar to GET_INTRINSIC_VERIFIER, batch up cases that have identical
// types.
- typedef std::map<std::vector<Record*>, std::vector<unsigned>,
- RecordListComparator> MapTy;
+ typedef std::map<RecPair, std::vector<unsigned>, RecordListComparator> MapTy;
MapTy UniqueArgInfos;
// Compute the unique argument type info.
for (unsigned i = 0, e = Ints.size(); i != e; ++i)
- UniqueArgInfos[Ints[i].ArgTypeDefs].push_back(i);
+ UniqueArgInfos[make_pair(Ints[i].IS.RetTypeDefs,
+ Ints[i].IS.ParamTypeDefs)].push_back(i);
// Loop through the array, emitting one generator for each batch.
for (MapTy::iterator I = UniqueArgInfos.begin(),
E = UniqueArgInfos.end(); I != E; ++I) {
- for (unsigned i = 0, e = I->second.size(); 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";
- }
- const std::vector<Record*> &ArgTypes = I->first;
- unsigned N = ArgTypes.size();
+ const RecPair &ArgTypes = I->first;
+ const std::vector<Record*> &RetTys = ArgTypes.first;
+ const std::vector<Record*> &ParamTys = ArgTypes.second;
+
+ unsigned N = ParamTys.size();
if (N > 1 &&
- getValueType(ArgTypes[N-1]->getValueAsDef("VT")) == MVT::isVoid) {
+ getValueType(ParamTys[N - 1]->getValueAsDef("VT")) == MVT::isVoid) {
OS << " IsVarArg = true;\n";
--N;
}
-
+
unsigned ArgNo = 0;
OS << " ResultTy = ";
- EmitTypeGenerate(OS, ArgTypes[0], ArgNo);
+ EmitTypeGenerate(OS, RetTys, ArgNo);
OS << ";\n";
- for (unsigned j = 1; j != N; ++j) {
+ for (unsigned j = 0; j != N; ++j) {
OS << " ArgTys.push_back(";
- EmitTypeGenerate(OS, ArgTypes[j], ArgNo);
+ EmitTypeGenerate(OS, ParamTys[j], ArgNo);
OS << ");\n";
}
+
OS << " break;\n";
}
+
OS << " }\n";
OS << "#endif\n\n";
}
break;
}
}
- OS << " Attr |= ParamAttr::ReadNone; // These do not access memory.\n";
+ OS << " Attr |= Attribute::ReadNone; // These do not access memory.\n";
OS << " break;\n";
for (unsigned i = 0, e = Ints.size(); i != e; ++i) {
switch (Ints[i].ModRef) {
break;
}
}
- OS << " Attr |= ParamAttr::ReadOnly; // These do not write memory.\n";
+ OS << " Attr |= Attribute::ReadOnly; // These do not write memory.\n";
OS << " break;\n";
OS << " }\n";
OS << "#endif\n\n";