raw_ostream &OS);
void EmitAttributes(const std::vector<CodeGenIntrinsic> &Ints,
raw_ostream &OS);
- void EmitModRefBehavior(const std::vector<CodeGenIntrinsic> &Ints,
- raw_ostream &OS);
void EmitIntrinsicToGCCBuiltinMap(const std::vector<CodeGenIntrinsic> &Ints,
raw_ostream &OS);
void EmitIntrinsicToMSBuiltinMap(const std::vector<CodeGenIntrinsic> &Ints,
// Emit the intrinsic parameter attributes.
EmitAttributes(Ints, OS);
- // Emit intrinsic alias analysis mod/ref behavior.
- EmitModRefBehavior(Ints, OS);
-
// Emit code to translate GCC builtins into LLVM intrinsics.
EmitIntrinsicToGCCBuiltinMap(Ints, OS);
// Values from 16+ are only encodable with the inefficient encoding.
IIT_V64 = 16,
IIT_MMX = 17,
- IIT_METADATA = 18,
- IIT_EMPTYSTRUCT = 19,
- IIT_STRUCT2 = 20,
- IIT_STRUCT3 = 21,
- IIT_STRUCT4 = 22,
- IIT_STRUCT5 = 23,
- IIT_EXTEND_ARG = 24,
- IIT_TRUNC_ARG = 25,
- IIT_ANYPTR = 26,
- IIT_V1 = 27,
- IIT_VARARG = 28,
- IIT_HALF_VEC_ARG = 29,
- IIT_SAME_VEC_WIDTH_ARG = 30,
- IIT_PTR_TO_ARG = 31,
- IIT_VEC_OF_PTRS_TO_ELT = 32,
- IIT_I128 = 33
+ IIT_TOKEN = 18,
+ IIT_METADATA = 19,
+ IIT_EMPTYSTRUCT = 20,
+ IIT_STRUCT2 = 21,
+ IIT_STRUCT3 = 22,
+ IIT_STRUCT4 = 23,
+ IIT_STRUCT5 = 24,
+ IIT_EXTEND_ARG = 25,
+ IIT_TRUNC_ARG = 26,
+ IIT_ANYPTR = 27,
+ IIT_V1 = 28,
+ IIT_VARARG = 29,
+ IIT_HALF_VEC_ARG = 30,
+ IIT_SAME_VEC_WIDTH_ARG = 31,
+ IIT_PTR_TO_ARG = 32,
+ IIT_VEC_OF_PTRS_TO_ELT = 33,
+ IIT_I128 = 34
};
case MVT::f16: return Sig.push_back(IIT_F16);
case MVT::f32: return Sig.push_back(IIT_F32);
case MVT::f64: return Sig.push_back(IIT_F64);
+ case MVT::token: return Sig.push_back(IIT_TOKEN);
case MVT::Metadata: return Sig.push_back(IIT_METADATA);
case MVT::x86mmx: return Sig.push_back(IIT_MMX);
// MVT::OtherVT is used to mean the empty struct type here.
OS << "#endif\n\n"; // End of GET_INTRINSIC_GENERATOR_GLOBAL
}
-namespace {
-enum ModRefKind {
- MRK_none,
- MRK_readonly,
- MRK_readnone
-};
-}
-
-static ModRefKind getModRefKind(const CodeGenIntrinsic &intrinsic) {
- switch (intrinsic.ModRef) {
- case CodeGenIntrinsic::NoMem:
- return MRK_readnone;
- case CodeGenIntrinsic::ReadArgMem:
- case CodeGenIntrinsic::ReadMem:
- return MRK_readonly;
- case CodeGenIntrinsic::ReadWriteArgMem:
- case CodeGenIntrinsic::ReadWriteMem:
- return MRK_none;
- }
- llvm_unreachable("bad mod-ref kind");
-}
-
namespace {
struct AttributeComparator {
bool operator()(const CodeGenIntrinsic *L, const CodeGenIntrinsic *R) const {
return R->isConvergent;
// Try to order by readonly/readnone attribute.
- ModRefKind LK = getModRefKind(*L);
- ModRefKind RK = getModRefKind(*R);
+ CodeGenIntrinsic::ModRefKind LK = L->ModRef;
+ CodeGenIntrinsic::ModRefKind RK = R->ModRef;
if (LK != RK) return (LK > RK);
// Order by argument attributes.
case CodeGenIntrinsic::ReadNone:
if (addComma)
OS << ",";
- OS << "Attributes::ReadNone";
+ OS << "Attribute::ReadNone";
addComma = true;
break;
}
}
}
- ModRefKind modRef = getModRefKind(intrinsic);
-
- if (!intrinsic.canThrow || modRef || intrinsic.isNoReturn ||
- intrinsic.isNoDuplicate || intrinsic.isConvergent) {
+ if (!intrinsic.canThrow ||
+ intrinsic.ModRef != CodeGenIntrinsic::ReadWriteMem ||
+ intrinsic.isNoReturn || intrinsic.isNoDuplicate ||
+ intrinsic.isConvergent) {
OS << " const Attribute::AttrKind Atts[] = {";
bool addComma = false;
if (!intrinsic.canThrow) {
addComma = true;
}
- switch (modRef) {
- case MRK_none: break;
- case MRK_readonly:
+ switch (intrinsic.ModRef) {
+ case CodeGenIntrinsic::NoMem:
+ if (addComma)
+ OS << ",";
+ OS << "Attribute::ReadNone";
+ break;
+ case CodeGenIntrinsic::ReadArgMem:
+ if (addComma)
+ OS << ",";
+ OS << "Attribute::ReadOnly,";
+ OS << "Attribute::ArgMemOnly";
+ break;
+ case CodeGenIntrinsic::ReadMem:
if (addComma)
OS << ",";
OS << "Attribute::ReadOnly";
break;
- case MRK_readnone:
+ case CodeGenIntrinsic::ReadWriteArgMem:
if (addComma)
OS << ",";
- OS << "Attribute::ReadNone";
+ OS << "Attribute::ArgMemOnly";
+ break;
+ case CodeGenIntrinsic::ReadWriteMem:
break;
}
OS << "};\n";
OS << "#endif // GET_INTRINSIC_ATTRIBUTES\n\n";
}
-/// EmitModRefBehavior - Determine intrinsic alias analysis mod/ref behavior.
-void IntrinsicEmitter::
-EmitModRefBehavior(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS){
- OS << "// Determine intrinsic alias analysis mod/ref behavior.\n"
- << "#ifdef GET_INTRINSIC_MODREF_BEHAVIOR\n"
- << "assert(iid <= Intrinsic::" << Ints.back().EnumName << " && "
- << "\"Unknown intrinsic.\");\n\n";
-
- OS << "static const uint8_t IntrinsicModRefBehavior[] = {\n"
- << " /* invalid */ UnknownModRefBehavior,\n";
- for (unsigned i = 0, e = Ints.size(); i != e; ++i) {
- OS << " /* " << TargetPrefix << Ints[i].EnumName << " */ ";
- switch (Ints[i].ModRef) {
- case CodeGenIntrinsic::NoMem:
- OS << "DoesNotAccessMemory,\n";
- break;
- case CodeGenIntrinsic::ReadArgMem:
- OS << "OnlyReadsArgumentPointees,\n";
- break;
- case CodeGenIntrinsic::ReadMem:
- OS << "OnlyReadsMemory,\n";
- break;
- case CodeGenIntrinsic::ReadWriteArgMem:
- OS << "OnlyAccessesArgumentPointees,\n";
- break;
- case CodeGenIntrinsic::ReadWriteMem:
- OS << "UnknownModRefBehavior,\n";
- break;
- }
- }
- OS << "};\n\n"
- << "return static_cast<ModRefBehavior>(IntrinsicModRefBehavior[iid]);\n"
- << "#endif // GET_INTRINSIC_MODREF_BEHAVIOR\n\n";
-}
-
/// 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,
E = BIM.end(); I != E; ++I) {
std::string ResultCode =
"return " + TargetPrefix + "Intrinsic::" + I->second + ";";
- Results.push_back(StringMatcher::StringPair(I->first, ResultCode));
+ Results.emplace_back(I->first, ResultCode);
}
StringMatcher("BuiltinName", Results, OS).Emit();