Esempio n. 1
0
int Expr::evaluateAsInteger(){
    if (isIntExpr()){
        return ((IntExpr*)this)->getValue();
    }

    if (isBinaryExpr()){
        BinaryExpr* binExpr = (BinaryExpr*)this;
        int e1 = binExpr->getE1()->evaluateAsInteger();
        int e2 = binExpr->getE1()->evaluateAsInteger();
        BinaryOp* op = binExpr->getOp();

        switch(op->getType()){
        case BinaryOp::TIMES:
            return e1*e2;
            break;

        case BinaryOp::MINUS:
            return e1-e2;
            break;

        case BinaryOp::PLUS:
            return e1+e2;
            break;

        default :
            cerr << "Unsupported binary expression for evaluation" << endl;
            exit(1);
        }

    }

    cerr << "Can't evaluate this expression";
    exit(1);
}
Esempio n. 2
0
void IRGenerator::accept(BinaryExpr& expr)
{
    FNTRACE();

    static const std::unordered_map<
        int /*FlowVM::Opcode*/,
        Value* (IRGenerator::*)(Value*, Value*, const std::string&)
    > ops = {
        // numerical
        { FlowVM::Opcode::NADD, &IRGenerator::createAdd },
        { FlowVM::Opcode::NSUB, &IRGenerator::createSub },
        { FlowVM::Opcode::NMUL, &IRGenerator::createMul },
        { FlowVM::Opcode::NDIV, &IRGenerator::createDiv },
        { FlowVM::Opcode::NREM, &IRGenerator::createRem },
        { FlowVM::Opcode::NSHL, &IRGenerator::createShl },
        { FlowVM::Opcode::NSHR, &IRGenerator::createShr },
        { FlowVM::Opcode::NPOW, &IRGenerator::createPow },
        { FlowVM::Opcode::NAND, &IRGenerator::createAnd },
        { FlowVM::Opcode::NOR,  &IRGenerator::createOr },
        { FlowVM::Opcode::NXOR, &IRGenerator::createXor },
        { FlowVM::Opcode::NCMPEQ, &IRGenerator::createNCmpEQ },
        { FlowVM::Opcode::NCMPNE, &IRGenerator::createNCmpNE },
        { FlowVM::Opcode::NCMPLE, &IRGenerator::createNCmpLE },
        { FlowVM::Opcode::NCMPGE, &IRGenerator::createNCmpGE },
        { FlowVM::Opcode::NCMPLT, &IRGenerator::createNCmpLT },
        { FlowVM::Opcode::NCMPGT, &IRGenerator::createNCmpGT },

        // string
        { FlowVM::Opcode::SADD, &IRGenerator::createSAdd },
        { FlowVM::Opcode::SCMPEQ, &IRGenerator::createSCmpEQ },
        { FlowVM::Opcode::SCMPNE, &IRGenerator::createSCmpNE },
        { FlowVM::Opcode::SCMPLE, &IRGenerator::createSCmpLE },
        { FlowVM::Opcode::SCMPGE, &IRGenerator::createSCmpGE },
        { FlowVM::Opcode::SCMPLT, &IRGenerator::createSCmpLT },
        { FlowVM::Opcode::SCMPGT, &IRGenerator::createSCmpGT },
        { FlowVM::Opcode::SCMPBEG, &IRGenerator::createSCmpEB },
        { FlowVM::Opcode::SCMPEND, &IRGenerator::createSCmpEE },
        //{ FlowVM::Opcode::SCONTAINS, &IRGenerator::createSContains },

        // regex
        { FlowVM::Opcode::SREGMATCH, &IRGenerator::createSCmpRE },
    };

    Value* lhs = codegen(expr.leftExpr());
    Value* rhs = codegen(expr.rightExpr());

    auto i = ops.find(expr.op());
    if (i != ops.end()) {
        result_ = (this->*i->second)(lhs, rhs, "");
    } else {
        // fall back to generic VmInstr
        result_ = insert(new VmInstr(expr.op(), {lhs, rhs}));
    }
}
Esempio n. 3
0
Expr* BinaryExpr::CreateSubExprForPushdown(const std::vector<std::string> &inTableNameList) const
{
	PDASSERT(mpLeftOperand && mpRightOperand);

	Expr *result = NULL;

	Expr *leftExpr = NULL;
	if (mpLeftOperand)
	{
		leftExpr = mpLeftOperand->CreateSubExprForPushdown(inTableNameList);
	}

	if (leftExpr)
	{
		Expr *rightExpr = NULL;

		if (mpRightOperand)
		{
			rightExpr = mpRightOperand->CreateSubExprForPushdown(inTableNameList);
		}

		if (rightExpr)
		{
			BinaryExpr *newBinaryExpr = new BinaryExpr();
			
			newBinaryExpr->SetOpType(this->GetOpType());
			newBinaryExpr->SetLeftOperand(leftExpr);
			newBinaryExpr->SetRightOperand(rightExpr);

			result = newBinaryExpr;
		}
		else
		{
			delete leftExpr;
			leftExpr = NULL;
		}
	}

	return result;
}
Esempio n. 4
0
      std::string process_impl(BinaryExpr const & e, bool use_parenthesis, rt_latex_translator<InterfaceType> const & translator) const
      {
        std::stringstream ss;
        viennamath::rt_expr<InterfaceType> lhs(e.lhs()->clone());
        viennamath::rt_expr<InterfaceType> rhs(e.rhs()->clone());

        if (dynamic_cast< const op_binary<op_div<NumericType>, InterfaceType> * >(e.op()) != NULL)  //division -> \frac{}{}
        {
          if (use_parenthesis)
            ss << " \\left( ";
          ss << " \\frac{" << translator(lhs) << "}{" << translator(rhs) << "} ";
          if (use_parenthesis)
            ss << " \\right) ";
        }
        else
        {
          bool is_op_mult = false;
          if (dynamic_cast< const op_binary<op_mult<NumericType>, InterfaceType> * >(e.op()) != NULL)
            is_op_mult = true;

          bool is_op_minus = false;
          if (dynamic_cast< const op_binary<op_minus<NumericType>, InterfaceType> * >(e.op()) != NULL)
            is_op_minus = true;

          if (use_parenthesis)
            ss << "(";
          ss << translator(lhs, is_op_mult);
          if (is_op_mult)
            ss << " \\cdot ";
          else
            ss << " " << e.op()->str() << " ";
          ss << translator(rhs, is_op_mult || is_op_minus);
          if (use_parenthesis)
            ss << ")";
        }

        return ss.str();
      }
Esempio n. 5
0
// we need to check for div by zero during partial evaluation,
// if this occurs then simply ignore the 0 divisor and use the
// original expression.
ExprVisitor::Action ExprEvaluator::protectedDivOperation(const BinaryExpr &e) {
  ref<Expr> kids[2] = { visit(e.left),
                        visit(e.right) };

  if (ConstantExpr *CE = dyn_cast<ConstantExpr>(kids[1]))
    if (CE->isZero())
      kids[1] = e.right;

  if (kids[0]!=e.left || kids[1]!=e.right) {
    return Action::changeTo(e.rebuild(kids));
  } else {
    return Action::skipChildren();
  }
}
Esempio n. 6
0
void FlowCallVisitor::accept(BinaryExpr& expr)
{
    visit(expr.leftExpr());
    visit(expr.rightExpr());
}
Esempio n. 7
0
void IRGenerator::accept(BinaryExpr& expr)
{
    FNTRACE();

    static const std::unordered_map<
        int /*FlowVM::Opcode*/,
        Value* (IRGenerator::*)(Value*, Value*, const std::string&)
    > ops = {
        // numerical
        { FlowVM::Opcode::NADD, &IRGenerator::createAdd },
        { FlowVM::Opcode::NSUB, &IRGenerator::createSub },
        { FlowVM::Opcode::NMUL, &IRGenerator::createMul },
        { FlowVM::Opcode::NDIV, &IRGenerator::createDiv },
        { FlowVM::Opcode::NREM, &IRGenerator::createRem },
        { FlowVM::Opcode::NSHL, &IRGenerator::createShl },
        { FlowVM::Opcode::NSHR, &IRGenerator::createShr },
        { FlowVM::Opcode::NPOW, &IRGenerator::createPow },
        { FlowVM::Opcode::NAND, &IRGenerator::createAnd },
        { FlowVM::Opcode::NOR,  &IRGenerator::createOr },
        { FlowVM::Opcode::NXOR, &IRGenerator::createXor },
        { FlowVM::Opcode::NCMPEQ, &IRGenerator::createNCmpEQ },
        { FlowVM::Opcode::NCMPNE, &IRGenerator::createNCmpNE },
        { FlowVM::Opcode::NCMPLE, &IRGenerator::createNCmpLE },
        { FlowVM::Opcode::NCMPGE, &IRGenerator::createNCmpGE },
        { FlowVM::Opcode::NCMPLT, &IRGenerator::createNCmpLT },
        { FlowVM::Opcode::NCMPGT, &IRGenerator::createNCmpGT },

        // string
        { FlowVM::Opcode::SADD, &IRGenerator::createSAdd },
        { FlowVM::Opcode::SCMPEQ, &IRGenerator::createSCmpEQ },
        { FlowVM::Opcode::SCMPNE, &IRGenerator::createSCmpNE },
        { FlowVM::Opcode::SCMPLE, &IRGenerator::createSCmpLE },
        { FlowVM::Opcode::SCMPGE, &IRGenerator::createSCmpGE },
        { FlowVM::Opcode::SCMPLT, &IRGenerator::createSCmpLT },
        { FlowVM::Opcode::SCMPGT, &IRGenerator::createSCmpGT },
        { FlowVM::Opcode::SCMPBEG, &IRGenerator::createSCmpEB },
        { FlowVM::Opcode::SCMPEND, &IRGenerator::createSCmpEE },
        { FlowVM::Opcode::SCONTAINS, &IRGenerator::createSIn },

        // regex
        { FlowVM::Opcode::SREGMATCH, &IRGenerator::createSCmpRE },

        // ip
        { FlowVM::Opcode::PCMPEQ, &IRGenerator::createPCmpEQ },
        { FlowVM::Opcode::PCMPNE, &IRGenerator::createPCmpNE },
        { FlowVM::Opcode::PINCIDR, &IRGenerator::createPInCidr },
    };

    if (expr.op() == FlowVM::Opcode::BOR) {
        // (lhs || rhs)
        //
        //   L = lhs();
        //   if (L) goto end;
        //   R = rhs();
        //   L = R;
        // end:
        //   result = L;

        BasicBlock* borLeft = createBlock("bor.left");
        BasicBlock* borRight = createBlock("bor.right");
        BasicBlock* borCont = createBlock("bor.cont");

        AllocaInstr* result = createAlloca(FlowType::Boolean, get(1), "bor");
        Value* lhs = codegen(expr.leftExpr());
        createCondBr(lhs, borLeft, borRight);

        setInsertPoint(borLeft);
        createStore(result, lhs, "bor.left");
        createBr(borCont);

        setInsertPoint(borRight);
        Value* rhs = codegen(expr.rightExpr());
        createStore(result, rhs, "bor.right");
        createBr(borCont);

        setInsertPoint(borCont);

        result_ = result;

        return;
    }

    Value* lhs = codegen(expr.leftExpr());
    Value* rhs = codegen(expr.rightExpr());

    auto i = ops.find(expr.op());
    if (i != ops.end()) {
        result_ = (this->*i->second)(lhs, rhs, "");
    } else {
        fprintf(stderr, "BUG: Binary operation `%s` not implemented.\n", mnemonic(expr.op()));
        assert(!"Unimplemented");
        result_ = nullptr;
    }
}
Esempio n. 8
0
// XXX we really want to do some sort of canonicalization of exprs
// globally so that cases below become simpler
void ImpliedValue::getImpliedValues(ref<Expr> e,
                                    ref<ConstantExpr> value,
                                    ImpliedValueList &results) {
  switch (e->getKind()) {
  case Expr::Constant: {
    assert(value == cast<ConstantExpr>(e) && 
           "error in implied value calculation");
    break;
  }

    // Special

  case Expr::NotOptimized: break;

  case Expr::Read: {
    // XXX in theory it is possible to descend into a symbolic index
    // under certain circumstances (all values known, known value
    // unique, or range known, max / min hit). Seems unlikely this
    // would work often enough to be worth the effort.
    ReadExpr *re = cast<ReadExpr>(e);
    results.push_back(std::make_pair(re, value));
    break;
  }
    
  case Expr::Select: {
    // not much to do, could improve with range analysis
    SelectExpr *se = cast<SelectExpr>(e);
    
    if (ConstantExpr *TrueCE = dyn_cast<ConstantExpr>(se->trueExpr)) {
      if (ConstantExpr *FalseCE = dyn_cast<ConstantExpr>(se->falseExpr)) {
        if (TrueCE != FalseCE) {
          if (value == TrueCE) {
            getImpliedValues(se->cond, ConstantExpr::alloc(1, Expr::Bool), 
                             results);
          } else {
            assert(value == FalseCE &&
                   "err in implied value calculation");
            getImpliedValues(se->cond, ConstantExpr::alloc(0, Expr::Bool), 
                             results);
          }
        }
      }
    }
    break;
  }

  case Expr::Concat: {
    ConcatExpr *ce = cast<ConcatExpr>(e);
    getImpliedValues(ce->getKid(0), value->Extract(ce->getKid(1)->getWidth(),
                                                   ce->getKid(0)->getWidth()),
                     results);
    getImpliedValues(ce->getKid(1), value->Extract(0,
                                                   ce->getKid(1)->getWidth()),
                     results);
    break;
  }
    
  case Expr::Extract: {
    // XXX, could do more here with "some bits" mask
    break;
  }

    // Casting

  case Expr::ZExt: 
  case Expr::SExt: {
    CastExpr *ce = cast<CastExpr>(e);
    getImpliedValues(ce->src, value->Extract(0, ce->src->getWidth()),
                     results);
    break;
  }

    // Arithmetic

  case Expr::Add: { // constants on left
    BinaryExpr *be = cast<BinaryExpr>(e);
    // C_0 + A = C  =>  A = C - C_0
    if (ConstantExpr *CE = dyn_cast<ConstantExpr>(be->left))
      getImpliedValues(be->right, value->Sub(CE), results);
    break;
  }
  case Expr::Sub: { // constants on left
    BinaryExpr *be = cast<BinaryExpr>(e);
    // C_0 - A = C  =>  A = C_0 - C
    if (ConstantExpr *CE = dyn_cast<ConstantExpr>(be->left))
      getImpliedValues(be->right, CE->Sub(value), results);
    break;
  }
  case Expr::Mul: {
    // FIXME: Can do stuff here, but need valid mask and other things because of
    // bits that might be lost.
    break;
  }

  case Expr::UDiv:
  case Expr::SDiv:
  case Expr::URem:
  case Expr::SRem:
    break;

    // Binary

  case Expr::And: {
    BinaryExpr *be = cast<BinaryExpr>(e);
    if (be->getWidth() == Expr::Bool) {
      if (value->isTrue()) {
        getImpliedValues(be->left, value, results);
        getImpliedValues(be->right, value, results);
      }
    } else {
      // FIXME; We can propogate a mask here where we know "some bits". May or
      // may not be useful.
    }
    break;
  }
  case Expr::Or: {
    BinaryExpr *be = cast<BinaryExpr>(e);
    if (value->isZero()) {
      getImpliedValues(be->left, 0, results);
      getImpliedValues(be->right, 0, results);
    } else {
      // FIXME: Can do more?
    }
    break;
  }
  case Expr::Xor: {
    BinaryExpr *be = cast<BinaryExpr>(e);
    if (ConstantExpr *CE = dyn_cast<ConstantExpr>(be->left))
      getImpliedValues(be->right, value->Xor(CE), results);
    break;
  }

    // Comparison
  case Expr::Ne: 
    value = value->Not();
    /* fallthru */
  case Expr::Eq: {
    EqExpr *ee = cast<EqExpr>(e);
    if (value->isTrue()) {
      if (ConstantExpr *CE = dyn_cast<ConstantExpr>(ee->left))
        getImpliedValues(ee->right, CE, results);
    } else {
      // Look for limited value range.
      //
      // In general anytime one side was restricted to two values we can apply
      // this trick. The only obvious case where this occurs, aside from
      // booleans, is as the result of a select expression where the true and
      // false branches are single valued and distinct.
      
      if (ConstantExpr *CE = dyn_cast<ConstantExpr>(ee->left))
        if (CE->getWidth() == Expr::Bool)
          getImpliedValues(ee->right, CE->Not(), results);
    }
    break;
  }
    
  default:
    break;
  }
}
void InstantiationVisitor::visit(BinaryExpr& b)
{
	_expr.reset(new BinaryExpr(b.sloc(), clone(b.left()), b.op(), clone(b.right())));
}