diff options
author | Simon Tatham <simon.tatham@arm.com> | 2019-11-13 15:23:38 +0000 |
---|---|---|
committer | Simon Tatham <simon.tatham@arm.com> | 2019-11-15 09:53:43 +0000 |
commit | 902e84556a51c70d95088aaa059ab9c494ab3516 (patch) | |
tree | e0ac82fb4fd42fe5985a47536a7c088d95c63152 /clang/utils/TableGen/MveEmitter.cpp | |
parent | 87054ec07bd57719b9f66bf0548d7ac8019799f5 (diff) | |
download | bcm5719-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/MveEmitter.cpp')
-rw-r--r-- | clang/utils/TableGen/MveEmitter.cpp | 46 |
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); } } |