pratlucas created this revision. Herald added subscribers: cfe-commits, kristof.beyls. Herald added a project: clang.
As multiple versions ofthe same Neon intrinsic can be created through the same TableGen definition with the same argument types, the existing 'call' operator is not always able to properly perform overload resolutions. As these different intrinsic versions are diferentiated later on by the NeonEmitter through name mangling, this patch introduces a new 'call_mangled' operator to the TableGen definitions, which allows a call for an otherwise ambiguous intrinsic by matching its mangled name with the mangled variation of the caller. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D74618 Files: clang/include/clang/Basic/arm_neon_incl.td clang/utils/TableGen/NeonEmitter.cpp
Index: clang/utils/TableGen/NeonEmitter.cpp =================================================================== --- clang/utils/TableGen/NeonEmitter.cpp +++ clang/utils/TableGen/NeonEmitter.cpp @@ -27,6 +27,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/None.h" +#include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringExtras.h" @@ -523,7 +524,7 @@ std::pair<Type, std::string> emitDagDupTyped(DagInit *DI); std::pair<Type, std::string> emitDagShuffle(DagInit *DI); std::pair<Type, std::string> emitDagCast(DagInit *DI, bool IsBitCast); - std::pair<Type, std::string> emitDagCall(DagInit *DI); + std::pair<Type, std::string> emitDagCall(DagInit *DI, bool MatchMangledName); std::pair<Type, std::string> emitDagNameReplace(DagInit *DI); std::pair<Type, std::string> emitDagLiteral(DagInit *DI); std::pair<Type, std::string> emitDagOp(DagInit *DI); @@ -551,7 +552,8 @@ public: /// Called by Intrinsic - this attempts to get an intrinsic that takes /// the given types as arguments. - Intrinsic &getIntrinsic(StringRef Name, ArrayRef<Type> Types); + Intrinsic &getIntrinsic(StringRef Name, ArrayRef<Type> Types, + Optional<std::string> MangledName); /// Called by Intrinsic - returns a globally-unique number. unsigned getUniqueNumber() { return UniqueNumber++; } @@ -1388,8 +1390,8 @@ return emitDagSaveTemp(DI); if (Op == "op") return emitDagOp(DI); - if (Op == "call") - return emitDagCall(DI); + if (Op == "call" || Op == "call_mangled") + return emitDagCall(DI, Op == "call_mangled"); if (Op == "name_replace") return emitDagNameReplace(DI); if (Op == "literal") @@ -1416,7 +1418,8 @@ } } -std::pair<Type, std::string> Intrinsic::DagEmitter::emitDagCall(DagInit *DI) { +std::pair<Type, std::string> Intrinsic::DagEmitter::emitDagCall(DagInit *DI, + bool MatchMangledName) { std::vector<Type> Types; std::vector<std::string> Values; for (unsigned I = 0; I < DI->getNumArgs() - 1; ++I) { @@ -1432,7 +1435,12 @@ N = SI->getAsUnquotedString(); else N = emitDagArg(DI->getArg(0), "").second; - Intrinsic &Callee = Intr.Emitter.getIntrinsic(N, Types); + Optional<std::string> MangledName; + if (MatchMangledName) { + if (Intr.getRecord()->getValueAsBit("isLaneQ")) N += "q"; + MangledName = Intr.mangleName(N, ClassS); + } + Intrinsic &Callee = Intr.Emitter.getIntrinsic(N, Types, MangledName); // Make sure the callee is known as an early def. Callee.setNeededEarly(); @@ -1839,7 +1847,8 @@ // NeonEmitter implementation //===----------------------------------------------------------------------===// -Intrinsic &NeonEmitter::getIntrinsic(StringRef Name, ArrayRef<Type> Types) { +Intrinsic &NeonEmitter::getIntrinsic(StringRef Name, ArrayRef<Type> Types, + Optional<std::string> MangledName) { // First, look up the name in the intrinsic map. assert_with_loc(IntrinsicMap.find(Name.str()) != IntrinsicMap.end(), ("Intrinsic '" + Name + "' not found!").str()); @@ -1878,6 +1887,9 @@ break; } } + if (MangledName) + Good &= I.getMangledName(true) == MangledName; + if (Good) GoodVec.push_back(&I); } Index: clang/include/clang/Basic/arm_neon_incl.td =================================================================== --- clang/include/clang/Basic/arm_neon_incl.td +++ clang/include/clang/Basic/arm_neon_incl.td @@ -60,6 +60,11 @@ // example: (call "vget_high", $p0) -> "vgetq_high_s16(__p0)" // (assuming $p0 has type int16x8_t). def call; +// call_mangled - Invoke another intrinsic matching the mangled name variation +// of the caller's base type. If there is no intrinsic defined +// that has the variation and takes the given types, an error +// is generated at tblgen time. +def call_mangled; // cast - Perform a cast to a different type. This gets emitted as a static // C-style cast. For a pure reinterpret cast (T x = *(T*)&y), use // "bitcast".
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits