#include "llvm/Transforms/Scalar/Scalarizer.h"
#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Analysis/VectorUtils.h"
#include "llvm/IR/Argument.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/InstVisitor.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Value.h"
#include "llvm/InitializePasses.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Transforms/Utils/Local.h"
#include <cassert>
#include <cstdint>
#include <iterator>
#include <map>
#include <utility>
usingnamespacellvm;
#define DEBUG_TYPE …
static cl::opt<bool> ClScalarizeVariableInsertExtract(
"scalarize-variable-insert-extract", cl::init(true), cl::Hidden,
cl::desc("Allow the scalarizer pass to scalarize "
"insertelement/extractelement with variable index"));
static cl::opt<bool> ClScalarizeLoadStore(
"scalarize-load-store", cl::init(false), cl::Hidden,
cl::desc("Allow the scalarizer pass to scalarize loads and store"));
static cl::opt<unsigned> ClScalarizeMinBits(
"scalarize-min-bits", cl::init(0), cl::Hidden,
cl::desc("Instruct the scalarizer pass to attempt to keep values of a "
"minimum number of bits"));
namespace {
BasicBlock::iterator skipPastPhiNodesAndDbg(BasicBlock::iterator Itr) { … }
ValueVector;
ScatterMap;
GatherList;
struct VectorSplit { … };
class Scatterer { … };
struct FCmpSplitter { … };
struct ICmpSplitter { … };
struct UnarySplitter { … };
struct BinarySplitter { … };
struct VectorLayout { … };
static Value *concatenate(IRBuilder<> &Builder, ArrayRef<Value *> Fragments,
const VectorSplit &VS, Twine Name) { … }
template <typename T>
T getWithDefaultOverride(const cl::opt<T> &ClOption,
const std::optional<T> &DefaultOverride) { … }
class ScalarizerVisitor : public InstVisitor<ScalarizerVisitor, bool> { … };
class ScalarizerLegacyPass : public FunctionPass { … };
}
ScalarizerLegacyPass::ScalarizerLegacyPass(const ScalarizerPassOptions &Options)
: … { … }
void ScalarizerLegacyPass::getAnalysisUsage(AnalysisUsage &AU) const { … }
char ScalarizerLegacyPass::ID = …;
INITIALIZE_PASS_BEGIN(ScalarizerLegacyPass, "scalarizer",
"Scalarize vector operations", false, false)
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
INITIALIZE_PASS_END(ScalarizerLegacyPass, "scalarizer",
"Scalarize vector operations", false, false)
Scatterer::Scatterer(BasicBlock *bb, BasicBlock::iterator bbi, Value *v,
const VectorSplit &VS, ValueVector *cachePtr)
: … { … }
Value *Scatterer::operator[](unsigned Frag) { … }
bool ScalarizerLegacyPass::runOnFunction(Function &F) { … }
FunctionPass *llvm::createScalarizerPass(const ScalarizerPassOptions &Options) { … }
bool ScalarizerVisitor::visit(Function &F) { … }
Scatterer ScalarizerVisitor::scatter(Instruction *Point, Value *V,
const VectorSplit &VS) { … }
void ScalarizerVisitor::gather(Instruction *Op, const ValueVector &CV,
const VectorSplit &VS) { … }
void ScalarizerVisitor::replaceUses(Instruction *Op, Value *CV) { … }
bool ScalarizerVisitor::canTransferMetadata(unsigned Tag) { … }
void ScalarizerVisitor::transferMetadataAndIRFlags(Instruction *Op,
const ValueVector &CV) { … }
std::optional<VectorSplit> ScalarizerVisitor::getVectorSplit(Type *Ty) { … }
std::optional<VectorLayout>
ScalarizerVisitor::getVectorLayout(Type *Ty, Align Alignment,
const DataLayout &DL) { … }
template<typename Splitter>
bool ScalarizerVisitor::splitUnary(Instruction &I, const Splitter &Split) { … }
template<typename Splitter>
bool ScalarizerVisitor::splitBinary(Instruction &I, const Splitter &Split) { … }
static bool isTriviallyScalariable(Intrinsic::ID ID) { … }
bool ScalarizerVisitor::splitCall(CallInst &CI) { … }
bool ScalarizerVisitor::visitSelectInst(SelectInst &SI) { … }
bool ScalarizerVisitor::visitICmpInst(ICmpInst &ICI) { … }
bool ScalarizerVisitor::visitFCmpInst(FCmpInst &FCI) { … }
bool ScalarizerVisitor::visitUnaryOperator(UnaryOperator &UO) { … }
bool ScalarizerVisitor::visitBinaryOperator(BinaryOperator &BO) { … }
bool ScalarizerVisitor::visitGetElementPtrInst(GetElementPtrInst &GEPI) { … }
bool ScalarizerVisitor::visitCastInst(CastInst &CI) { … }
bool ScalarizerVisitor::visitBitCastInst(BitCastInst &BCI) { … }
bool ScalarizerVisitor::visitInsertElementInst(InsertElementInst &IEI) { … }
bool ScalarizerVisitor::visitExtractElementInst(ExtractElementInst &EEI) { … }
bool ScalarizerVisitor::visitShuffleVectorInst(ShuffleVectorInst &SVI) { … }
bool ScalarizerVisitor::visitPHINode(PHINode &PHI) { … }
bool ScalarizerVisitor::visitLoadInst(LoadInst &LI) { … }
bool ScalarizerVisitor::visitStoreInst(StoreInst &SI) { … }
bool ScalarizerVisitor::visitCallInst(CallInst &CI) { … }
bool ScalarizerVisitor::visitFreezeInst(FreezeInst &FI) { … }
bool ScalarizerVisitor::finish() { … }
PreservedAnalyses ScalarizerPass::run(Function &F, FunctionAnalysisManager &AM) { … }