[cfe-dev] Optimized subarch library support
Jonathan Roelofs
jonathan at codesourcery.com
Fri Dec 6 17:35:43 PST 2013
I'd like to add support to Clang for picking subarch-optimized versions
of libraries. One place I see this being particularly useful is on x86
where there are a handful of different vector units available but
libraries need to be built to the lowest common denominator and
therefore can't take advantage of the increased performance of
architectures supporting them (runtime cpu dispatch aside). Embedded arm
targets could benefit from this as well.
GCC's multilibs are one possible solution to this problem, and they seem
relatively orthogonal to the multiarch movement, so their structure is
probably a reasonable place to start.
For example, on x86 it could look something like this:
/lib/i386-linux-gnu/
/lib/i386-linux-gnu/sse2/
/lib/i386-linux-gnu/sse4.2/
/lib/i386-linux-gnu/avx/
and then at compile time, depending on which flags (target, march, mcpu,
etc) were provided, Clang would pick the appropriate directory suffix
and link against what's inside it. This would give the user the best
thing that is compatible with their flags, rather than always sticking
with the (s)lowest commmon denominator.
There are two parts to this as far as implementation goes: 1) library
discovery, and 2) picking the best one for a given set of flags.
In order for (1) to work, these directory names would either have to be
standardized, or have some sort of configuration file that says which
features each subdir supports. Given that there are so many combinations
of flags that could affect this library choice, I think it makes most
sense to go with config files. OTOH, this would require support from
distros to put in the right config file in order to get it to 'just
work' when Clang is installed, so that feels slightly less desirable.
I'm not sure the right way to go here.
Part (2) can be further split up into determining compatibility and
assigning rank, both of which seem like architecture family specific
things that could be determined from the feature sets mentioned above.
Implementation-wise, I'm thinking of something roughly like this:
class Multilib {
public:
Multilib(StringRef Suffix);
Multilib(StringRef Suffix, ArrayRef<std::string> FeatureSet);
bool SupportsFeature(StringRef Feature);
std::string GetSuffix() { return Suffix; }
private:
std::vector<std::string> FeatureSet;
std::string Suffix;
};
class MultilibManager {
public:
std::vector<Multilib> FindCompatibleMultilibs(StringRef Path,
llvm::Triple Triple, const ArgList &Args);
Multilib GetBestMatch(ArrayRef<Multilib> Libs, llvm::Triple Triple,
const ArgList &Args);
private:
void AddConfigFileLibs(StringRef ConfigFilePath, ArrayRef<Multilib>
Libs);
bool IsCompatible(const Multilib & Lib, llvm::Triple Triple, const
ArgList &Args);
bool IsSuperior(const Multilib & a, const Multilib & b, llvm::Triple
Triple, const ArgList &Args);
};
appropriately hooked into Driver/Toolchains.cpp
Comments & suggestions before I put together a more formal patch would
be much appreciated :)
--
Jon Roelofs
jonathan at codesourcery.com
CodeSourcery / Mentor Embedded
More information about the cfe-dev
mailing list