#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
-#include "llvm/Frontend/OpenMP/OMPIRBuilder.h"
#include "llvm/Support/Capacity.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
#include <cstdlib>
#include <map>
#include <memory>
-#include <numeric>
#include <optional>
#include <string>
#include <tuple>
}
unsigned ASTContext::getOpenMPDefaultSimdAlign(QualType T) const {
- const std::vector<std::string> &TargetFeatures =
- Target->getTargetOpts().Features;
- std::string TargetFeaturesString = std::accumulate(
- TargetFeatures.cbegin(), TargetFeatures.cend(), std::string(),
- [](const std::string &s1, const std::string &s2) {
- return s1.empty() ? s2 : s1 + "," + s2;
- });
- unsigned SimdAlign = llvm::OpenMPIRBuilder ::getSimdDefaultAlignment(
- getTargetInfo().getTriple().str(), Target->getTargetOpts().CPU,
- TargetFeaturesString);
+ unsigned SimdAlign = getTargetInfo().getSimdDefaultAlign();
return SimdAlign;
}
NewBr->setDebugLoc(DL);
}
-/// Create the TargetMachine object to query the backend for optimization
-/// preferences.
-///
-/// Ideally, this would be passed from the front-end to the OpenMPBuilder, but
-/// e.g. Clang does not pass it to its CodeGen layer and creates it only when
-/// needed for the LLVM pass pipline. We use some default options to avoid
-/// having to pass too many settings from the frontend that probably do not
-/// matter.
-///
-/// Currently, TargetMachine is only used sometimes by the unrollLoopPartial
-/// and getVectorTypeAlignment methods. If we are going to use TargetMachine
-/// for more purposes, especially those that are sensitive to TargetOptions,
-/// RelocModel and CodeModel, it might become be worth requiring front-ends to
-/// pass on their TargetMachine, or at least cache it between methods.
-/// Note that while fontends such as Clang have just a single main
-/// TargetMachine per translation unit, "target-cpu" and "target-features"
-/// that determine the TargetMachine are per-function and can be overrided
-/// using __attribute__((target("OPTIONS"))).
-static std::unique_ptr<TargetMachine>
-createTargetMachine(const std::string &Triple, StringRef CPU,
- StringRef Features, CodeGenOpt::Level OptLevel) {
- std::string Error;
- const llvm::Target *TheTarget = TargetRegistry::lookupTarget(Triple, Error);
- if (!TheTarget)
- return {};
-
- llvm::TargetOptions Options;
- return std::unique_ptr<TargetMachine>(TheTarget->createTargetMachine(
- Triple, CPU, Features, Options, /*RelocModel=*/std::nullopt,
- /*CodeModel=*/std::nullopt, OptLevel));
-}
-
-/// Create the TargetMachine object to query the backend for optimization
-/// preferences.
-static std::unique_ptr<TargetMachine>
-createTargetMachine(Function *F, CodeGenOpt::Level OptLevel) {
- Module *M = F->getParent();
-
- StringRef CPU = F->getFnAttribute("target-cpu").getValueAsString();
- StringRef Features = F->getFnAttribute("target-features").getValueAsString();
- const std::string &Triple = M->getTargetTriple();
- return createTargetMachine(Triple, CPU, Features, OptLevel);
-}
-
void llvm::spliceBB(IRBuilderBase::InsertPoint IP, BasicBlock *New,
bool CreateBranch) {
assert(New->getFirstInsertionPt() == New->begin() &&
Builder.CreateBr(NewBlocks.front());
}
-unsigned OpenMPIRBuilder::getSimdDefaultAlignment(const std::string &Triple,
- StringRef CPU,
- StringRef Features) {
- std::unique_ptr<TargetMachine> TgtInfo(
- createTargetMachine(Triple, CPU, Features, CodeGenOpt::Default));
- if (!TgtInfo) {
- return 0;
- }
-
- return TgtInfo->getSimdDefaultAlignment();
-}
-
void OpenMPIRBuilder::applySimd(CanonicalLoopInfo *CanonicalLoop,
MapVector<Value *, Value *> AlignedVars,
Value *IfCond, OrderKind Order,
addLoopMetadata(CanonicalLoop, LoopMDList);
}
+/// Create the TargetMachine object to query the backend for optimization
+/// preferences.
+///
+/// Ideally, this would be passed from the front-end to the OpenMPBuilder, but
+/// e.g. Clang does not pass it to its CodeGen layer and creates it only when
+/// needed for the LLVM pass pipline. We use some default options to avoid
+/// having to pass too many settings from the frontend that probably do not
+/// matter.
+///
+/// Currently, TargetMachine is only used sometimes by the unrollLoopPartial
+/// method. If we are going to use TargetMachine for more purposes, especially
+/// those that are sensitive to TargetOptions, RelocModel and CodeModel, it
+/// might become be worth requiring front-ends to pass on their TargetMachine,
+/// or at least cache it between methods. Note that while fontends such as Clang
+/// have just a single main TargetMachine per translation unit, "target-cpu" and
+/// "target-features" that determine the TargetMachine are per-function and can
+/// be overrided using __attribute__((target("OPTIONS"))).
+static std::unique_ptr<TargetMachine>
+createTargetMachine(Function *F, CodeGenOpt::Level OptLevel) {
+ Module *M = F->getParent();
+
+ StringRef CPU = F->getFnAttribute("target-cpu").getValueAsString();
+ StringRef Features = F->getFnAttribute("target-features").getValueAsString();
+ const std::string &Triple = M->getTargetTriple();
+
+ std::string Error;
+ const llvm::Target *TheTarget = TargetRegistry::lookupTarget(Triple, Error);
+ if (!TheTarget)
+ return {};
+
+ llvm::TargetOptions Options;
+ return std::unique_ptr<TargetMachine>(TheTarget->createTargetMachine(
+ Triple, CPU, Features, Options, /*RelocModel=*/std::nullopt,
+ /*CodeModel=*/std::nullopt, OptLevel));
+}
+
/// Heuristically determine the best-performant unroll factor for \p CLI. This
/// depends on the target processor. We are re-using the same heuristics as the
/// LoopUnrollPass.