summaryrefslogtreecommitdiffstats
path: root/clang/utils/TableGen
diff options
context:
space:
mode:
authorSimon Tatham <simon.tatham@arm.com>2019-11-13 15:23:38 +0000
committerSimon Tatham <simon.tatham@arm.com>2019-11-15 09:53:43 +0000
commit902e84556a51c70d95088aaa059ab9c494ab3516 (patch)
treee0ac82fb4fd42fe5985a47536a7c088d95c63152 /clang/utils/TableGen
parent87054ec07bd57719b9f66bf0548d7ac8019799f5 (diff)
downloadbcm5719-llvm-902e84556a51c70d95088aaa059ab9c494ab3516.tar.gz
bcm5719-llvm-902e84556a51c70d95088aaa059ab9c494ab3516.zip
[ARM,MVE] Add intrinsics for 'administrative' vector operations.
This batch of intrinsics includes lots of things that move vector data around or change its type without really affecting its value very much. It includes the `vreinterpretq` family (cast one vector type to another); `vuninitializedq` (create a vector of a given type with don't-care contents); and `vcreateq` (make a 128-bit vector out of two `uint64_t` halves). These are all implemented using completely standard IR that's already tested in existing LLVM unit tests, so I've just written a clang test to check the IR is correct, and left it at that. I've also added some richer infrastructure to the MveEmitter Tablegen backend, to make it specify the exact integer type of integer arguments passed to IR construction functions, and wrap those arguments in a `static_cast` in the autogenerated C++. That was necessary to prevent an overloading ambiguity when passing the integer literal `0` to `IRBuilder::CreateInsertElement`, because otherwise, it could mean either a null pointer `llvm::Value *` or a zero `uint64_t`. Reviewers: ostannard, MarkMurrayARM, dmgreen Subscribers: kristof.beyls, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D70133
Diffstat (limited to 'clang/utils/TableGen')
-rw-r--r--clang/utils/TableGen/MveEmitter.cpp46
1 files changed, 35 insertions, 11 deletions
diff --git a/clang/utils/TableGen/MveEmitter.cpp b/clang/utils/TableGen/MveEmitter.cpp
index 2941cb6ec08..4258dd0a1f4 100644
--- a/clang/utils/TableGen/MveEmitter.cpp
+++ b/clang/utils/TableGen/MveEmitter.cpp
@@ -632,10 +632,10 @@ public:
StringRef CallPrefix;
std::vector<Ptr> Args;
std::set<unsigned> AddressArgs;
- std::set<unsigned> IntConstantArgs;
+ std::map<unsigned, std::string> IntConstantArgs;
IRBuilderResult(StringRef CallPrefix, std::vector<Ptr> Args,
std::set<unsigned> AddressArgs,
- std::set<unsigned> IntConstantArgs)
+ std::map<unsigned, std::string> IntConstantArgs)
: CallPrefix(CallPrefix), Args(Args), AddressArgs(AddressArgs),
IntConstantArgs(IntConstantArgs) {}
void genCode(raw_ostream &OS,
@@ -644,11 +644,13 @@ public:
const char *Sep = "";
for (unsigned i = 0, e = Args.size(); i < e; ++i) {
Ptr Arg = Args[i];
- if (IntConstantArgs.find(i) != IntConstantArgs.end()) {
+ auto it = IntConstantArgs.find(i);
+ if (it != IntConstantArgs.end()) {
assert(Arg->hasIntegerConstantValue());
- OS << Sep
+ OS << Sep << "static_cast<" << it->second << ">("
<< ParamAlloc.allocParam("unsigned",
- utostr(Arg->integerConstantValue()));
+ utostr(Arg->integerConstantValue()))
+ << ")";
} else {
OS << Sep << Arg->varname();
}
@@ -763,6 +765,14 @@ class ACLEIntrinsic {
// shares with at least one other intrinsic.
std::string ShortName, FullName;
+ // A very small number of intrinsics _only_ have a polymorphic
+ // variant (vuninitializedq taking an unevaluated argument).
+ bool PolymorphicOnly;
+
+ // Another rarely-used flag indicating that the builtin doesn't
+ // evaluate its argument(s) at all.
+ bool NonEvaluating;
+
const Type *ReturnType;
std::vector<const Type *> ArgTypes;
std::map<unsigned, ImmediateArg> ImmediateArgs;
@@ -796,6 +806,8 @@ public:
return false;
}
bool polymorphic() const { return ShortName != FullName; }
+ bool polymorphicOnly() const { return PolymorphicOnly; }
+ bool nonEvaluating() const { return NonEvaluating; }
// External entry point for code generation, called from MveEmitter.
void genCode(raw_ostream &OS, CodeGenParamAllocator &ParamAlloc,
@@ -1126,11 +1138,15 @@ Result::Ptr MveEmitter::getCodeForDag(DagInit *D, const Result::Scope &Scope,
Args.push_back(getCodeForDagArg(D, i, Scope, Param));
if (Op->isSubClassOf("IRBuilderBase")) {
std::set<unsigned> AddressArgs;
- for (unsigned i : Op->getValueAsListOfInts("address_params"))
- AddressArgs.insert(i);
- std::set<unsigned> IntConstantArgs;
- for (unsigned i : Op->getValueAsListOfInts("int_constant_params"))
- IntConstantArgs.insert(i);
+ std::map<unsigned, std::string> IntConstantArgs;
+ for (Record *sp : Op->getValueAsListOfDefs("special_params")) {
+ unsigned Index = sp->getValueAsInt("index");
+ if (sp->isSubClassOf("IRBuilderAddrParam")) {
+ AddressArgs.insert(Index);
+ } else if (sp->isSubClassOf("IRBuilderIntParam")) {
+ IntConstantArgs[Index] = sp->getValueAsString("type");
+ }
+ }
return std::make_shared<IRBuilderResult>(
Op->getValueAsString("prefix"), Args, AddressArgs, IntConstantArgs);
} else if (Op->isSubClassOf("IRIntBase")) {
@@ -1235,6 +1251,9 @@ ACLEIntrinsic::ACLEIntrinsic(MveEmitter &ME, Record *R, const Type *Param)
}
ShortName = join(std::begin(NameParts), std::end(NameParts), "_");
+ PolymorphicOnly = R->getValueAsBit("polymorphicOnly");
+ NonEvaluating = R->getValueAsBit("nonEvaluating");
+
// Process the intrinsic's argument list.
DagInit *ArgsDag = R->getValueAsDag("args");
Result::Scope Scope;
@@ -1404,6 +1423,8 @@ void MveEmitter::EmitHeader(raw_ostream &OS) {
for (bool Polymorphic : {false, true}) {
if (Polymorphic && !Int.polymorphic())
continue;
+ if (!Polymorphic && Int.polymorphicOnly())
+ continue;
// We also generate each intrinsic under a name like __arm_vfooq
// (which is in C language implementation namespace, so it's
@@ -1557,7 +1578,10 @@ void MveEmitter::EmitBuiltinDef(raw_ostream &OS) {
if (Int.polymorphic()) {
StringRef Name = Int.shortName();
if (ShortNamesSeen.find(Name) == ShortNamesSeen.end()) {
- OS << "BUILTIN(__builtin_arm_mve_" << Name << ", \"vi.\", \"nt\")\n";
+ OS << "BUILTIN(__builtin_arm_mve_" << Name << ", \"vi.\", \"nt";
+ if (Int.nonEvaluating())
+ OS << "u"; // indicate that this builtin doesn't evaluate its args
+ OS << "\")\n";
ShortNamesSeen.insert(Name);
}
}
OpenPOWER on IntegriCloud