1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 11:13:28 +01:00

[TLI] Add functions determining if int parameters/returns should be zeroext/signext.

On some architectures (s390x, ppc64, sparc64, mips), C-level int is passed
as i32 signext instead of plain i32.  Likewise, unsigned int may be passed
as i32, i32 signext, or i32 zeroext depending on the platform.  Add this
information to TargetLibraryInfo, to be used whenever some LLVM pass
inserts a compiler-rt call to a function involving int parameters
or returns.

Differential Revision: http://reviews.llvm.org/D21739

llvm-svn: 287533
This commit is contained in:
Marcin Koscielnicki 2016-11-21 11:57:11 +00:00
parent 5b15b8b9d0
commit 3aa3dc33a3
2 changed files with 73 additions and 2 deletions

View File

@ -51,6 +51,7 @@ class TargetLibraryInfoImpl {
unsigned char AvailableArray[(LibFunc::NumLibFuncs+3)/4];
llvm::DenseMap<unsigned, std::string> CustomNames;
static StringRef const StandardNames[LibFunc::NumLibFuncs];
bool ShouldExtI32Param, ShouldExtI32Return, ShouldSignExtI32Param;
enum AvailabilityState {
StandardName = 3, // (memset to all ones)
@ -172,6 +173,26 @@ public:
///
/// Set VF to the vectorization factor.
StringRef getScalarizedFunction(StringRef F, unsigned &VF) const;
/// Set to true iff i32 parameters to library functions should have signext
/// or zeroext attributes if they correspond to C-level int or unsigned int,
/// respectively.
void setShouldExtI32Param(bool Val) {
ShouldExtI32Param = Val;
}
/// Set to true iff i32 results from library functions should have signext
/// or zeroext attributes if they correspond to C-level int or unsigned int,
/// respectively.
void setShouldExtI32Return(bool Val) {
ShouldExtI32Return = Val;
}
/// Set to true iff i32 parameters to library functions should have signext
/// attribute if they correspond to C-level int or unsigned int.
void setShouldSignExtI32Param(bool Val) {
ShouldSignExtI32Param = Val;
}
};
/// Provides information about what library functions are available for
@ -268,6 +289,26 @@ public:
return Impl->CustomNames.find(F)->second;
}
/// Returns extension attribute kind to be used for i32 parameters
/// correpsonding to C-level int or unsigned int. May be zeroext, signext,
/// or none.
Attribute::AttrKind getExtAttrForI32Param(bool Signed = true) const {
if (Impl->ShouldExtI32Param)
return Signed ? Attribute::SExt : Attribute::ZExt;
if (Impl->ShouldSignExtI32Param)
return Attribute::SExt;
return Attribute::None;
}
/// Returns extension attribute kind to be used for i32 return values
/// correpsonding to C-level int or unsigned int. May be zeroext, signext,
/// or none.
Attribute::AttrKind getExtAttrForI32Return(bool Signed = true) const {
if (Impl->ShouldExtI32Return)
return Signed ? Attribute::SExt : Attribute::ZExt;
return Attribute::None;
}
/// Handle invalidation from the pass manager.
///
/// If we try to invalidate this info, just return false. It cannot become

View File

@ -414,6 +414,25 @@ static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T,
}
TLI.addVectorizableFunctionsFromVecLib(ClVectorLibrary);
bool ShouldExtI32Param = false, ShouldExtI32Return = false,
ShouldSignExtI32Param = false;
// PowerPC64, Sparc64, SystemZ need signext/zeroext on i32 parameters and
// returns corresponding to C-level ints and unsigned ints.
if (T.getArch() == Triple::ppc64 || T.getArch() == Triple::ppc64le ||
T.getArch() == Triple::sparcv9 || T.getArch() == Triple::systemz) {
ShouldExtI32Param = true;
ShouldExtI32Return = true;
}
// Mips, on the other hand, needs signext on i32 parameters corresponding
// to both signed and unsigned ints.
if (T.getArch() == Triple::mips || T.getArch() == Triple::mipsel ||
T.getArch() == Triple::mips64 || T.getArch() == Triple::mips64el) {
ShouldSignExtI32Param = true;
}
TLI.setShouldExtI32Param(ShouldExtI32Param);
TLI.setShouldExtI32Return(ShouldExtI32Return);
TLI.setShouldSignExtI32Param(ShouldSignExtI32Param);
}
TargetLibraryInfoImpl::TargetLibraryInfoImpl() {
@ -431,14 +450,19 @@ TargetLibraryInfoImpl::TargetLibraryInfoImpl(const Triple &T) {
}
TargetLibraryInfoImpl::TargetLibraryInfoImpl(const TargetLibraryInfoImpl &TLI)
: CustomNames(TLI.CustomNames) {
: CustomNames(TLI.CustomNames), ShouldExtI32Param(TLI.ShouldExtI32Param),
ShouldExtI32Return(TLI.ShouldExtI32Return),
ShouldSignExtI32Param(TLI.ShouldSignExtI32Param) {
memcpy(AvailableArray, TLI.AvailableArray, sizeof(AvailableArray));
VectorDescs = TLI.VectorDescs;
ScalarDescs = TLI.ScalarDescs;
}
TargetLibraryInfoImpl::TargetLibraryInfoImpl(TargetLibraryInfoImpl &&TLI)
: CustomNames(std::move(TLI.CustomNames)) {
: CustomNames(std::move(TLI.CustomNames)),
ShouldExtI32Param(TLI.ShouldExtI32Param),
ShouldExtI32Return(TLI.ShouldExtI32Return),
ShouldSignExtI32Param(TLI.ShouldSignExtI32Param) {
std::move(std::begin(TLI.AvailableArray), std::end(TLI.AvailableArray),
AvailableArray);
VectorDescs = TLI.VectorDescs;
@ -447,12 +471,18 @@ TargetLibraryInfoImpl::TargetLibraryInfoImpl(TargetLibraryInfoImpl &&TLI)
TargetLibraryInfoImpl &TargetLibraryInfoImpl::operator=(const TargetLibraryInfoImpl &TLI) {
CustomNames = TLI.CustomNames;
ShouldExtI32Param = TLI.ShouldExtI32Param;
ShouldExtI32Return = TLI.ShouldExtI32Return;
ShouldSignExtI32Param = TLI.ShouldSignExtI32Param;
memcpy(AvailableArray, TLI.AvailableArray, sizeof(AvailableArray));
return *this;
}
TargetLibraryInfoImpl &TargetLibraryInfoImpl::operator=(TargetLibraryInfoImpl &&TLI) {
CustomNames = std::move(TLI.CustomNames);
ShouldExtI32Param = TLI.ShouldExtI32Param;
ShouldExtI32Return = TLI.ShouldExtI32Return;
ShouldSignExtI32Param = TLI.ShouldSignExtI32Param;
std::move(std::begin(TLI.AvailableArray), std::end(TLI.AvailableArray),
AvailableArray);
return *this;