Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Firefox/js/src/jit/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 3 kB image not shown  

Quelle  AlignmentMaskAnalysis.cpp   Sprache: C

 
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 * vim: set ts=8 sts=2 et sw=2 tw=80:
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */


#include "jit/AlignmentMaskAnalysis.h"
#include "jit/MIR-wasm.h"
#include "jit/MIR.h"
#include "jit/MIRGraph.h"

using namespace js;
using namespace jit;

static bool IsAlignmentMask(uint32_t m) {
  // Test whether m is just leading ones and trailing zeros.
  return (-m & ~m) == 0;
}

static void AnalyzeAsmHeapAddress(MDefinition* ptr, MIRGraph& graph) {
  // Fold (a+i)&m to (a&m)+i, provided that this doesn't change the result,
  // since the users of the BitAnd include heap accesses. This will expose
  // the redundancy for GVN when expressions like this:
  //   a&m
  //   (a+1)&m,
  //   (a+2)&m,
  // are transformed into this:
  //   a&m
  //   (a&m)+1
  //   (a&m)+2
  // and it will allow the constants to be folded by the
  // EffectiveAddressAnalysis pass.
  //
  // Putting the add on the outside might seem like it exposes other users of
  // the expression to the possibility of i32 overflow, if we aren't in wasm
  // and they aren't naturally truncating. However, since we use MAdd::New
  // with MIRType::Int32, we make sure that the value is truncated, just as it
  // would be by the MBitAnd.

  MOZ_ASSERT(IsCompilingWasm());

  if (!ptr->isBitAnd()) {
    return;
  }

  MDefinition* lhs = ptr->toBitAnd()->getOperand(0);
  MDefinition* rhs = ptr->toBitAnd()->getOperand(1);
  if (lhs->isConstant()) {
    std::swap(lhs, rhs);
  }
  if (!lhs->isAdd() || !rhs->isConstant()) {
    return;
  }

  MDefinition* op0 = lhs->toAdd()->getOperand(0);
  MDefinition* op1 = lhs->toAdd()->getOperand(1);
  if (op0->isConstant()) {
    std::swap(op0, op1);
  }
  if (!op1->isConstant()) {
    return;
  }

  uint32_t i = op1->toConstant()->toInt32();
  uint32_t m = rhs->toConstant()->toInt32();
  if (!IsAlignmentMask(m) || (i & m) != i) {
    return;
  }

  // The pattern was matched! Produce the replacement expression.
  MInstruction* and_ = MBitAnd::New(graph.alloc(), op0, rhs, MIRType::Int32);
  ptr->block()->insertBefore(ptr->toBitAnd(), and_);
  auto* add = MAdd::New(graph.alloc(), and_, op1, TruncateKind::Truncate);
  ptr->block()->insertBefore(ptr->toBitAnd(), add);
  ptr->replaceAllUsesWith(add);
  ptr->block()->discard(ptr->toBitAnd());
}

bool AlignmentMaskAnalysis::analyze() {
  for (ReversePostorderIterator block(graph_.rpoBegin());
       block != graph_.rpoEnd(); block++) {
    for (MInstructionIterator i = block->begin(); i != block->end(); i++) {
      if (!graph_.alloc().ensureBallast()) {
        return false;
      }

      // Note that we don't check for MWasmCompareExchangeHeap
      // or MWasmAtomicBinopHeap, because the backend and the OOB
      // mechanism don't support non-zero offsets for them yet.
      if (i->isAsmJSLoadHeap()) {
        AnalyzeAsmHeapAddress(i->toAsmJSLoadHeap()->base(), graph_);
      } else if (i->isAsmJSStoreHeap()) {
        AnalyzeAsmHeapAddress(i->toAsmJSStoreHeap()->base(), graph_);
      }
    }
  }
  return true;
}

Messung V0.5
C=88 H=97 G=92

¤ Dauer der Verarbeitung: 0.12 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.