[AMDGPU] Transform __read_pipe_* and __write_pipe_*
When packet size equals packet align and is power of 2, transform
__read_pipe* and __write_pipe* to specialized library function.
Differential Revision: https://reviews.llvm.org/D36831
llvm-svn: 312598
diff --git a/llvm/lib/Target/AMDGPU/AMDGPULibFunc.h b/llvm/lib/Target/AMDGPU/AMDGPULibFunc.h
index bb8724a..8f4297b 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPULibFunc.h
+++ b/llvm/lib/Target/AMDGPU/AMDGPULibFunc.h
@@ -18,7 +18,7 @@
class Function;
class Module;
-class AMDGPULibFunc {
+class AMDGPULibFuncBase {
public:
enum EFuncId {
EI_NONE,
@@ -26,6 +26,14 @@
// IMPORTANT: enums below should go in ascending by 1 value order
// because they are used as indexes in the mangling rules table.
// don't use explicit value assignment.
+ //
+ // There are two types of library functions: those with mangled
+ // name and those with unmangled name. The enums for the library
+ // functions with mangled name are defined before enums for the
+ // library functions with unmangled name. The enum for the last
+ // library function with mangled name is EI_LAST_MANGLED.
+ //
+ // Library functions with mangled name.
EI_ABS,
EI_ABS_DIFF,
EI_ACOS,
@@ -144,7 +152,6 @@
EI_POWR,
EI_PREFETCH,
EI_RADIANS,
- EI_READ_PIPE,
EI_RECIP,
EI_REMAINDER,
EI_REMQUO,
@@ -212,7 +219,6 @@
EI_WRITE_IMAGEF,
EI_WRITE_IMAGEI,
EI_WRITE_IMAGEUI,
- EI_WRITE_PIPE,
EI_NCOS,
EI_NEXP2,
EI_NFMA,
@@ -225,6 +231,14 @@
EI_FLDEXP,
EI_CLASS,
EI_RCBRT,
+ EI_LAST_MANGLED =
+ EI_RCBRT, /* The last library function with mangled name */
+
+ // Library functions with unmangled name.
+ EI_READ_PIPE_2,
+ EI_READ_PIPE_4,
+ EI_WRITE_PIPE_2,
+ EI_WRITE_PIPE_4,
EX_INTRINSICS_COUNT
};
@@ -298,51 +312,144 @@
template <typename Stream>
void mangleItanium(Stream& os);
};
-
-public:
- static bool parse(StringRef mangledName, AMDGPULibFunc &iInfo);
-
- AMDGPULibFunc();
- AMDGPULibFunc(EFuncId id, const AMDGPULibFunc& copyFrom);
-
- ENamePrefix getPrefix() const { return FKind; }
- EFuncId getId() const { return FuncId; }
-
- std::string getName() const;
- unsigned getNumArgs() const;
-
- FunctionType* getFunctionType(Module& M) const;
-
- std::string mangle() const;
-
- void setPrefix(ENamePrefix pfx) { FKind = pfx; }
- void setId(EFuncId id) { FuncId = id; }
-
- static Function* getFunction(llvm::Module *M, const AMDGPULibFunc& fInfo);
-
- static Function* getOrInsertFunction(llvm::Module *M,
- const AMDGPULibFunc& fInfo);
-
- static StringRef getUnmangledName(const StringRef& mangledName);
-
- Param Leads[2];
-
-private:
- EFuncId FuncId;
- ENamePrefix FKind;
- std::string Name;
-
- void reset();
-
- std::string mangleNameItanium() const;
- bool parseItanuimName(StringRef& mangledName);
-
- std::string mangleName(const StringRef& name) const;
- bool parseName(const StringRef& mangledName);
-
- template <typename Stream>
- void writeName(Stream& OS) const;
+ static bool isMangled(EFuncId Id) {
+ return static_cast<unsigned>(Id) <= static_cast<unsigned>(EI_LAST_MANGLED);
+ }
};
+class AMDGPULibFuncImpl : public AMDGPULibFuncBase {
+public:
+ AMDGPULibFuncImpl() {}
+ virtual ~AMDGPULibFuncImpl() {}
+
+ /// Get unmangled name for mangled library function and name for unmangled
+ /// library function.
+ virtual std::string getName() const = 0;
+ virtual unsigned getNumArgs() const = 0;
+ EFuncId getId() const { return FuncId; }
+ ENamePrefix getPrefix() const { return FKind; }
+
+ bool isMangled() const { return AMDGPULibFuncBase::isMangled(FuncId); }
+
+ void setId(EFuncId id) { FuncId = id; }
+ virtual bool parseFuncName(StringRef &mangledName) = 0;
+
+ /// \return The mangled function name for mangled library functions
+ /// and unmangled function name for unmangled library functions.
+ virtual std::string mangle() const = 0;
+
+ void setName(StringRef N) { Name = N; }
+ void setPrefix(ENamePrefix pfx) { FKind = pfx; }
+
+ virtual FunctionType *getFunctionType(Module &M) const = 0;
+
+protected:
+ EFuncId FuncId;
+ std::string Name;
+ ENamePrefix FKind;
+};
+
+/// Wrapper class for AMDGPULIbFuncImpl
+class AMDGPULibFunc : public AMDGPULibFuncBase {
+public:
+ explicit AMDGPULibFunc() : Impl(std::unique_ptr<AMDGPULibFuncImpl>()) {}
+ AMDGPULibFunc(const AMDGPULibFunc &F);
+ /// Clone a mangled library func with the Id \p Id and argument info from \p
+ /// CopyFrom.
+ explicit AMDGPULibFunc(EFuncId Id, const AMDGPULibFunc &CopyFrom);
+ /// Construct an unmangled library function on the fly.
+ explicit AMDGPULibFunc(StringRef FName, FunctionType *FT);
+
+ AMDGPULibFunc &operator=(const AMDGPULibFunc &F);
+
+ /// Get unmangled name for mangled library function and name for unmangled
+ /// library function.
+ std::string getName() const { return Impl->getName(); }
+ unsigned getNumArgs() const { return Impl->getNumArgs(); }
+ EFuncId getId() const { return Impl->getId(); }
+ ENamePrefix getPrefix() const { return Impl->getPrefix(); }
+ /// Get leading parameters for mangled lib functions.
+ Param *getLeads();
+ const Param *getLeads() const;
+
+ bool isMangled() const { return Impl->isMangled(); }
+ void setId(EFuncId Id) { Impl->setId(Id); }
+ bool parseFuncName(StringRef &MangledName) {
+ return Impl->parseFuncName(MangledName);
+ }
+
+ /// \return The mangled function name for mangled library functions
+ /// and unmangled function name for unmangled library functions.
+ std::string mangle() const { return Impl->mangle(); }
+
+ void setName(StringRef N) { Impl->setName(N); }
+ void setPrefix(ENamePrefix PFX) { Impl->setPrefix(PFX); }
+
+ FunctionType *getFunctionType(Module &M) const {
+ return Impl->getFunctionType(M);
+ }
+ static Function *getFunction(llvm::Module *M, const AMDGPULibFunc &fInfo);
+
+ static Function *getOrInsertFunction(llvm::Module *M,
+ const AMDGPULibFunc &fInfo);
+ static bool parse(StringRef MangledName, AMDGPULibFunc &Ptr);
+
+private:
+ /// Initialize as a mangled library function.
+ void initMangled();
+ std::unique_ptr<AMDGPULibFuncImpl> Impl;
+};
+
+class AMDGPUMangledLibFunc : public AMDGPULibFuncImpl {
+public:
+ Param Leads[2];
+
+ explicit AMDGPUMangledLibFunc();
+ explicit AMDGPUMangledLibFunc(EFuncId id,
+ const AMDGPUMangledLibFunc ©From);
+
+ std::string getName() const override;
+ unsigned getNumArgs() const override;
+ FunctionType *getFunctionType(Module &M) const override;
+ static StringRef getUnmangledName(StringRef MangledName);
+
+ bool parseFuncName(StringRef &mangledName) override;
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static bool classof(const AMDGPULibFuncImpl *F) { return F->isMangled(); }
+
+ std::string mangle() const override;
+
+private:
+ std::string mangleNameItanium() const;
+
+ std::string mangleName(StringRef Name) const;
+ bool parseUnmangledName(StringRef MangledName);
+
+ template <typename Stream> void writeName(Stream &OS) const;
+};
+
+class AMDGPUUnmangledLibFunc : public AMDGPULibFuncImpl {
+ FunctionType *FuncTy;
+
+public:
+ explicit AMDGPUUnmangledLibFunc();
+ explicit AMDGPUUnmangledLibFunc(StringRef FName, FunctionType *FT) {
+ Name = FName;
+ FuncTy = FT;
+ }
+ std::string getName() const override { return Name; }
+ unsigned getNumArgs() const override;
+ FunctionType *getFunctionType(Module &M) const override { return FuncTy; }
+
+ bool parseFuncName(StringRef &Name) override;
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static bool classof(const AMDGPULibFuncImpl *F) { return !F->isMangled(); }
+
+ std::string mangle() const override { return Name; }
+
+ void setFunctionType(FunctionType *FT) { FuncTy = FT; }
+};
}
#endif // _AMDGPU_LIBFUNC_H_