summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/AMDGPU/AMDGPULibFunc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/AMDGPU/AMDGPULibFunc.cpp')
-rw-r--r--llvm/lib/Target/AMDGPU/AMDGPULibFunc.cpp192
1 files changed, 157 insertions, 35 deletions
diff --git a/llvm/lib/Target/AMDGPU/AMDGPULibFunc.cpp b/llvm/lib/Target/AMDGPU/AMDGPULibFunc.cpp
index 96addc01eda..919e8c1e13c 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPULibFunc.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPULibFunc.cpp
@@ -65,6 +65,51 @@ struct ManglingRule {
unsigned getNumArgs() const;
};
+// Information about library functions with unmangled names.
+class UnmangledFuncInfo {
+ StringRef const Name;
+ unsigned NumArgs;
+
+ // Table for all lib functions with unmangled names.
+ static const UnmangledFuncInfo Table[];
+
+ // Number of entries in Table.
+ static const unsigned TableSize;
+
+ // Map function name to index.
+ class NameMap : public StringMap<unsigned> {
+ public:
+ NameMap() {
+ for (unsigned I = 0; I != TableSize; ++I)
+ (*this)[Table[I].Name] = I;
+ }
+ };
+ friend class NameMap;
+ static NameMap Map;
+
+public:
+ using ID = AMDGPULibFunc::EFuncId;
+ UnmangledFuncInfo() = default;
+ UnmangledFuncInfo(StringRef _Name, unsigned _NumArgs)
+ : Name(_Name), NumArgs(_NumArgs) {}
+ // Get index to Table by function name.
+ static bool lookup(StringRef Name, ID &Id);
+ static unsigned toIndex(ID Id) {
+ assert(static_cast<unsigned>(Id) >
+ static_cast<unsigned>(AMDGPULibFunc::EI_LAST_MANGLED) &&
+ "Invalid unmangled library function");
+ return static_cast<unsigned>(Id) - 1 -
+ static_cast<unsigned>(AMDGPULibFunc::EI_LAST_MANGLED);
+ }
+ static ID toFuncId(unsigned Index) {
+ assert(Index < TableSize && "Invalid unmangled library function");
+ return static_cast<ID>(
+ Index + 1 + static_cast<unsigned>(AMDGPULibFunc::EI_LAST_MANGLED));
+ }
+ static unsigned getNumArgs(ID Id) { return Table[toIndex(Id)].NumArgs; }
+ static StringRef getName(ID Id) { return Table[toIndex(Id)].Name; }
+};
+
unsigned ManglingRule::getNumArgs() const {
unsigned I=0;
while (I < (sizeof Param/sizeof Param[0]) && Param[I]) ++I;
@@ -215,7 +260,6 @@ static const ManglingRule manglingRules[] = {
{ "powr" , {1}, {E_ANY,E_COPY}},
{ "prefetch" , {1}, {E_CONSTPTR_ANY,EX_SIZET}},
{ "radians" , {1}, {E_ANY}},
-{ "read_pipe" , {4}, {E_COPY,EX_RESERVEDID,EX_UINT,E_ANY}},
{ "recip" , {1}, {E_ANY}},
{ "remainder" , {1}, {E_ANY,E_COPY}},
{ "remquo" , {1,3}, {E_ANY,E_COPY,E_ANY}},
@@ -283,7 +327,6 @@ static const ManglingRule manglingRules[] = {
{ "write_imagef" , {1}, {E_ANY,E_IMAGECOORDS,EX_FLOAT4}},
{ "write_imagei" , {1}, {E_ANY,E_IMAGECOORDS,EX_INTV4}},
{ "write_imageui" , {1}, {E_ANY,E_IMAGECOORDS,EX_UINTV4}},
-{ "write_pipe" , {4}, {E_COPY,EX_RESERVEDID,EX_UINT,E_ANY}},
{ "ncos" , {1}, {E_ANY} },
{ "nexp2" , {1}, {E_ANY} },
{ "nfma" , {1}, {E_ANY, E_COPY, E_COPY} },
@@ -298,6 +341,19 @@ static const ManglingRule manglingRules[] = {
{ "rcbrt" , {1}, {E_ANY} },
};
+// Library functions with unmangled name.
+const UnmangledFuncInfo UnmangledFuncInfo::Table[] = {
+ {"__read_pipe_2", 4},
+ {"__read_pipe_4", 6},
+ {"__write_pipe_2", 4},
+ {"__write_pipe_4", 6},
+};
+
+const unsigned UnmangledFuncInfo::TableSize =
+ sizeof(UnmangledFuncInfo::Table) / sizeof(UnmangledFuncInfo::Table[0]);
+
+UnmangledFuncInfo::NameMap UnmangledFuncInfo::Map;
+
static const struct ManglingRulesMap : public StringMap<int> {
ManglingRulesMap()
: StringMap<int>(sizeof(manglingRules)/sizeof(manglingRules[0])) {
@@ -461,18 +517,7 @@ static StringRef eatLengthPrefixedName(StringRef& mangledName) {
} // end anonymous namespace
-AMDGPULibFunc::AMDGPULibFunc() {
- reset();
-}
-
-AMDGPULibFunc::AMDGPULibFunc(EFuncId id, const AMDGPULibFunc& copyFrom)
- : FuncId(id) {
- FKind = copyFrom.FKind;
- Leads[0] = copyFrom.Leads[0];
- Leads[1] = copyFrom.Leads[1];
-}
-
-void AMDGPULibFunc::reset() {
+AMDGPUMangledLibFunc::AMDGPUMangledLibFunc() {
FuncId = EI_NONE;
FKind = NOPFX;
Leads[0].reset();
@@ -480,6 +525,19 @@ void AMDGPULibFunc::reset() {
Name.clear();
}
+AMDGPUUnmangledLibFunc::AMDGPUUnmangledLibFunc() {
+ FuncId = EI_NONE;
+ FuncTy = nullptr;
+}
+
+AMDGPUMangledLibFunc::AMDGPUMangledLibFunc(
+ EFuncId id, const AMDGPUMangledLibFunc &copyFrom) {
+ FuncId = id;
+ FKind = copyFrom.FKind;
+ Leads[0] = copyFrom.Leads[0];
+ Leads[1] = copyFrom.Leads[1];
+}
+
///////////////////////////////////////////////////////////////////////////////
// Demangling
@@ -508,8 +566,8 @@ static AMDGPULibFunc::ENamePrefix parseNamePrefix(StringRef& mangledName) {
return Pfx;
}
-bool AMDGPULibFunc::parseName(const StringRef& fullName) {
- FuncId = static_cast<EFuncId>(manglingRulesMap.lookup(fullName));
+bool AMDGPUMangledLibFunc::parseUnmangledName(StringRef FullName) {
+ FuncId = static_cast<EFuncId>(manglingRulesMap.lookup(FullName));
return FuncId != EI_NONE;
}
@@ -601,10 +659,11 @@ bool ItaniumParamParser::parseItaniumParam(StringRef& param,
return true;
}
-bool AMDGPULibFunc::parseItanuimName(StringRef& mangledName) {
+bool AMDGPUMangledLibFunc::parseFuncName(StringRef &mangledName) {
StringRef Name = eatLengthPrefixedName(mangledName);
FKind = parseNamePrefix(Name);
- if (!parseName(Name)) return false;
+ if (!parseUnmangledName(Name))
+ return false;
const ManglingRule& Rule = manglingRules[FuncId];
ItaniumParamParser Parser;
@@ -619,30 +678,42 @@ bool AMDGPULibFunc::parseItanuimName(StringRef& mangledName) {
return true;
}
-bool AMDGPULibFunc::parse(StringRef mangledName, AMDGPULibFunc& iInfo) {
- iInfo.reset();
- if (mangledName.empty())
+bool AMDGPUUnmangledLibFunc::parseFuncName(StringRef &Name) {
+ if (!UnmangledFuncInfo::lookup(Name, FuncId))
return false;
+ setName(Name);
+ return true;
+}
- if (eatTerm(mangledName, "_Z")) {
- return iInfo.parseItanuimName(mangledName);
+bool AMDGPULibFunc::parse(StringRef FuncName, AMDGPULibFunc &F) {
+ if (FuncName.empty()) {
+ F.Impl = std::unique_ptr<AMDGPULibFuncImpl>();
+ return false;
}
+
+ if (eatTerm(FuncName, "_Z"))
+ F.Impl = make_unique<AMDGPUMangledLibFunc>();
+ else
+ F.Impl = make_unique<AMDGPUUnmangledLibFunc>();
+ if (F.Impl->parseFuncName(FuncName))
+ return true;
+
+ F.Impl = std::unique_ptr<AMDGPULibFuncImpl>();
return false;
}
-StringRef AMDGPULibFunc::getUnmangledName(const StringRef& mangledName) {
+StringRef AMDGPUMangledLibFunc::getUnmangledName(StringRef mangledName) {
StringRef S = mangledName;
if (eatTerm(S, "_Z"))
return eatLengthPrefixedName(S);
return StringRef();
}
-
///////////////////////////////////////////////////////////////////////////////
// Mangling
template <typename Stream>
-void AMDGPULibFunc::writeName(Stream& OS) const {
+void AMDGPUMangledLibFunc::writeName(Stream &OS) const {
const char *Pfx = "";
switch (FKind) {
case NATIVE: Pfx = "native_"; break;
@@ -658,9 +729,7 @@ void AMDGPULibFunc::writeName(Stream& OS) const {
}
}
-std::string AMDGPULibFunc::mangle() const {
- return mangleNameItanium();
-}
+std::string AMDGPUMangledLibFunc::mangle() const { return mangleNameItanium(); }
///////////////////////////////////////////////////////////////////////////////
// Itanium Mangling
@@ -788,7 +857,7 @@ public:
};
} // namespace
-std::string AMDGPULibFunc::mangleNameItanium() const {
+std::string AMDGPUMangledLibFunc::mangleNameItanium() const {
SmallString<128> Buf;
raw_svector_ostream S(Buf);
SmallString<128> NameBuf;
@@ -850,7 +919,7 @@ static Type* getIntrinsicParamType(
return T;
}
-FunctionType* AMDGPULibFunc::getFunctionType(Module& M) const {
+FunctionType *AMDGPUMangledLibFunc::getFunctionType(Module &M) const {
LLVMContext& C = M.getContext();
std::vector<Type*> Args;
ParamIterator I(Leads, manglingRules[FuncId]);
@@ -863,18 +932,22 @@ FunctionType* AMDGPULibFunc::getFunctionType(Module& M) const {
Args, false);
}
-unsigned AMDGPULibFunc::getNumArgs() const {
+unsigned AMDGPUMangledLibFunc::getNumArgs() const {
return manglingRules[FuncId].getNumArgs();
}
-std::string AMDGPULibFunc::getName() const {
+unsigned AMDGPUUnmangledLibFunc::getNumArgs() const {
+ return UnmangledFuncInfo::getNumArgs(FuncId);
+}
+
+std::string AMDGPUMangledLibFunc::getName() const {
SmallString<128> Buf;
raw_svector_ostream OS(Buf);
writeName(OS);
return OS.str();
}
-Function *AMDGPULibFunc::getFunction(Module *M, const AMDGPULibFunc& fInfo) {
+Function *AMDGPULibFunc::getFunction(Module *M, const AMDGPULibFunc &fInfo) {
std::string FuncName = fInfo.mangle();
Function *F = dyn_cast_or_null<Function>(
M->getValueSymbolTable().lookup(FuncName));
@@ -889,7 +962,7 @@ Function *AMDGPULibFunc::getFunction(Module *M, const AMDGPULibFunc& fInfo) {
}
Function *AMDGPULibFunc::getOrInsertFunction(Module *M,
- const AMDGPULibFunc& fInfo) {
+ const AMDGPULibFunc &fInfo) {
std::string const FuncName = fInfo.mangle();
Function *F = dyn_cast_or_null<Function>(
M->getValueSymbolTable().lookup(FuncName));
@@ -929,3 +1002,52 @@ Function *AMDGPULibFunc::getOrInsertFunction(Module *M,
return cast<Function>(C);
}
+
+bool UnmangledFuncInfo::lookup(StringRef Name, ID &Id) {
+ auto Loc = Map.find(Name);
+ if (Loc != Map.end()) {
+ Id = toFuncId(Loc->second);
+ return true;
+ }
+ Id = AMDGPULibFunc::EI_NONE;
+ return false;
+}
+
+AMDGPULibFunc::AMDGPULibFunc(const AMDGPULibFunc &F) {
+ if (auto *MF = dyn_cast<AMDGPUMangledLibFunc>(F.Impl.get()))
+ Impl.reset(new AMDGPUMangledLibFunc(*MF));
+ else if (auto *UMF = dyn_cast<AMDGPUUnmangledLibFunc>(F.Impl.get()))
+ Impl.reset(new AMDGPUUnmangledLibFunc(*UMF));
+ else
+ Impl = std::unique_ptr<AMDGPULibFuncImpl>();
+}
+
+AMDGPULibFunc &AMDGPULibFunc::operator=(const AMDGPULibFunc &F) {
+ if (this == &F)
+ return *this;
+ new (this) AMDGPULibFunc(F);
+ return *this;
+}
+
+AMDGPULibFunc::AMDGPULibFunc(EFuncId Id, const AMDGPULibFunc &CopyFrom) {
+ assert(AMDGPULibFuncBase::isMangled(Id) && CopyFrom.isMangled() &&
+ "not supported");
+ Impl.reset(new AMDGPUMangledLibFunc(
+ Id, *cast<AMDGPUMangledLibFunc>(CopyFrom.Impl.get())));
+}
+
+AMDGPULibFunc::AMDGPULibFunc(StringRef Name, FunctionType *FT) {
+ Impl.reset(new AMDGPUUnmangledLibFunc(Name, FT));
+}
+
+void AMDGPULibFunc::initMangled() { Impl.reset(new AMDGPUMangledLibFunc()); }
+
+AMDGPULibFunc::Param *AMDGPULibFunc::getLeads() {
+ if (!Impl)
+ initMangled();
+ return cast<AMDGPUMangledLibFunc>(Impl.get())->Leads;
+}
+
+const AMDGPULibFunc::Param *AMDGPULibFunc::getLeads() const {
+ return cast<const AMDGPUMangledLibFunc>(Impl.get())->Leads;
+}
OpenPOWER on IntegriCloud