forked from OSchip/llvm-project
[ARM] Creating 'call_mangled' for Neon intrinsics definitions
Summary: As multiple versions of the 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 differentiated 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. Reviewers: jmolloy, t.p.northover, rsmith, olista01, dnsampaio Reviewed By: dnsampaio Subscribers: dnsampaio, kristof.beyls, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D74618
This commit is contained in:
parent
dade859b58
commit
d42711625a
|
@ -60,6 +60,15 @@ def op;
|
|||
// 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.
|
||||
// example: (call_mangled "vfma_lane", $p0, $p1) -> "vfma_lane(__p0, __p1)"
|
||||
// (assuming non-LaneQ caller)
|
||||
// (call_mangled "vfma_lane", $p0, $p1) -> "vfma_laneq(__p0, __p1)"
|
||||
// (assuming LaneQ caller)
|
||||
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".
|
||||
|
|
|
@ -27,8 +27,9 @@
|
|||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/None.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/Optional.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
|
@ -518,7 +519,8 @@ private:
|
|||
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);
|
||||
|
@ -546,7 +548,8 @@ class NeonEmitter {
|
|||
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++; }
|
||||
|
@ -1383,8 +1386,8 @@ std::pair<Type, std::string> Intrinsic::DagEmitter::emitDag(DagInit *DI) {
|
|||
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")
|
||||
|
@ -1411,7 +1414,8 @@ std::pair<Type, std::string> Intrinsic::DagEmitter::emitDagOp(DagInit *DI) {
|
|||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
|
@ -1427,7 +1431,13 @@ std::pair<Type, std::string> Intrinsic::DagEmitter::emitDagCall(DagInit *DI) {
|
|||
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();
|
||||
|
@ -1832,7 +1842,8 @@ void Intrinsic::indexBody() {
|
|||
// 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());
|
||||
|
@ -1861,17 +1872,19 @@ Intrinsic &NeonEmitter::getIntrinsic(StringRef Name, ArrayRef<Type> Types) {
|
|||
}
|
||||
ErrMsg += ")\n";
|
||||
|
||||
if (MangledName && MangledName != I.getMangledName(true))
|
||||
continue;
|
||||
|
||||
if (I.getNumParams() != Types.size())
|
||||
continue;
|
||||
|
||||
bool Good = true;
|
||||
for (unsigned Arg = 0; Arg < Types.size(); ++Arg) {
|
||||
if (I.getParamType(Arg) != Types[Arg]) {
|
||||
Good = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (Good)
|
||||
unsigned ArgNum = 0;
|
||||
bool MatchingArgumentTypes =
|
||||
std::all_of(Types.begin(), Types.end(), [&](const auto &Type) {
|
||||
return Type == I.getParamType(ArgNum++);
|
||||
});
|
||||
|
||||
if (MatchingArgumentTypes)
|
||||
GoodVec.push_back(&I);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue