Пример #1
0
LLVMValueRef gen_xor(compile_t* c, ast_t* left, ast_t* right)
{
  LLVMValueRef l_value = gen_expr(c, left);
  LLVMValueRef r_value = gen_expr(c, right);

  if((l_value == NULL) || (r_value == NULL))
    return NULL;

  if(LLVMIsConstant(l_value) && LLVMIsConstant(r_value))
    return LLVMConstXor(l_value, r_value);

  if(is_always_true(c, l_value))
    return LLVMBuildNot(c->builder, r_value, "");

  if(is_always_false(c, l_value))
    return r_value;

  if(is_always_true(c, r_value))
    return LLVMBuildNot(c->builder, l_value, "");

  if(is_always_false(c, r_value))
    return l_value;

  return LLVMBuildXor(c->builder, l_value, r_value, "");
}
Пример #2
0
LLVMValueRef gen_and(compile_t* c, ast_t* left, ast_t* right)
{
  LLVMValueRef l_value = gen_expr(c, left);
  LLVMValueRef r_value = gen_expr(c, right);

  if((l_value == NULL) || (r_value == NULL))
    return NULL;

  if(LLVMIsConstant(l_value) && LLVMIsConstant(r_value))
    return LLVMConstAnd(l_value, r_value);

  if(is_always_false(c, l_value) || is_always_false(c, r_value))
    return LLVMConstInt(c->i1, 0, false);

  return LLVMBuildAnd(c->builder, l_value, r_value, "");
}
Пример #3
0
int
cond_is_disjunct(node_t *a, node_t *b)
{
	if (!a || !b || a == b)
		return 0;

	node_t *op = dupnode_nochild(a);
	op->type = nt_expr;
	op->e.op = AND_OP;
	set_node_child(op, che_arg1, a);
	set_node_child(op, che_arg2, b);

	struct truth_table *ttbl = cpp_truth_table(op);
	int ret = is_always_false(ttbl);

	free_truth_table(ttbl);
	list_del_init(&a->list);
	list_del_init(&b->list);
	freenode(op);
	return ret;
}
Пример #4
0
LLVMValueRef make_short_circuit(compile_t* c, ast_t* left, ast_t* right,
  bool is_and)
{
  LLVMBasicBlockRef entry_block = LLVMGetInsertBlock(c->builder);
  LLVMBasicBlockRef left_block = codegen_block(c, "sc_left");
  LLVMValueRef branch = LLVMBuildBr(c->builder, left_block);

  LLVMPositionBuilderAtEnd(c->builder, left_block);
  LLVMValueRef l_value = gen_expr(c, left);

  if(l_value == NULL)
    return NULL;

  if(is_constant_i1(c, l_value))
  {
    LLVMInstructionEraseFromParent(branch);
    LLVMDeleteBasicBlock(left_block);
    LLVMPositionBuilderAtEnd(c->builder, entry_block);

    if(is_and)
    {
      if(is_always_false(c, l_value))
        return gen_expr(c, left);
    } else {
      if(is_always_true(c, l_value))
        return gen_expr(c, left);
    }

    return gen_expr(c, right);
  }

  LLVMBasicBlockRef left_exit_block = LLVMGetInsertBlock(c->builder);

  LLVMBasicBlockRef right_block = codegen_block(c, "sc_right");
  LLVMBasicBlockRef post_block = codegen_block(c, "sc_post");

  if(is_and)
    LLVMBuildCondBr(c->builder, l_value, right_block, post_block);
  else
    LLVMBuildCondBr(c->builder, l_value, post_block, right_block);

  LLVMPositionBuilderAtEnd(c->builder, right_block);
  LLVMValueRef r_value = gen_expr(c, right);

  if(r_value == NULL)
    return NULL;

  LLVMBasicBlockRef right_exit_block = LLVMGetInsertBlock(c->builder);
  LLVMBuildBr(c->builder, post_block);

  LLVMPositionBuilderAtEnd(c->builder, post_block);
  LLVMValueRef phi = LLVMBuildPhi(c->builder, c->i1, "");

  LLVMAddIncoming(phi, &l_value, &left_exit_block, 1);
  LLVMAddIncoming(phi, &r_value, &right_exit_block, 1);

  if(is_constant_i1(c, r_value))
  {
    if(is_and)
    {
      if(is_always_false(c, r_value))
        return r_value;
    } else {
      if(is_always_true(c, r_value))
        return r_value;
    }

    return l_value;
  }

  return phi;
}