<commit_before>package analysis

import analysis.AccessCounts.SubstitutionMap
import lift.arithmetic.ArithExpr._
import lift.arithmetic._
import ir.Type
import ir.ast._
import ir.view._
import opencl.generator.OpenCLAST.VarRef
import opencl.generator.OpenCLGenerator.NDRange
import opencl.ir.pattern.{MapGlb, MapLcl}

import scala.collection.immutable


object AccessPatterns {

  def apply(lambda: Lambda,
    localSize: NDRange = Array(?,?,?),
    globalSize: NDRange = Array(?,?,?),
    valueMap: SubstitutionMap = collection.immutable.Map()
  ) = new AccessPatterns(lambda, localSize, globalSize, valueMap)

}

abstract class AccessPattern
object CoalescedPattern extends AccessPattern
object UnknownPattern extends AccessPattern

class AccessPatterns(
  lambda: Lambda,
  localSize: NDRange,
  globalSize: NDRange,
  valueMap: SubstitutionMap
) extends Analyser(lambda, localSize, globalSize, valueMap) {

  private var readPatterns = immutable.Map[Expr, AccessPattern]()
  private var writePatterns = immutable.Map[Expr, AccessPattern]()

  private var coalescingId: Option[Var] = None

  if (lambda.body.view == NoView)
    View(lambda)

  determinePatterns(lambda.body)

  def getReadPatterns: immutable.Map[Expr, AccessPattern] = readPatterns
  def getWritePatterns: immutable.Map[Expr, AccessPattern] = writePatterns

  def apply(): (immutable.Map[Expr, AccessPattern], immutable.Map[Expr, AccessPattern]) =
    (readPatterns, writePatterns)

  private def isCoalesced(v: VarRef, length: ArithExpr): Boolean = {
    val accessLocation = v.arrayIndex.content

    if (coalescingId.isEmpty)
      return false

    val newVar = Var()
    val i0 = substitute(accessLocation, immutable.Map(coalescingId.get -> (newVar + 0)))
    val i1 = substitute(accessLocation, immutable.Map(coalescingId.get -> (newVar + 1)))

    i1 - i0 == length
  }

  private def getAccessPattern(v: VarRef, length: ArithExpr) = {
    if (isCoalesced(v, length))
      CoalescedPattern
    else
      UnknownPattern
  }

  private def getAccessPattern(expr: Expr): AccessPattern = {
    val length = Type.getLength(Type.getValueType(expr.view.t))
    ViewPrinter.emit(Var(), expr.view) match {
      case v: VarRef => getAccessPattern(v, length)
      case x => throw new MatchError(s"Expected a VarRef, but got ${x.toString}.")
    }
  }

  private def determinePatterns(expr: Expr): Unit = {

    expr match {
      case FunCall(f, args@_*) =>
        args.foreach(determinePatterns)

        f match {
          case mapLcl@MapLcl(0, nestedLambda) =>
            coalescingId = Some(mapLcl.loopVar)
            determinePatterns(nestedLambda.body)
            coalescingId = None

          case mapGlb@MapGlb(0, nestedLambda) =>
            coalescingId = Some(mapGlb.loopVar)
            determinePatterns(nestedLambda.body)
            coalescingId = None

          case lambda: Lambda => determinePatterns(lambda.body)
          case fp: FPattern => determinePatterns(fp.f.body)
          case _: UserFun | _: VectorizeUserFun =>

            args.foreach(arg => readPatterns += arg -> getAccessPattern(arg))

            writePatterns += expr -> getAccessPattern(expr)

          case _ =>
        }

      case _ =>
    }

  }

}<commit_msg>Don't try to assign an access pattern to something that's not an access.<commit_after>package analysis

import analysis.AccessCounts.SubstitutionMap
import lift.arithmetic.ArithExpr._
import lift.arithmetic._
import ir.Type
import ir.ast._
import ir.view._
import opencl.generator.OpenCLAST.VarRef
import opencl.generator.OpenCLGenerator.NDRange
import opencl.ir.pattern.{MapGlb, MapLcl}

import scala.collection.immutable


object AccessPatterns {

  def apply(lambda: Lambda,
    localSize: NDRange = Array(?,?,?),
    globalSize: NDRange = Array(?,?,?),
    valueMap: SubstitutionMap = collection.immutable.Map()
  ) = new AccessPatterns(lambda, localSize, globalSize, valueMap)

}

abstract class AccessPattern
object CoalescedPattern extends AccessPattern
object UnknownPattern extends AccessPattern

class AccessPatterns(
  lambda: Lambda,
  localSize: NDRange,
  globalSize: NDRange,
  valueMap: SubstitutionMap
) extends Analyser(lambda, localSize, globalSize, valueMap) {

  private var readPatterns = immutable.Map[Expr, AccessPattern]()
  private var writePatterns = immutable.Map[Expr, AccessPattern]()

  private var coalescingId: Option[Var] = None

  if (lambda.body.view == NoView)
    View(lambda)

  determinePatterns(lambda.body)

  def getReadPatterns: immutable.Map[Expr, AccessPattern] = readPatterns
  def getWritePatterns: immutable.Map[Expr, AccessPattern] = writePatterns

  def apply(): (immutable.Map[Expr, AccessPattern], immutable.Map[Expr, AccessPattern]) =
    (readPatterns, writePatterns)

  private def isCoalesced(v: VarRef, length: ArithExpr): Boolean = {
    val accessLocation = v.arrayIndex.content

    if (coalescingId.isEmpty)
      return false

    val newVar = Var()
    val i0 = substitute(accessLocation, immutable.Map(coalescingId.get -> (newVar + 0)))
    val i1 = substitute(accessLocation, immutable.Map(coalescingId.get -> (newVar + 1)))

    i1 - i0 == length
  }

  private def getAccessPattern(v: VarRef, length: ArithExpr) = {
    if (isCoalesced(v, length))
      Some(CoalescedPattern)
    else
      Some(UnknownPattern)
  }

  private def getAccessPattern(expr: Expr): Option[AccessPattern] = {
    val length = Type.getLength(Type.getValueType(expr.view.t))
    ViewPrinter.emit(Var(), expr.view) match {
      case v: VarRef => getAccessPattern(v, length)
      case _ => None
    }
  }

  private def determinePatterns(expr: Expr): Unit = {

    expr match {
      case FunCall(f, args@_*) =>
        args.foreach(determinePatterns)

        f match {
          case mapLcl@MapLcl(0, nestedLambda) =>
            coalescingId = Some(mapLcl.loopVar)
            determinePatterns(nestedLambda.body)
            coalescingId = None

          case mapGlb@MapGlb(0, nestedLambda) =>
            coalescingId = Some(mapGlb.loopVar)
            determinePatterns(nestedLambda.body)
            coalescingId = None

          case lambda: Lambda => determinePatterns(lambda.body)
          case fp: FPattern => determinePatterns(fp.f.body)
          case _: UserFun | _: VectorizeUserFun =>

            args.foreach(arg => {
              val accessPattern = getAccessPattern(arg)

              if (accessPattern.isDefined)
                readPatterns += arg -> accessPattern.get
            })

            writePatterns += expr -> getAccessPattern(expr).get

          case _ =>
        }

      case _ =>
    }

  }

}
{'fraction_non_alphanumeric': 0.1017384731670446, 'fraction_numerical': 0.002418745275888133, 'mean_word_length': 3.338360655737705, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 33, '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': '511078', 'n_tokens_mistral': 2060, 'n_tokens_neox': 2003, 'n_words': 459}