<commit_before>//===----- LoadStoreVectorizer.cpp - GPU Load & Store Vectorizer ----------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/Vectorize.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/Analysis/VectorUtils.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Value.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"

using namespace llvm;

#define DEBUG_TYPE "load-store-vectorizer"
STATISTIC(NumVectorInstructions, "Number of vector accesses generated");
STATISTIC(NumScalarsVectorized, "Number of scalar accesses vectorized");

namespace {

// TODO: Remove this
static const unsigned TargetBaseAlign = 4;

class Vectorizer {
  typedef SmallVector<Value *, 8> ValueList;
  typedef MapVector<Value *, ValueList> ValueListMap;

  Function &F;
  AliasAnalysis &AA;
  DominatorTree &DT;
  ScalarEvolution &SE;
  TargetTransformInfo &TTI;
  const DataLayout &DL;
  IRBuilder<> Builder;
  ValueListMap StoreRefs;
  ValueListMap LoadRefs;

public:
  Vectorizer(Function &F, AliasAnalysis &AA, DominatorTree &DT,
             ScalarEvolution &SE, TargetTransformInfo &TTI)
    : F(F), AA(AA), DT(DT), SE(SE), TTI(TTI),
      DL(F.getParent()->getDataLayout()),
      Builder(SE.getContext()) {}

  bool run();

private:
  Value *getPointerOperand(Value *I);

  unsigned getPointerAddressSpace(Value *I);

  unsigned getAlignment(LoadInst *LI) const {
    unsigned Align = LI->getAlignment();
    if (Align != 0)
      return Align;

    return DL.getABITypeAlignment(LI->getType());
  }

  unsigned getAlignment(StoreInst *SI) const {
    unsigned Align = SI->getAlignment();
    if (Align != 0)
      return Align;

    return DL.getABITypeAlignment(SI->getValueOperand()->getType());
  }

  bool isConsecutiveAccess(Value *A, Value *B);

  /// Reorders the users of I after vectorization to ensure that I dominates its
  /// users.
  void reorder(Instruction *I);

  /// Returns the first and the last instructions in Chain.
  std::pair<BasicBlock::iterator, BasicBlock::iterator>
  getBoundaryInstrs(ArrayRef<Value *> Chain);

  /// Erases the original instructions after vectorizing.
  void eraseInstructions(ArrayRef<Value *> Chain);

  /// "Legalize" the vector type that would be produced by combining \p
  /// ElementSizeBits elements in \p Chain. Break into two pieces such that the
  /// total size of each piece is 1, 2 or a multiple of 4 bytes. \p Chain is
  /// expected to have more than 4 elements.
  std::pair<ArrayRef<Value *>, ArrayRef<Value *>>
  splitOddVectorElts(ArrayRef<Value *> Chain, unsigned ElementSizeBits);

  /// Checks if there are any instructions which may affect the memory accessed
  /// in the chain between \p From and \p To. The elements of \p Chain should be
  /// all loads or all stores.
  bool isVectorizable(ArrayRef<Value *> Chain, BasicBlock::iterator From,
                      BasicBlock::iterator To);

  /// Collects load and store instructions to vectorize.
  void collectInstructions(BasicBlock *BB);

  /// Processes the collected instructions, the \p Map. The elements of \p Map
  /// should be all loads or all stores.
  bool vectorizeChains(ValueListMap &Map);

  /// Finds the load/stores to consecutive memory addresses and vectorizes them.
  bool vectorizeInstructions(ArrayRef<Value *> Instrs);

  /// Vectorizes the load instructions in Chain.
  bool vectorizeLoadChain(ArrayRef<Value *> Chain);

  /// Vectorizes the store instructions in Chain.
  bool vectorizeStoreChain(ArrayRef<Value *> Chain);
};

class LoadStoreVectorizer : public FunctionPass {
public:
  static char ID;

  LoadStoreVectorizer() : FunctionPass(ID) {
    initializeLoadStoreVectorizerPass(*PassRegistry::getPassRegistry());
  }

  bool runOnFunction(Function &F) override;

  const char *getPassName() const override {
    return "GPU Load and Store Vectorizer";
  }

  void getAnalysisUsage(AnalysisUsage &AU) const override {
    AU.addRequired<AAResultsWrapperPass>();
    AU.addRequired<ScalarEvolutionWrapperPass>();
    AU.addRequired<DominatorTreeWrapperPass>();
    AU.addRequired<TargetTransformInfoWrapperPass>();
    AU.setPreservesCFG();
  }
};
}

INITIALIZE_PASS_BEGIN(LoadStoreVectorizer, DEBUG_TYPE,
                      "Vectorize load and Store instructions", false, false);
INITIALIZE_PASS_DEPENDENCY(SCEVAAWrapperPass)
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
INITIALIZE_PASS_DEPENDENCY(GlobalsAAWrapperPass)
INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
INITIALIZE_PASS_END(LoadStoreVectorizer, DEBUG_TYPE,
                    "Vectorize load and store instructions", false, false);

char LoadStoreVectorizer::ID = 0;

Pass *llvm::createLoadStoreVectorizerPass() {
  return new LoadStoreVectorizer();
}

bool LoadStoreVectorizer::runOnFunction(Function &F) {
  // Don't vectorize when the attribute NoImplicitFloat is used.
  if (skipFunction(F) || F.hasFnAttribute(Attribute::NoImplicitFloat))
    return false;

  AliasAnalysis &AA = getAnalysis<AAResultsWrapperPass>().getAAResults();
  DominatorTree &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
  ScalarEvolution &SE = getAnalysis<ScalarEvolutionWrapperPass>().getSE();
  TargetTransformInfo &TTI
    = getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);

  Vectorizer V(F, AA, DT, SE, TTI);
  return V.run();
}

// Vectorizer Implementation
bool Vectorizer::run() {
  bool Changed = false;

  // Scan the blocks in the function in post order.
  for (BasicBlock *BB : post_order(&F)) {<commit_msg>LoadStoreVectorizer: Fix warning about extra semicolon<commit_after>//===----- LoadStoreVectorizer.cpp - GPU Load & Store Vectorizer ----------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/Vectorize.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/Analysis/VectorUtils.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Value.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"

using namespace llvm;

#define DEBUG_TYPE "load-store-vectorizer"
STATISTIC(NumVectorInstructions, "Number of vector accesses generated");
STATISTIC(NumScalarsVectorized, "Number of scalar accesses vectorized");

namespace {

// TODO: Remove this
static const unsigned TargetBaseAlign = 4;

class Vectorizer {
  typedef SmallVector<Value *, 8> ValueList;
  typedef MapVector<Value *, ValueList> ValueListMap;

  Function &F;
  AliasAnalysis &AA;
  DominatorTree &DT;
  ScalarEvolution &SE;
  TargetTransformInfo &TTI;
  const DataLayout &DL;
  IRBuilder<> Builder;
  ValueListMap StoreRefs;
  ValueListMap LoadRefs;

public:
  Vectorizer(Function &F, AliasAnalysis &AA, DominatorTree &DT,
             ScalarEvolution &SE, TargetTransformInfo &TTI)
    : F(F), AA(AA), DT(DT), SE(SE), TTI(TTI),
      DL(F.getParent()->getDataLayout()),
      Builder(SE.getContext()) {}

  bool run();

private:
  Value *getPointerOperand(Value *I);

  unsigned getPointerAddressSpace(Value *I);

  unsigned getAlignment(LoadInst *LI) const {
    unsigned Align = LI->getAlignment();
    if (Align != 0)
      return Align;

    return DL.getABITypeAlignment(LI->getType());
  }

  unsigned getAlignment(StoreInst *SI) const {
    unsigned Align = SI->getAlignment();
    if (Align != 0)
      return Align;

    return DL.getABITypeAlignment(SI->getValueOperand()->getType());
  }

  bool isConsecutiveAccess(Value *A, Value *B);

  /// Reorders the users of I after vectorization to ensure that I dominates its
  /// users.
  void reorder(Instruction *I);

  /// Returns the first and the last instructions in Chain.
  std::pair<BasicBlock::iterator, BasicBlock::iterator>
  getBoundaryInstrs(ArrayRef<Value *> Chain);

  /// Erases the original instructions after vectorizing.
  void eraseInstructions(ArrayRef<Value *> Chain);

  /// "Legalize" the vector type that would be produced by combining \p
  /// ElementSizeBits elements in \p Chain. Break into two pieces such that the
  /// total size of each piece is 1, 2 or a multiple of 4 bytes. \p Chain is
  /// expected to have more than 4 elements.
  std::pair<ArrayRef<Value *>, ArrayRef<Value *>>
  splitOddVectorElts(ArrayRef<Value *> Chain, unsigned ElementSizeBits);

  /// Checks if there are any instructions which may affect the memory accessed
  /// in the chain between \p From and \p To. The elements of \p Chain should be
  /// all loads or all stores.
  bool isVectorizable(ArrayRef<Value *> Chain, BasicBlock::iterator From,
                      BasicBlock::iterator To);

  /// Collects load and store instructions to vectorize.
  void collectInstructions(BasicBlock *BB);

  /// Processes the collected instructions, the \p Map. The elements of \p Map
  /// should be all loads or all stores.
  bool vectorizeChains(ValueListMap &Map);

  /// Finds the load/stores to consecutive memory addresses and vectorizes them.
  bool vectorizeInstructions(ArrayRef<Value *> Instrs);

  /// Vectorizes the load instructions in Chain.
  bool vectorizeLoadChain(ArrayRef<Value *> Chain);

  /// Vectorizes the store instructions in Chain.
  bool vectorizeStoreChain(ArrayRef<Value *> Chain);
};

class LoadStoreVectorizer : public FunctionPass {
public:
  static char ID;

  LoadStoreVectorizer() : FunctionPass(ID) {
    initializeLoadStoreVectorizerPass(*PassRegistry::getPassRegistry());
  }

  bool runOnFunction(Function &F) override;

  const char *getPassName() const override {
    return "GPU Load and Store Vectorizer";
  }

  void getAnalysisUsage(AnalysisUsage &AU) const override {
    AU.addRequired<AAResultsWrapperPass>();
    AU.addRequired<ScalarEvolutionWrapperPass>();
    AU.addRequired<DominatorTreeWrapperPass>();
    AU.addRequired<TargetTransformInfoWrapperPass>();
    AU.setPreservesCFG();
  }
};
}

INITIALIZE_PASS_BEGIN(LoadStoreVectorizer, DEBUG_TYPE,
                      "Vectorize load and Store instructions", false, false)
INITIALIZE_PASS_DEPENDENCY(SCEVAAWrapperPass)
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
INITIALIZE_PASS_DEPENDENCY(GlobalsAAWrapperPass)
INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
INITIALIZE_PASS_END(LoadStoreVectorizer, DEBUG_TYPE,
                    "Vectorize load and store instructions", false, false)

char LoadStoreVectorizer::ID = 0;

Pass *llvm::createLoadStoreVectorizerPass() {
  return new LoadStoreVectorizer();
}

bool LoadStoreVectorizer::runOnFunction(Function &F) {
  // Don't vectorize when the attribute NoImplicitFloat is used.
  if (skipFunction(F) || F.hasFnAttribute(Attribute::NoImplicitFloat))
    return false;

  AliasAnalysis &AA = getAnalysis<AAResultsWrapperPass>().getAAResults();
  DominatorTree &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
  ScalarEvolution &SE = getAnalysis<ScalarEvolutionWrapperPass>().getSE();
  TargetTransformInfo &TTI
    = getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);

  Vectorizer V(F, AA, DT, SE, TTI);
  return V.run();
}

// Vectorizer Implementation
bool Vectorizer::run() {
  bool Changed = false;

  // Scan the blocks in the function in post order.
  for (BasicBlock *BB : post_order(&F)) {
{'fraction_non_alphanumeric': 0.13558926487747958, 'fraction_numerical': 0.0014002333722287048, 'mean_word_length': 3.9068702290076334, 'pattern_counts': {'":': 0, '<': 47, '<?xml version=': 0, '>': 59, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5537891', 'n_tokens_mistral': 3890, 'n_tokens_neox': 3785, 'n_words': 1013}