Exemple #1
0
BT::RegisterCell BT::MachineEvaluator::eSUB(const RegisterCell &A1,
      const RegisterCell &A2) const {
  uint16_t W = A1.width();
  assert(W == A2.width());
  RegisterCell Res(W);
  bool Borrow = false;
  uint16_t I;
  for (I = 0; I < W; ++I) {
    const BitValue &V1 = A1[I];
    const BitValue &V2 = A2[I];
    if (!V1.num() || !V2.num())
      break;
    unsigned S = bool(V1) - bool(V2) - Borrow;
    Res[I] = BitValue(S & 1);
    Borrow = (S > 1);
  }
  for (; I < W; ++I) {
    const BitValue &V1 = A1[I];
    const BitValue &V2 = A2[I];
    if (V1.is(Borrow)) {
      Res[I] = BitValue::ref(V2);
      break;
    }
    if (V2.is(Borrow))
      Res[I] = BitValue::ref(V1);
    else
      break;
  }
  for (; I < W; ++I)
    Res[I] = BitValue::self();
  return Res;
}
Exemple #2
0
BT::RegisterCell BT::MachineEvaluator::eADD(const RegisterCell &A1,
      const RegisterCell &A2) const {
  uint16_t W = A1.width();
  assert(W == A2.width());
  RegisterCell Res(W);
  bool Carry = false;
  uint16_t I;
  for (I = 0; I < W; ++I) {
    const BitValue &V1 = A1[I];
    const BitValue &V2 = A2[I];
    if (!V1.num() || !V2.num())
      break;
    unsigned S = bool(V1) + bool(V2) + Carry;
    Res[I] = BitValue(S & 1);
    Carry = (S > 1);
  }
  for (; I < W; ++I) {
    const BitValue &V1 = A1[I];
    const BitValue &V2 = A2[I];
    // If the next bit is same as Carry, the result will be 0 plus the
    // other bit. The Carry bit will remain unchanged.
    if (V1.is(Carry))
      Res[I] = BitValue::ref(V2);
    else if (V2.is(Carry))
      Res[I] = BitValue::ref(V1);
    else
      break;
  }
  for (; I < W; ++I)
    Res[I] = BitValue::self();
  return Res;
}
Exemple #3
0
BT::RegisterCell BT::MachineEvaluator::eMLU(const RegisterCell &A1,
      const RegisterCell &A2) const {
  uint16_t W = A1.width() + A2.width();
  uint16_t Z = A1.ct(false) + A2.ct(false);
  RegisterCell Res(W);
  Res.fill(0, Z, BitValue::Zero);
  Res.fill(Z, W, BitValue::self());
  return Res;
}
Exemple #4
0
BT::RegisterCell BT::MachineEvaluator::eINS(const RegisterCell &A1,
      const RegisterCell &A2, uint16_t AtN) const {
  uint16_t W1 = A1.width(), W2 = A2.width();
  (void)W1;
  assert(AtN < W1 && AtN+W2 <= W1);
  // Copy bits from A1, insert A2 at position AtN.
  RegisterCell Res = RegisterCell::ref(A1);
  if (W2 > 0)
    Res.insert(RegisterCell::ref(A2), BT::BitMask(AtN, AtN+W2-1));
  return Res;
}
Exemple #5
0
BT::RegisterCell BT::MachineEvaluator::eCLR(const RegisterCell &A1,
      uint16_t BitN) const {
  assert(BitN < A1.width());
  RegisterCell Res = RegisterCell::ref(A1);
  Res[BitN] = BitValue::Zero;
  return Res;
}
Exemple #6
0
// Check if the cell represents a compile-time integer value.
bool BT::MachineEvaluator::isInt(const RegisterCell &A) const {
  uint16_t W = A.width();
  for (uint16_t i = 0; i < W; ++i)
    if (!A[i].is(0) && !A[i].is(1))
      return false;
  return true;
}
Exemple #7
0
BT::RegisterCell BT::MachineEvaluator::eZXT(const RegisterCell &A1,
      uint16_t FromN) const {
  uint16_t W = A1.width();
  assert(FromN <= W);
  RegisterCell Res = RegisterCell::ref(A1);
  Res.fill(FromN, W, BitValue::Zero);
  return Res;
}
Exemple #8
0
BT::RegisterCell BT::MachineEvaluator::eASL(const RegisterCell &A1,
      uint16_t Sh) const {
  assert(Sh <= A1.width());
  RegisterCell Res = RegisterCell::ref(A1);
  Res.rol(Sh);
  Res.fill(0, Sh, BitValue::Zero);
  return Res;
}
Exemple #9
0
BT::RegisterCell BT::MachineEvaluator::eCTB(const RegisterCell &A1, bool B,
      uint16_t W) const {
  uint16_t C = A1.ct(B), AW = A1.width();
  // If the last trailing non-B bit is not a constant, then we don't know
  // the real count.
  if ((C < AW && A1[C].num()) || C == AW)
    return eIMM(C, W);
  return RegisterCell::self(0, W);
}
Exemple #10
0
BT::RegisterCell BT::MachineEvaluator::eLSR(const RegisterCell &A1,
      uint16_t Sh) const {
  uint16_t W = A1.width();
  assert(Sh <= W);
  RegisterCell Res = RegisterCell::ref(A1);
  Res.rol(W-Sh);
  Res.fill(W-Sh, W, BitValue::Zero);
  return Res;
}
Exemple #11
0
BT::RegisterCell BT::MachineEvaluator::eSXT(const RegisterCell &A1,
      uint16_t FromN) const {
  uint16_t W = A1.width();
  assert(FromN <= W);
  RegisterCell Res = RegisterCell::ref(A1);
  BitValue Sign = Res[FromN-1];
  // Sign-extend "inreg".
  Res.fill(FromN, W, Sign);
  return Res;
}
Exemple #12
0
// Convert a cell to the integer value. The result must fit in uint64_t.
uint64_t BT::MachineEvaluator::toInt(const RegisterCell &A) const {
  assert(isInt(A));
  uint64_t Val = 0;
  uint16_t W = A.width();
  for (uint16_t i = 0; i < W; ++i) {
    Val <<= 1;
    Val |= A[i].is(1);
  }
  return Val;
}
Exemple #13
0
BT::RegisterCell BT::MachineEvaluator::eXOR(const RegisterCell &A1,
      const RegisterCell &A2) const {
  uint16_t W = A1.width();
  assert(W == A2.width());
  RegisterCell Res(W);
  for (uint16_t i = 0; i < W; ++i) {
    const BitValue &V1 = A1[i];
    const BitValue &V2 = A2[i];
    if (V1.is(0))
      Res[i] = BitValue::ref(V2);
    else if (V2.is(0))
      Res[i] = BitValue::ref(V1);
    else if (V1 == V2)
      Res[i] = BitValue::Zero;
    else
      Res[i] = BitValue::self();
  }
  return Res;
}
Exemple #14
0
BT::RegisterCell BT::MachineEvaluator::eXTR(const RegisterCell &A1,
      uint16_t B, uint16_t E) const {
  uint16_t W = A1.width();
  assert(B < W && E <= W);
  if (B == E)
    return RegisterCell(0);
  uint16_t Last = (E > 0) ? E-1 : W-1;
  RegisterCell Res = RegisterCell::ref(A1).extract(BT::BitMask(B, Last));
  // Return shorter cell.
  return Res;
}
Exemple #15
0
BT::RegisterCell BT::MachineEvaluator::eNOT(const RegisterCell &A1) const {
  uint16_t W = A1.width();
  RegisterCell Res(W);
  for (uint16_t i = 0; i < W; ++i) {
    const BitValue &V = A1[i];
    if (V.is(0))
      Res[i] = BitValue::One;
    else if (V.is(1))
      Res[i] = BitValue::Zero;
    else
      Res[i] = BitValue::self();
  }
  return Res;
}
Exemple #16
0
void BT::MachineEvaluator::putCell(const RegisterRef &RR, RegisterCell RC,
      CellMapType &M) const {
  // While updating the cell map can be done in a meaningful way for
  // a part of a register, it makes little sense to implement it as the
  // SSA representation would never contain such "partial definitions".
  if (!TargetRegisterInfo::isVirtualRegister(RR.Reg))
    return;
  assert(RR.Sub == 0 && "Unexpected sub-register in definition");
  // Eliminate all ref-to-reg-0 bit values: replace them with "self".
  for (unsigned i = 0, n = RC.width(); i < n; ++i) {
    const BitValue &V = RC[i];
    if (V.Type == BitValue::Ref && V.RefI.Reg == 0)
      RC[i].RefI = BitRef(RR.Reg, i);
  }
  M[RR.Reg] = RC;
}
Exemple #17
0
void BT::visitNonBranch(const MachineInstr &MI) {
  if (Trace) {
    int ThisN = MI.getParent()->getNumber();
    dbgs() << "Visit MI(BB#" << ThisN << "): " << MI;
  }
  if (MI.isDebugValue())
    return;
  assert(!MI.isBranch() && "Unexpected branch instruction");

  CellMapType ResMap;
  bool Eval = ME.evaluate(MI, Map, ResMap);

  if (Trace && Eval) {
    for (unsigned i = 0, n = MI.getNumOperands(); i < n; ++i) {
      const MachineOperand &MO = MI.getOperand(i);
      if (!MO.isReg() || !MO.isUse())
        continue;
      RegisterRef RU(MO);
      dbgs() << "  input reg: " << PrintReg(RU.Reg, &ME.TRI, RU.Sub)
             << " cell: " << ME.getCell(RU, Map) << "\n";
    }
    dbgs() << "Outputs:\n";
    for (CellMapType::iterator I = ResMap.begin(), E = ResMap.end();
         I != E; ++I) {
      RegisterRef RD(I->first);
      dbgs() << "  " << PrintReg(I->first, &ME.TRI) << " cell: "
             << ME.getCell(RD, ResMap) << "\n";
    }
  }

  // Iterate over all definitions of the instruction, and update the
  // cells accordingly.
  for (unsigned i = 0, n = MI.getNumOperands(); i < n; ++i) {
    const MachineOperand &MO = MI.getOperand(i);
    // Visit register defs only.
    if (!MO.isReg() || !MO.isDef())
      continue;
    RegisterRef RD(MO);
    assert(RD.Sub == 0 && "Unexpected sub-register in definition");
    if (!TargetRegisterInfo::isVirtualRegister(RD.Reg))
      continue;

    bool Changed = false;
    if (!Eval || ResMap.count(RD.Reg) == 0) {
      // Set to "ref" (aka "bottom").
      uint16_t DefBW = ME.getRegBitWidth(RD);
      RegisterCell RefC = RegisterCell::self(RD.Reg, DefBW);
      if (RefC != ME.getCell(RD, Map)) {
        ME.putCell(RD, RefC, Map);
        Changed = true;
      }
    } else {
      RegisterCell DefC = ME.getCell(RD, Map);
      RegisterCell ResC = ME.getCell(RD, ResMap);
      // This is a non-phi instruction, so the values of the inputs come
      // from the same registers each time this instruction is evaluated.
      // During the propagation, the values of the inputs can become lowered
      // in the sense of the lattice operation, which may cause different
      // results to be calculated in subsequent evaluations. This should
      // not cause the bottoming of the result in the map, since the new
      // result is already reflecting the lowered inputs.
      for (uint16_t i = 0, w = DefC.width(); i < w; ++i) {
        BitValue &V = DefC[i];
        // Bits that are already "bottom" should not be updated.
        if (V.Type == BitValue::Ref && V.RefI.Reg == RD.Reg)
          continue;
        // Same for those that are identical in DefC and ResC.
        if (V == ResC[i])
          continue;
        V = ResC[i];
        Changed = true;
      }
      if (Changed)
        ME.putCell(RD, DefC, Map);
    }
    if (Changed)
      visitUsesOf(RD.Reg);
  }
}